I'm experiencing app crashes on Oreo Android 8.0/8.1 devices when using the calendar provider. The problem does not show on my devices running Nougat and below.
Permission Denial: reading com.android.providers.calendar.CalendarProvider2 uri content://com.android.calendar/calendars from pid=8522, uid=10197 requires android.permission.READ_CALENDAR, or grantUriPermission()
What puzzles me is that crashes happen even though the system requests persmissions in runtime, they are confirmed by the user, and they can be verified in the system settings. Even checking permissions before access (see my code below) does not help. Access is confirmed - and then denied.
In my AndroidManifest:
<manifest ...>
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application>
...
</application>
</manifest>
As an example (the problem occurs also for other queries), I create a calendar using this method:
public static void createCalendarIfNotExists(android.app.Activity activity) throws SecurityException {
ContentResolver contentResolver = activity.getContentResolver();
// Check if calendar already exists.
String[] projection = new String[]{
CalendarContract.Calendars._ID,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME};
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_CALENDAR) == PackageManager.PERMISSION_GRANTED) {
Cursor cursor = contentResolver.query(CalendarContract.Calendars.CONTENT_URI,
projection,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME + " = ?",
new String[]{CALENDAR_NAME},
null);
if (cursor != null) {
if (cursor.getCount() == 0) {
final ContentValues cv = buildNewCalContentValues(activity);
Uri calUri = buildCalUri();
// Insert the calendar into the database.
contentResolver.insert(calUri, cv);
}
if (!cursor.isClosed()) {
cursor.close();
}
}
}
}
Despite checking calendar permissions with result GRANTED the query fails due to lack of permissions (the request for permissions is done outside this function but the permissions are verified here before running the query).
Why is this happening, and why does it seem to start happening with Android Version 8?