[Android Tips] Calendar Provider で Event を登録すると Google カレンダーアプリが強制終了することがある
Google カレンダーが強制終了
久しぶりに Android に関するブログを書きます。
弊社では iCalSync という iCalendar 形式(.ics)のイベントデータを Android のローカルカレンダーに定期的に同期するアプリをリリースしています。
好評いただいているんですが、先日 iCalSync で登録したイベントを Google カレンダーで開くと強制終了するという問題が発生しました。
この問題が発生する Google カレンダーは Material Design が適用された最新バージョン(Ver.5.0)です。
OWNER_ACCOUNT が原因
ログを見てみたところ、どうやら NullPointerException で落ちているということが分かりました。つまり、登録したイベントのプロパティに何かが足りないということです。あとはどのデータが足りないかという話ですが…探しまくったところ、CalendarProvider で Calendar を登録する時、OWNER_ACCOUNT というプロパティが足りていないことが分かりました。
public void entryCalendar(String accountName, String displayName, int color) { ContentResolver contentResolver = App.getContext().getContentResolver(); ContentValues calVal = new ContentValues(); calVal.put(getAccountNameColumn(), accountName); calVal.put(getAccountTypeColumn(), AccountSetting.ACCOUNT_TYPE); calVal.put(getNameColumn(), Res.string(R.string.calendar_title)); calVal.put(getCalendarDisplayNameColumn(), displayName); calVal.put(getCalendarColorColumn(), color); calVal.put(getCalendarAccessLevelColumn(), 700); calVal.put(getCalendarTimeZoneColumn(), TimeZone.getDefault().getID()); calVal.put(getSyncEventsColumn(), 1); contentResolver.insert(asSyncAdapter(getCalendarsURI(), accountName, AccountSetting.ACCOUNT_TYPE), calVal).toString(); }
足りていないので、OWNER_ACCOUNT を追加します。
public void entryCalendar(String accountName, String displayName, int color, String ownerMailAddress) { ContentResolver contentResolver = App.getContext().getContentResolver(); ContentValues calVal = new ContentValues(); calVal.put(getAccountNameColumn(), accountName); calVal.put(getAccountTypeColumn(), AccountSetting.ACCOUNT_TYPE); calVal.put(getNameColumn(), Res.string(R.string.calendar_title)); calVal.put(getCalendarDisplayNameColumn(), displayName); calVal.put(getCalendarColorColumn(), color); calVal.put(getCalendarAccessLevelColumn(), 700); calVal.put(getOwnerAccountColumn(), ownerMailAddress); calVal.put(getCalendarTimeZoneColumn(), TimeZone.getDefault().getID()); calVal.put(getSyncEventsColumn(), 1); contentResolver.insert(asSyncAdapter(getCalendarsURI(), accountName, AccountSetting.ACCOUNT_TYPE), calVal).toString(); }
これで Google カレンダーで確認してみたところ、正常に表示されました。
まとめ
OWNER_ACCOUNT は必須項目ではないようですし、アプリの機能上必要がないので省いていましたが、Google カレンダーの動作には必要という感じでした。OWNER_ACCOUNT が設定できる iCalSync のアップデートは Google Play ストアで公開中です。なお同期実行時に OWNER_ACCOUNT がない場合は必ずセットするようになっているので、既存カレンダーをそのまま使えます。ぜひアップデートをよろしくお願いします!