为 Android CallLog 注册 ContentObserver 导致崩溃

Registering ContentObserver for Android CallLog causes crash

最近,我的应用程序 keeps 在为 Android CallLog(在 ServiceonCreate 中)注册 contentObserver 时崩溃了。我是这样注册的:

getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler()));

部分堆栈跟踪:

java.lang.RuntimeException: Unable to create service nl.xelion.restandroid.service.CallLogChanged: java.lang.SecurityException: Permission Denial: opening provider com.android.providers.contacts.CallLogProvider from ProcessRecord{f73a1ed 7949:nl.my.app.debug/u0a119} (pid=7949, uid=10119) requires android.permission.READ_CALL_LOG or android.permission.WRITE_CALL_LOG

...

Caused by: java.lang.SecurityException: Permission Denial: opening provider...etc

我使用了这个教程,它确实工作了大约一年: http://www.adityathakker.com/android-content-observer-react-on-content-change

大约从 Android O 开始,崩溃就开始出现了。 registerContentObserver 的 javadoc 确实按照这些行说了一些事情:Starting in O, all content notifications must be backed by a valid ContentProvider. 所以我想知道这是否是问题所在,如果是,如何解决?

无论如何,为什么它会抱怨联系人权限问题,为什么以前没有发生过这种情况?这对我来说没有意义。

ps。我确实使用了需要联系人权限的代码,它在 ContentObserver 的 onChange 中调用,但即使我评论这段代码,崩溃仍然发生。

问题在于对 Android O 的更新。Permissions are grouped together and since Android O permission behaviour was changed 因为权限请求处理不正确。

在我的示例中,我已将权限 READ_CALL_LOG/WRITE_CALL_LOGCALL_PHONE 添加到清单,但在应用程序首次启动时仅请求 CALL_PHONE。这导致权限组 PHONE 被接受,但通话记录权限均未被接受。因此,当 registerContentObserver 方法被调用时,Android 隐含地接受了它,因为接受了组 PHONE.

当我的用户从 N 升级到 O 时,再次调用 registerContentObserver 时,它会崩溃(理直气壮)。解决方案:在调用 registerContentObserver.

之前检查 READ_CALL_LOG/WRITE_CALL_LOG 权限

AndroidO 上仍在使用旧的崩溃代码的用户的解决方法:手动关闭和打开应用程序 Android 设置中的特定权限(因此 PHONE 本例中的权限组)。这会导致接受该组中的所有权限(或至少接受该组中应用所需的那些权限)