Search code examples
javaandroidsecurityexceptionandroid-8.0-oreo

Security Exception for ContentProvider.notifyChange on my own URI in Oreo


This one has been asked before - but never answered. So I try my luck again.

My app is a perfect clone of Google's IO Schedule app in terms of synchronization - I use exactly their code at this position.

When running against SDK 25 everything works here - when I go to 26, it crashes with this exception:

12-28 21:11:13.641 6153-6190/? E/AndroidRuntime: FATAL EXCEPTION: IntentService[DataBootstrapService]
                                                 Process: de.XXX.XXX.debug, PID: 6153
                                                 java.lang.SecurityException: Failed to find provider null for user 0; expected to find a valid ContentProvider for this authority

As suggested in other resources: YES, I have set an authority on my content provider. This error is ridiculous. I have no idea why it comes up with null and user 0.

Does anyone have an idea of what to look for? Thanks!

You asked for more details, but I do EXACTLY as Google does in IO Schedule.

My AndroidManifest includes my Provider as follows:

<provider
        android:name=".provider.PendelbusProvider"
        android:authorities="${applicationId}.provider"
        android:exported="false"
        android:syncable="true"/>

The line that causes the crash is this:

getContentResolver().notifyChange(Uri.parse(PendelbusContract.CONTENT_AUTHORITY), null, false);

My CONTENT_AUTHORITY is defined like this: (indirectly through build variables)

public static final String CONTENT_AUTHORITY = BuildConfig.AUTHORITY;
 // equals to: "de.zordid.pendelbus.debug.provider"

I do not understand at all what the message is supposed to indicate.

What is "provider null" and what is "user 0"?


Solution

  • The answer to my problem lies in the definition of an URI and the authority derived from that using Uri.getAuthority().

    Pair this with a classic BUG in Google's own software, the Google IO Schedule app which is open source.

    In their DataBootstrapService line 93, they do this:

    getContentResolver().notifyChange(Uri.parse(ScheduleContract.CONTENT_AUTHORITY), null, false);

    But, what I did not know: ScheduleContract.CONTENT_AUTHORITY is a string containing only the authority. It does NOT make a valid URI, so this is buggy from the very beginning and lead into my problems.

    If you test this created Uri and call getAuthority, you will see the damn null.

    Fix: use something like BASE_CONTENT_URI which is only "content://"+ AUTHORITY. Then it's fixed.

    Hope this helps others.