SecurityException: Failed to find provider null for user 0; on ActiveAndroid on Android 8.0
Asked Answered
F

10

40

I have an app that is using ActiveAndroid and it's been working fine. However; now when I try to save a model to the database I'm getting a SecurityException.

The stack is:

Error saving model java.lang.SecurityException: Failed to find provider null for user 0; expected to find a valid ContentProvider for this authority 
at android.os.Parcel.readException(Parcel.java:1942) 
at android.os.Parcel.readException(Parcel.java:1888) 
at android.content.IContentService$Stub$Proxy.notifyChange(IContentService.java:801) 
at android.content.ContentResolver.notifyChange(ContentResolver.java:2046) 
at android.content.ContentResolver.notifyChange(ContentResolver.java:1997) 
at android.content.ContentResolver.notifyChange(ContentResolver.java:1967) 
at com.activeandroid.Model.save(Model.java:162)
[.... local stack removed]

Has anyone else experienced this? Do we need to specify the Content Provider in the AndroidManifest.xml?

Sorry but I do not have an isolated example of this yet. I will work to put something together.

Thanks in advance

Formulate answered 28/8, 2017 at 18:37 Comment(4)
"Failed to find provider null" suggests a malformed Uri, one whose authority string is either missing or literally "null".Acierate
I get the same crash, but with something else than "null" as provider in the stacktrace. Dont know why this is happening, but its only occurring on Android 8...Tentation
This one is driving me crazy. Targeting SDK 25 works fine, targeting 26+ crashes with exactly this error. I HAVE set the authority in the Provider correctly. Still this crash. I have NO IDEA what this is about. Of course my Uri is not null at the call! Do you now anything new??Pinter
@Velval's answer below is probably the correct one: https://mcmap.net/q/397468/-securityexception-failed-to-find-provider-null-for-user-0-on-activeandroid-on-android-8-0Ceiba
F
54

As pointed out by @GeigerGeek security changes on Android 26 and above require you to specify the content provider in your manifest.

For ActiveAndroid you can add the below to your Manifest and change your package name.

<provider
  android:name="com.activeandroid.content.ContentProvider"
  android:authorities="<your.package.name>"
  android:enabled="true"
  android:exported="false">
</provider>

If using flavours on your build process you can use below instead:

android:authorities="${applicationId}"

Using ${applicationId} will help in flavor based project structure where application package may be different for each flavors.

For more solutions or info this was taken from here.

Flourishing answered 6/12, 2017 at 0:13 Comment(1)
note: authorities may be other strings, not just your package nameSkull
T
6

For hot fix, set your

compileSdkVersion 25
targetSDKVersion 25

and you will ignore android O features. It will save your day!

important for hot fix:

But this solution will be invalid.

August 2018: New apps required to target API level 26 (Android 8.0) or higher. November 2018: Updates to existing apps required to target API level 26 or higher. 2019 onwards: Each year the targetSdkVersion requirement will advance. Within one year following each Android dessert release, new apps and app updates will need to target the corresponding API level or higher.

Another ways, you can fix with ActiveAndroid but It is deprecated now. You can try or you can try ReActiveAndroid

with ActiveAndroid, visit https://github.com/pardom/ActiveAndroid/issues/536#issuecomment-344470558

When project have defined model classes in java source code through addModelClasses configuration method application will still be crashing cause model classes wont be loaded through that configuration. In that situation You need to move model definition to the AndroidManifest.xml file.

AndroidManifest.xml

<provider
    android:name=".content.DatabaseContentProvider"
    android:authorities="your package name"
    android:exported="false" />

DatabaseContentProvider.java

...
import com.activeandroid.content.ContentProvider;
...

public class DatabaseContentProvider extends ContentProvider {

@Override
protected Configuration getConfiguration() {
    Configuration.Builder builder = new Configuration.Builder(getContext());
    builder.addModelClass(SomeModel.class);
    builder.addModelClass(OtherModel.class);
    return builder.create();
 }}

If you are doing something with FileProvider, don't miss to change package name

 Uri contentUri = FileProvider.getUriForFile(mContext,
            "your package name", new File(mImageFilePath));
Toronto answered 16/2, 2018 at 13:46 Comment(1)
I don't think ReActiveAndroid is from the same team. "Unfortunately, the author of [ActiveAndroid] stopped maintaining it, so I decided to continue maintain the library instead of him."Priestcraft
T
3

Android O apparently requires the use of a custom ContentProvider for database usage, even if you do not intend to share your data with other applications.

https://developer.android.com/about/versions/oreo/android-8.0-changes.html

Your custom class must be defined in a provider tag within your application tag in AndroidManifest.xml. If applicable, set exported=false to protect your data from external usage.

<provider android:name=".MyContentProvider"
    android:exported="false"
    android:authorities="com.your_app_path.MyContentProvider"/>

