Android Calendar一闪而过 无法创建event
手机端Calendar一闪而过的问题
与因为Calendar的启动启动步骤有关。
Android的Calendar是通过 LaunchActivity.java类启动的。
先看LaunchActivity类的onCreate函数实现:
@Override
protected void onCreate(Bundle icicle) {
super.onCreate(icicle);
mExtras = getIntent().getExtras();
// Our UI is not something intended for the user to see. We just
// stick around until we can figure out what to do next based on
// the current state of the system.
setVisible(false);
// Only try looking for an account if this is the first launch.
if (icicle == null) {
// This will request a Gmail account and if none are present, it will
// invoke SetupWizard to login or create one. The result is returned
// through onActivityResult().
Bundle bundle = new Bundle();
bundle.putCharSequence("optional_message", getText(R.string.calendar_plug));
GoogleLoginServiceHelper.getCredentials (
this,
GET_ACCOUNT_REQUEST,
bundle,
GoogleLoginServiceConstants.PREFER_HOSTED,
Gmail.GMAIL_AUTH_SERVICE,
true);
}
其实大家稍微看下代码就清楚这个onCreate函数中并没有通过startActivity来启动Calendar,唯一值得怀疑的接口应该是黄色标注接口GoogleLoginServiceHelper.getCredentials 。
这个接口暂时不关心它到底做什么,但至少可以初步判定它会通过 protected void onActivityResult(int requestCode, int resultCode, Intent intent)的resultCode和intent来控制进一步的代码调用。
然后,正是这个地方的返回值导致了calendar一闪而过的问题。
所以接下来再关注下onActivityResult的相关代码:
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (requestCode == GET_ACCOUNT_REQUEST) {
if (resultCode == RESULT_OK) {// RESULT_CANCELED
if (intent != null) {
Log.d("Calendars", "onActivityResult", null);
Bundle extras = intent.getExtras();
if (extras != null) {
final String account = "";
//account = extras.getString(GoogleLoginServiceConstants.AUTH_ACCOUNT_KEY);
onAccountsLoaded(account);
}
}
} else {
finish();
}
}
}
代码其实比较简单,也就是返回调用成功的话则会做进一步的调用。
一开始的时候也不确定返回值到底会是RESULT_OK,于是想到了Log的方法来调试,在if语句内添加log来确认代码是否会走到onAccountsLoaded();
结果发现该log并没有打印出,进而可以确定RESULT_OK 返回值存在问题,通过查看返回值的具体那些定义值可以暂定使用RESULT_CANCELED 。
再重新跑一次,结果就可以发现log打印出来了,而onAccountsLoaded()函数也走到了的。之后的startActiviy则可以启动Calendar了。
但启动Calendar之后发现OptionMenu中的New Event的时候提示找不到Calendars,无法创建Event .
所以单单的只是改掉RESULT_OK,也会因为calendar.db中没有Calendars Table实例,进而说明还需要添加一个Table实例。
Calendars需要那些字段?其实有两种方法:
一, 通过代码,去观察Calendars的类,可以观察其中的字段名(一般都会有相关的注释和采取全大写的变量名)
二, 通过Sqlite Manager来打开Calendar.db 文件来观察Calendars Table具体有哪些字段。Elicpse的DMSS下将calendar.db导出(adb)。
想到这,于是打算先投机取巧下,用Sqlite Manager添加一项Calendars Table,然后再将修改后的db导入手机中(填了一些必须的字段)。
结果却大失所望,看来还是不能走捷径。
没办法,硬着头皮看android的数据库操作,一步步参考下去尝试添加数据,具体代码如下:
Log.d("Calendars", "onAccountsLoaded", null);
//SQLiteDatabase db = openOrCreateDatabase("Calendar", null);
Cursor c = Calendars.query(getContentResolver(), null,
null, Calendars.DEFAULT_SORT_ORDER);
Log.d("Calendars", "Get Cursor", null);
if ((c == null) || c.getCount() == 0)
{
ContentValues cv = new ContentValues();
cv.put(Calendars.HIDDEN, 0);
cv.put(Calendars.DISPLAY_NAME, "localcalendar");
cv.put(Calendars.NAME, "localcalednar");
cv.put(Calendars.ACCESS_LEVEL, 700);
cv.put(Calendars.SELECTED, 1);
//cv.put(Calendars.LOCATION, );
//cv.put(Calendars.URL, 1);
cv.put(Calendars.SYNC_EVENTS, 1);
cv.put(Calendars.TIMEZONE, Time.getCurrentTimezon());
getContentResolver().insert(Calendars.CONTENT_URI, cv);
Log.d("Calendars", "cr.insert", null);
cv.clear();
}
加了几行log来跟进,看看是否有问题:懒的又没有完全添加所有的字段,本以为加几个必须的就OK了,结果发现还是不行。
接着看代码,根据log提示仔细观察相关代码,结果一看:
// If there are no syncable calendars, then we cannot allow
// creating a new event.
if (cursor.getCount() == 0) {
// Cancel the "loading calendars" dialog if it exists
if (mSaveAfterQueryComplete) {
mLoadingCalendarsDialog.cancel();
}
NND,弹的就是这个框,不对啊,count怎么会是0啊?我已经添加calendars Table了啊,导出来的db也显示有啊,奇怪?难道这个cursor遍历有问题?
继续跟踪这个cursor,QueryHandler的函数,肯定跟它的实例脱不了关系,继续找,找到了实例对象:private QueryHandler mQueryHandler;
毫无疑问,多半在onCreate()函数里实例化的,过去看看,结果一看,恍然大悟:
mQueryHandler = new QueryHandler(getContentResolver());
mQueryHandler.startQuery(0, null, Calendars.CONTENT_URI, CALENDARS_PROJECTION ,
CALENDARS_WHERE, null , null );
原来这个CALENDARS_PROJECTION 这个家伙才是罪魁祸首,看看它的本来面目:
private static final String[] CALENDARS_PROJECTION = new String[] {
Calendars._ID, // 0
Calendars.DISPLAY_NAME, // 1
Calendars.TIMEZONE, // 2
};
哎,看来还是自己太懒,没有加timezone的字段,难怪一直getcount为0。
然后老老实实的重新加上timezone字段,终于大功告成(别忘了相关的package哦)。
更多相关文章
- C基础—函数指针,联合体,枚举,结构体和结构体指针
- Android ListView 滚动条的设置详解及实例代码
- Android NDK c调用java代码
- Android 代码风格指南
- Android px和dip及sp的区别及转换代码
- Android 源代码编译前后的目录结构
- Android有用代码片段(三)