【发布时间】:2017-12-17 12:18:04
【问题描述】:
在使用日历提供程序时,我在 Oreo Android 8.0/8.1 设备上遇到应用崩溃。在我运行 Nougat 及以下版本的设备上未显示此问题。
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()
让我感到困惑的是,即使系统在运行时请求权限,也会发生崩溃,它们是由用户确认的,并且可以在系统设置中进行验证。即使在访问之前检查权限(请参阅下面的代码)也无济于事。访问被确认 - 然后被拒绝。
在我的 AndroidManifest 中:
<manifest ...>
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<application>
...
</application>
</manifest>
作为示例(其他查询也会出现问题),我使用此方法创建日历:
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();
}
}
}
}
尽管使用结果 GRANTED 检查日历权限,但由于缺少权限,查询失败(权限请求在此函数之外完成,但在运行查询之前在此处验证权限)。
为什么会发生这种情况,为什么它似乎从 Android 版本 8 开始发生?
【问题讨论】:
标签: java android android-permissions android-calendar android-8.0-oreo