android securityexception activeandroid android-8.0-oreo

SecurityException: no se pudo encontrar el proveedor nulo para el usuario 0; en ActiveAndroid en Android 8.0



android-8.0-oreo (9)

Tengo una aplicación que utiliza ActiveAndroid y ha funcionado bien. Sin embargo; ahora, cuando intento guardar un modelo en la base de datos, obtengo una excepción SecurityException.

La pila es:

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]

Alguien más ha experimentado esto? ¿Necesitamos especificar el proveedor de contenido en el AndroidManifest.xml ?

Lo siento pero todavía no tengo un ejemplo aislado de esto. Voy a trabajar para poner algo juntos.

Gracias por adelantado


Aparentemente, Android O requiere el uso de un ContentProvider personalizado para el uso de la base de datos, incluso si no tiene intención de compartir sus datos con otras aplicaciones.

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

Su clase personalizada debe definirse en una etiqueta de proveedor dentro de su etiqueta de aplicación en AndroidManifest.xml. Si corresponde, configure export = false para proteger sus datos del uso externo.

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

Para mí, el problema surgió porque estaba llamando a NotifyChange desde contentResolver. Terminé no necesitando esto, así que pude evitar la implementación de un ContentProvider.


Como lo indican los cambios de seguridad de @GeigerGeek en Android 26 y superiores, es necesario que especifique el proveedor de contenido en su manifiesto.

Para ActiveAndroid puede agregar lo siguiente a su Manifiesto y cambiar el nombre de su paquete.

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

Si usa sabores en su proceso de construcción, puede usar a continuación:

android:authorities="${applicationId}"

El uso de ${applicationId} ayudará en la estructura del proyecto basada en el sabor, donde el paquete de aplicación puede ser diferente para cada sabor.

Para más soluciones o información, esto fue tomado de aquí.


Edite Manifest y agregue este nodo de etiqueta de proveedor en el nodo de aplicación lateral.

<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>

Yo uso esto y solucioné mi error. Haga clic aquí para la demostración .


Fui redirigido a esta pregunta cuando estaba buscando el mismo problema. Sin embargo, esta pregunta específica se refiere a una implementación de biblioteca específica. Para superar este error debido a los https://developer.android.com/about/versions/oreo/android-8.0-changes.html#ccn que se introdujeron recientemente en Android O, debemos proporcionar la autorización específica a ContentProvider agregando lo siguiente en el archivo AndroidManifest.xml bajo la etiqueta de la application .

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

Y necesita tener una clase ContentProvider como la siguiente.

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; } }


Hay dos pasos simples.

  1. Debe tener el proveedor especificado en su AndroidManifest.xml bajo su etiqueta de application como la siguiente.

    <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. Y necesita tener la clase java que especifica el proveedor indicado en el manifiesto. En mi caso, tenía el archivo del proveedor en el paquete util .

    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; } }

Eso es. Tú eres bueno para irte.

Aquí hay un código de trabajo completo para la operación de lectura / escritura / actualización de SQLite en Github. ¡Espero que ayude!




Tuve exactamente el mismo problema con Android activo en Android O. Resulta que uno de los métodos en mi ContentProvider personalizado devolvió un Uri , algunas veces devolvería el valor nulo y esto causaba el problema. Así que agregué la anotación @Nullable al método como se muestra a continuación, que solucionó el problema.

@Nullable @Override public Uri insert(Uri uri, ContentValues contentValues) {..}


Para hotfix , configura tu

compileSdkVersion 25 targetSDKVersion 25

e ignorarás las características de Android O. ¡Te salvará el día!

importante para hot fix:

Pero esta solución será inválida.

Agosto de 2018: se requieren nuevas aplicaciones para alcanzar el nivel de API 26 (Android 8.0) o superior. Noviembre de 2018: se requieren actualizaciones de las aplicaciones existentes para alcanzar el nivel de API 26 o superior. A partir de 2019: cada año avanzará el requisito de targetSdkVersion. Dentro de un año después de cada lanzamiento de Android, las aplicaciones nuevas y las actualizaciones de las aplicaciones deberán apuntar al nivel de API correspondiente o superior.

Otra forma , puedes arreglarlo con ActiveAndroid pero ahora está obsoleto. Puedes probar o puedes probar ReActiveAndroid

con ActiveAndroid , visite https://github.com/pardom/ActiveAndroid/issues/536#issuecomment-344470558

Cuando el proyecto haya definido clases de modelo en el código fuente de Java a través de la aplicación del método de configuración addModelClasses, aún se bloqueará porque las clases de modelo no se cargarán a través de esa configuración. En esa situación, necesita mover la definición del modelo al archivo AndroidManifest.xml.

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(); }}

Si está haciendo algo con FileProvider, no deje de cambiar el nombre del paquete

Uri contentUri = FileProvider.getUriForFile(mContext, "your package name", new File(mImageFilePath));