For me the problem arose because I was calling notifyChange from the contentResolver. I ended up not needing this, so I was able to avoid implementation a ContentProvider.

Thoughtless answered 25/10, 2017 at 18:43 Comment(0)
J
2

if your package is different from your applicationId then you should use the applicationId

<provider
            android:name="com.activeandroid.content.ContentProvider"
            android:authorities="${applicationId}"
            android:exported="false" />
Jovian answered 6/5, 2019 at 4:45 Comment(0)
R
0

Maybe because of your uri is null when you use notifyChange, https://developer.android.com/about/versions/oreo/android-8.0-changes.html#ccn

Android O will add check for provider:

311 .checkContentProviderAccess(uri.getAuthority(), userHandle);
312 if (msg != null) {
313 if (targetSdkVersion >= Build.VERSION_CODES.O) {
314 throw new **SecurityException**(msg);
315 } else {
Retro answered 24/10, 2017 at 7:30 Comment(0)
N
0

I was redirected to this question when I was searching for the same problem. However, this specific question concerns to an specific library implementation. To overcome this error due to the changes which are newly introduced in Android O, we have to provide the specific authority to the ContentProvider by adding the following in the AndroidManifest.xml file under application tag.

<provider
    android:name=".DatabaseContentProvider"
    android:authorities="com.yourpackage.name"
    android:exported="false" /> 

And you need to have a ContentProvider class like the following.

public class DatabaseContentProvider extends ContentProvider {

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
        return null;
    }

    @Nullable
    @Override
    public Cursor query(@NonNull Uri uri,
                        @Nullable String[] projection,
                        @Nullable String selection,
                        @Nullable String[] selectionArgs,
                        @Nullable String sortOrder) {
        return null;
    }

    @Override
    public boolean onCreate() {
        return true;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues values,
                      @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
        return 0;
    }

    @Nullable
    @Override
    public String getType(@NonNull Uri uri) {
        return null;
    }
}
Niedersachsen answered 17/5, 2018 at 21:18 Comment(0)
N
0

There are two simple steps.

  1. You need to have the provider specified in your AndroidManifest.xml under your application tag like the following.

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:theme="@style/AppTheme">
        <activity
            android:name=".activity.MainActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    
        <provider
            android:name=".util.DatabaseContentProvider"
            android:authorities="com.your.application.package.name"
            android:exported="false" />
    </application>
    

  2. And you need to have the java class which specifies the provider stated in the manifest. In my case, I had the provider file in the util package.

    package com.your.application.package.name.util;
    
    import android.content.ContentProvider;
    import android.content.ContentValues;
    import android.database.Cursor;
    import android.net.Uri;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    
    public class DatabaseContentProvider extends ContentProvider {
    
        @Nullable
        @Override
        public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) {
            return null;
        }
    
        @Nullable
        @Override
        public Cursor query(@NonNull Uri uri,
                        @Nullable String[] projection,
                        @Nullable String selection,
                        @Nullable String[] selectionArgs,
                        @Nullable String sortOrder) {
            return null;
        }
    
        @Override
        public boolean onCreate() {
            return true;
        }
    
        @Override
        public int update(@NonNull Uri uri, @Nullable ContentValues values,
                      @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    
        @Override
        public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
            return 0;
        }
    
        @Nullable
        @Override
        public String getType(@NonNull Uri uri) {
            return null;
        }
    }
    

That's it. You are good to go.

Here is a complete working code for SQLite read/write/update operation in Github. Hope that helps!

Niedersachsen answered 2/4, 2019 at 22:19 Comment(0)
C
-1

Edit Manifest and add this provider tag node in side application node.

<application ....>
    <provider android:name="com.activeandroid.content.ContentProvider"
        android:exported="false"
        android:enabled="true"
        android:authorities="here will be package name of your app"/>
.....
</application>

I use this and it fixed my error. Click here for demo.

Cheer answered 14/12, 2017 at 13:4 Comment(0)
R
-1

i know there already good answer is there, but i dont understand how to best way to fix this bug and read this post Fixing SecurityException requiring a valid ContentProvider on Android 8, it very helpful to fix my bug i hope its helpful for other, Cheers!!!

Rozellarozelle answered 27/9, 2018 at 16:53 Comment(0)
L
-2

I had the exact same problem with active android on Android O. Turns out that one of the methods in my custom ContentProvider returned a Uri, some times it would return null and this was causing the issue. So I added the @Nullable annotation to the method as shown below which fixed the problem.

@Nullable
@Override
public Uri insert(Uri uri, ContentValues contentValues) {..}
Lawrenson answered 11/9, 2017 at 21:54 Comment(1)
This doesn't fix the problem.Henton

© 2022 - 2024 — McMap. All rights reserved.