pardom-zz / ActiveAndroid

Active record style SQLite persistence for Android
http://www.activeandroid.com
4.7k stars 1.03k forks source link

.save failing on Android O device #536

Open JacobVanAssche opened 7 years ago

JacobVanAssche commented 7 years ago

I recently just updated my device to Android O and now the .save methods no longer work.

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)

agonper commented 7 years ago

Same problem here, hope gets fixed soon

zuiaichiyu commented 7 years ago

same problem

uncledoc commented 7 years ago

on latest android emulator works fine for me

JacobVanAssche commented 7 years ago

@uncledoc You're using Android 8.0.0 on the emulator? I'm still getting the same error on an emulator.

pavelannin commented 7 years ago

Hi. Same problem. I set compileSdkVersion = 25 and targetSdkVersion = 25. On Android O (API 26) it works. This is not a solution, it's a HotFix. Waiting for a solution from the developers.

tzutalin commented 7 years ago

Met the same issue on Android 8

JacobVanAssche commented 7 years ago

I think my plan is to convert over to Google's new Room Persistence Library instead of using ActiveAndroid. It doesn't look like ActiveAndroid is maintained at all anymore.

martino2k6 commented 6 years ago

This can be fixed by adding

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

to your manifest file.

But I'd agree with @JacobVanAssche, if you can then move to a different library as this one hasn't been updated for a while and probably won't be.

martiwi commented 6 years ago

Importing the source code into your project and compile it with API 26 solved it.

giperwlad commented 6 years ago

In my case it was fixed as following steps:

1) clone source code to my ap as module 2) hardcode sAuthority string field in class com.activeandroid.content.ContentProvider: private static final String sAuthority="your.package.name"; 3) Declare provider in manifest <provider android:name="com.activeandroid.content.ContentProvider" android:authorities="" android:enabled="true" android:exported="false">

azizimusa commented 6 years ago

@martino2k6 solution work for me.

ricardomorsch commented 6 years ago

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" />
adrianbudzynski commented 6 years ago

@martino2k6 & @ricardomorsch Yours solution is good but not in all cases. 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.

joshuatam commented 6 years ago

@adrianbudzynski I get it work by extending com.activeandroid.content.ContentProvider

AndroidManifest.xml

<provider
        android:name=".content.DatabaseContentProvider"
        android:authorities="${applicationId}"
        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();
    }
}
azizimusa commented 6 years ago

Solution by @joshuatam is working.

To get a context at this line Configuration.Builder builder = new Configuration.Builder(context); inside DatabaseContentProvider. Can just use getContext()

joshuatam commented 6 years ago

@azizimusa Thanks, corrected.

PareshMayani commented 6 years ago

Thanks @joshuatam, your solution is working.

ImangazalievM commented 6 years ago

Hello, guys! You can use my library - https://github.com/ImangazalievM/ReActiveAndroid. I forked the ActiveAndroid and fixed all bugs. It works fine on Android O and other versions.

@JacobVanAssche @agonper @zuiaichiyu @anninpavel @azizimusa @PareshMayani @joshuapinter @adrianbudzynski @martino2k6 @tzutalin

erhanbicer commented 6 years ago

Thanks! @joshuatam is working

liupeng826 commented 6 years ago

@joshuatam issue again when add 1 column when I follow the Schema-migrations https://github.com/pardom-zz/ActiveAndroid/wiki/Schema-migrations

<provider android:name=".search.AddressSuggestionsProvider" android:authorities="${search_authority}" android:exported="false"/>

    <meta-data android:name="AA_DB_NAME" android:value="NALocator.db" />
    <meta-data android:name="AA_DB_VERSION" android:value="2" />
    <meta-data android:name="AA_MODELS"
    android:value="com.volvo.it.mobile.locator.core.entity.Location, com.volvo.it.mobile.locator.core.entity.LocationService" />

what need i to do more? do you have an worked sample?

liupeng826 commented 6 years ago

@ImangazalievM do i need to change a lot if use ReActiveAndroid?

ImangazalievM commented 6 years ago

@liupeng826 No. If you want to migrate to ReActiveAndroid, read this article https://imangazalievm.gitbooks.io/reactiveandroid/migration-from-activeandroid.html

NagoLazaro commented 6 years ago

@joshuatam Your solution worked for me perfectly. Thanks!

fajaranugrah commented 6 years ago

So what to do to solve this problem? I have never used ContentProvider for all classes but one class has already created the code but still gets the report error Thank you

ImangazalievM commented 6 years ago

@fajaranugrah you can start using https://github.com/ImangazalievM/ReActiveAndroid. I fixed all bugs and it works on Android O. If you want to migrate to ReActiveAndroid, please read this article https://imangazalievm.gitbooks.io/reactiveandroid/migration-from-activeandroid.html

deiry commented 5 years ago

@joshuatam Thank you for help! It's works perfectly.

joshuapinter commented 5 years ago

A nifty trick if you don't want to extend the ContentProvider to put your dynamic configuration in there, is to just dispose() of the ActiveAndroid database connection on your app initialization and just reinitialize it with your specific configuration.

This allows you to keep the normal ContentProvider as is in the AndroidManifest.xml:

<provider
  android:name="com.activeandroid.content.ContentProvider"
  android:authorities="${applicationId}"
  android:enabled="true"
  android:exported="false">
</provider>

And then just do something like this in your App's onCreate() method:

// Close existing database connection, if it exists.
try {
  ActiveAndroid.dispose();
}
catch( NullPointerException ignored ) {}

Configuration databaseConfiguration = new Configuration.Builder( this )
  .setDatabaseName( "MyDatabase" )
  .setDatabaseVersion( 100 )
  .setModelClasses( MyModel.class )
  .create();

ActiveAndroid.initialize( databaseConfiguration );

This does mean that you will have an Application.db file in your data/data/databases/ directory (from ActiveAndroid initializing with the ContentProvider) but I think that's a minor drawback in order to have a clean, dynamic configuration.