Recently my app keeps crashing when registering a contentObserver for the Android CallLog (in onCreate
of a Service
). This is the way I register it:
getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler()));
Part of the stacktrace:
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
I used this tutorial, and it DID work for about a year: http://www.adityathakker.com/android-content-observer-react-on-content-change
Approximately since Android O the crashes started to appear. The javadoc of registerContentObserver
does say something along these lines: Starting in O, all content notifications must be backed by a valid ContentProvider.
So I was wondering if this would be the problem, and if so, how to solve it?
Anyway, why is it complaining about permissions for contacts, and why didn't this happen before? This doesn't make sense to me.
ps. I do use code which requires permission for contacts, which is called in the onChange of the ContentObserver, but even when I comment this piece of code the crash still occurs.
The problem lies with the update to Android O. Permissions are grouped together and since Android O permission behaviour was changed because of incorrect handling of permission requests.
In my example I had added the permissions READ_CALL_LOG
/WRITE_CALL_LOG
and CALL_PHONE
to the manifest, but requested only CALL_PHONE
at first startup of the app. This caused the permission group PHONE
to be accepted, but neither of the call-log permissions. So when the registerContentObserver
method was called, Android implicitly accepted it to be used because of accepting the group PHONE
.
When my user upgraded from N to O, and registerContentObserver
was called again, it would crash (justly). Solution: check for the READ_CALL_LOG
/WRITE_CALL_LOG
permisions before calling registerContentObserver
.
Workaround for users on Android O who're still using the old - crashing- code: Manually turn off & on the specific permission in the Android settings of the app (so the PHONE
permission group in this case). This causes all permissions in this group to be accepted (or at least those permissions in that group that are required by the app)