手机端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哦)。

更多相关文章

  1. C基础—函数指针,联合体,枚举,结构体和结构体指针
  2. Android ListView 滚动条的设置详解及实例代码
  3. Android NDK c调用java代码
  4. Android 代码风格指南
  5. Android px和dip及sp的区别及转换代码
  6. Android 源代码编译前后的目录结构
  7. Android有用代码片段(三)

随机推荐

  1. android 程序全屏设置
  2. android使用keystore打包错误解决方法
  3. hello android
  4. Android(安卓)flutter Json转Dart Model
  5. android中的sqlite操作
  6. android识别鼠标左键,右键操作
  7. Android(安卓)界面设计工具 droiddraw
  8. Android基于TitleBar页面导航实现
  9. Business mobile application developmen
  10. android 实现图片加载效果