Excepción de seguridad de Android Java

8

En mi aplicación, el usuario tiene la capacidad de tomar una foto o agregar una foto a la aplicación. Recibo informes de fallos de java.lang.SecurityException cuando la aplicación intenta mostrar la imagen guardada en un ImageView

La línea en la que se equivoca es

holder.imageV.setImageURI(uriParsed);

No he podido duplicar el error en mi dispositivo o en los simuladores, todos muestran bien la imagen.

El código completo que estoy usando es

JoinProjectPicture projectPicture = mProjects.get(position);
Project current = projectPicture.getProject();
Picture picture = projectPicture.getPicture();

 holder.projectName.setText(current.getProjectName() + "(" + current.getWidth() + "x" + current.getHeight() + ")");
 holder.projectStatusTV.setText(current.getStatus());

 if(picture != null) {
      String pictureName = picture.getPictureName();
      Uri uriParsed = Uri.parse(pictureName);

      if(uriParsed != null) {
           Log.d("URIParsed", "Project: " + current.getProjectName() + " - Parsed: " + uriParsed);
           holder.imageV.setImageURI(uriParsed);
    }
}

La salida de los registros que se muestran en mi dispositivo (3 proyectos, uno sin imagen)

Proyecto: Prueba - Analizado: archivo: ///storage/emulated/0/Android/data/com.desbrina.diamondpaintinglogbook/files/Pictures/20191111_1408166491573472523237896.jpg

Proyecto: Prueba 3 - Analizado: contenido: //com.android.providers.media.documents/document/image%3A1891

El error

java.lang.SecurityException: 
  at android.os.Parcel.createException (Parcel.java:1966)
  at android.os.Parcel.readException (Parcel.java:1934)
  at android.os.Parcel.readException (Parcel.java:1884)
  at android.app.IActivityManager$Stub$Proxy.getContentProvider (IActivityManager.java:4039)
  at android.app.ActivityThread.acquireProvider (ActivityThread.java:6365)
  at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider (ContextImpl.java:2825)
  at android.content.ContentResolver.acquireUnstableProvider (ContentResolver.java:1835)
  at android.content.ContentResolver.openTypedAssetFileDescriptor (ContentResolver.java:1449)
  at android.content.ContentResolver.openAssetFileDescriptor (ContentResolver.java:1302)
  at android.content.ContentResolver.openAssetFileDescriptor (ContentResolver.java:1225)
  at android.graphics.ImageDecoder$ContentResolverSource.createImageDecoder (ImageDecoder.java:273)
  at android.graphics.ImageDecoder.decodeDrawableImpl (ImageDecoder.java:1652)
  at android.graphics.ImageDecoder.decodeDrawable (ImageDecoder.java:1645)
  at android.widget.ImageView.getDrawableFromUri (ImageView.java:952)
  at android.widget.ImageView.resolveUri (ImageView.java:921)
  at android.widget.ImageView.setImageURI (ImageView.java:532)
  at android.support.v7.widget.AppCompatImageView.setImageURI (AppCompatImageView.java:116)
  at com.desbrina.diamondpaintinglogbook.ui.main.Adapters.ProjectListAdapter.onBindViewHolder (ProjectListAdapter.java:88)
  at com.desbrina.diamondpaintinglogbook.ui.main.Adapters.ProjectListAdapter.onBindViewHolder (ProjectListAdapter.java:23)
  at android.support.v7.widget.RecyclerView$Adapter.onBindViewHolder (RecyclerView.java:6781)
  at android.support.v7.widget.RecyclerView$Adapter.bindViewHolder (RecyclerView.java:6823)
  at android.support.v7.widget.RecyclerView$Recycler.tryBindViewHolderByDeadline (RecyclerView.java:5752)
  at android.support.v7.widget.RecyclerView$Recycler.tryGetViewHolderForPositionByDeadline (RecyclerView.java:6019)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:5858)
  at android.support.v7.widget.RecyclerView$Recycler.getViewForPosition (RecyclerView.java:5854)
  at android.support.v7.widget.LinearLayoutManager$LayoutState.next (LinearLayoutManager.java:2230)
  at android.support.v7.widget.LinearLayoutManager.layoutChunk (LinearLayoutManager.java:1557)
  at android.support.v7.widget.LinearLayoutManager.fill (LinearLayoutManager.java:1517)
  at android.support.v7.widget.LinearLayoutManager.onLayoutChildren (LinearLayoutManager.java:612)
  at android.support.v7.widget.RecyclerView.dispatchLayoutStep2 (RecyclerView.java:3924)
  at android.support.v7.widget.RecyclerView.dispatchLayout (RecyclerView.java:3641)
  at android.support.v7.widget.RecyclerView.onLayout (RecyclerView.java:4194)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.support.constraint.ConstraintLayout.onLayout (ConstraintLayout.java:1915)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.support.v4.view.ViewPager.onLayout (ViewPager.java:1775)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.LinearLayout.setChildFrame (LinearLayout.java:1812)
  at android.widget.LinearLayout.layoutVertical (LinearLayout.java:1656)
  at android.widget.LinearLayout.onLayout (LinearLayout.java:1565)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.widget.FrameLayout.layoutChildren (FrameLayout.java:323)
  at android.widget.FrameLayout.onLayout (FrameLayout.java:261)
  at com.android.internal.policy.DecorView.onLayout (DecorView.java:1088)
  at android.view.View.layout (View.java:22406)
  at android.view.ViewGroup.layout (ViewGroup.java:6594)
  at android.view.ViewRootImpl.performLayout (ViewRootImpl.java:3417)
  at android.view.ViewRootImpl.performTraversals (ViewRootImpl.java:2884)
  at android.view.ViewRootImpl.doTraversal (ViewRootImpl.java:1932)
  at android.view.ViewRootImpl$TraversalRunnable.run (ViewRootImpl.java:8589)
  at android.view.Choreographer$CallbackRecord.run (Choreographer.java:949)
  at android.view.Choreographer.doCallbacks (Choreographer.java:761)
  at android.view.Choreographer.doFrame (Choreographer.java:696)
  at android.view.Choreographer$FrameDisplayEventReceiver.run (Choreographer.java:935)
  at android.os.Handler.handleCallback (Handler.java:873)
  at android.os.Handler.dispatchMessage (Handler.java:99)
  at android.os.Looper.loop (Looper.java:214)
  at android.app.ActivityThread.main (ActivityThread.java:7094)
  at java.lang.reflect.Method.invoke (Native Method)
  at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run (RuntimeInit.java:494)
  at com.android.internal.os.ZygoteInit.main (ZygoteInit.java:975)
Caused by: android.os.RemoteException: 
  at com.android.server.am.ActivityManagerService.getContentProviderImpl (ActivityManagerService.java:15677)
  at com.android.server.am.ActivityManagerService.getContentProviderImpl (ActivityManagerService.java:15586)
  at com.android.server.am.ActivityManagerService.getContentProvider (ActivityManagerService.java:16151)
  at android.app.IActivityManager$Stub.onTransact$getContentProvider$ (IActivityManager.java:11035)
  at android.app.IActivityManager$Stub.onTransact (IActivityManager.java:295)
Ceri Turner
fuente
¿Has intentado crear una versión ofuscada de lanzamiento de tu aplicación y prueba? ¿Funciona?
Sagar
¿Puedes publicar un registro de errores completo? ¿Estás usando uri desde el almacenamiento de tu teléfono?
Amit Tiwary
Será desde el almacenamiento del teléfono o desde la aplicación, dependiendo de si se agregó desde la galería o si se tomó la cámara en la aplicación. Accidente completo agregado
Ceri Turner
1
Compruebe que se cumplen los siguientes requisitos: permisos de escritura y que tiene un proveedor de archivos si está guardando en una ruta interna personalizada.
TheRealChx101
Estás diciendo que probaste el código en emuladores. Recomiendo probar dicho código relacionado con el hardware en casi todas las versiones de Android. ¿Lo has probado en Android Pie, como sugieren las respuestas a continuación?
L3n95

Respuestas:

4

Creo que está recibiendo la excepción de seguridad en un sistema operativo Android Pie o posterior. Esto se debe a que en estos sistemas tienes que declarar la ruta que tu aplicación quiere usar.

Verifique: https://developer.android.com/reference/android/support/v4/content/FileProvider

Además, es posible que su aplicación esté tratando de obtener contenido de otra aplicación que requiere permiso, como Google Photos requiere: <uses-permission android:name="com.google.android.apps.photos.permission.GOOGLE_PHOTOS"/>

Compruebe esto: java.lang.SecurityException: denegación de permisos: proveedor de apertura com.google.android.apps.photos.content.GooglePhotosImageProvider

Vatish Sharma
fuente
Lo estoy obteniendo en 9, pero estoy ejecutando 10 y no puedo reproducirlo yo mismo. Intenté reproducirlo en un 9 de manera similar o no pude
Ceri Turner
Recibo este error cuando intento disparar una intención a una aplicación de galería de terceros (en mi caso, fue Google Photos) para que pueda elegir una foto para mi aplicación. Por lo tanto, probablemente también necesite una aplicación que necesite permiso antes de intentarlo.
Vatish Sharma
He añadido eso y todavía se bloquea
Ceri Turner
4

Desde Api 24, no puede acceder al archivo Uris directamente. Debe usar Autoridades de archivo para la carpeta y luego usar

val photoURI = FileProvider.getUriForFile(activity, BuildConfig.APPLICATION_ID + ".provider", File(path));

En AndroidManifes.xml

Agregue lo siguiente a la applicationetiqueta. En el siguiente nombre del paquete esBuildConfig.APPLICATION_ID

<provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="packagename.provider"
            android:enabled="true"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

proveedor_rutass.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>
    <external-path
        name="external"
        path="." />
</paths>
Mustansar Saeed
fuente
3

Esta excepción generalmente es causada por el uso de imageuri de aplicaciones de terceros. La solución es implementar el proveedor de archivos. Puede obtener muchas soluciones sobre cómo implementar el proveedor de archivos.

AkashToSky
fuente
Estoy buscando y no estoy realmente seguro de lo que necesito cambiar. Actualmente estoy agregando las imágenes usando pastebin.com/Xswi7puK y mostrándolas con pastebin.com/EQVvyRnG
Ceri Turner el
No, sigue fallando
Ceri Turner
Intenté configurar imageUri en una vista de imagen pero funciona bien para mí. La solución alternativa es crear un mapa de bits desde el imageuri y configurarlo en la vista de imagen. Creo que hay un problema en imageuri. ¿De dónde lo sacas?
AkashToSky
Me sale el mismo error al intentar con un mapa de bits. Las imágenes se agregan usando el código aquí. pastebin.com/Xswi7puK
Ceri Turner
Para el primer caso en onActivityResult photoUri no está asignado.
AkashToSky
2

Sospecho que esto se debe a los permisos que ha implementado en su AndroidManifest.xmlarchivo. Si está depurando en API Level 23una versión de Android o superior, entonces debe tomar el permiso de WRITE_EXTERNAL_STORAGEtiempo de ejecución en tiempo de ejecución ya que se produce una excepción de seguridad debido a un permiso denegado por el dispositivo.

Omkar C.
fuente
Tanto la lectura como la escritura externa ya están en el archivo de manifiesto.
Ceri Turner el
Por cierto, WRITE_EXTERNAL_STORAGE quedará obsoleto en la próxima versión de Android.
usuario70
2

Esto se debe a que en la nueva versión se Android 9introdujo un nuevo FOREGROUND_SERVICEpermiso; los documentos dicen:

Nota: Las aplicaciones que se dirigen Android 9 (API level 28)o son superiores y usan servicios en primer plano deben solicitar el FOREGROUND_SERVICE permission. Este es un permiso normal, por lo que el sistema lo otorga automáticamente a la aplicación solicitante. Si una aplicación que tiene API level 28como objetivo o intentos superiores de crear un servicio en primer plano sin solicitar FOREGROUND_SERVICE, el sistema arrojaSecurityException .

Simplemente agregue el permiso al manifiesto y debería hacer el truco, "en teoría". ¡¡Haznos saber!! Algo como:

<manifest ...>   
     <uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> 
     <application ...>
</manifest>

Tratemos de tomar esa recompensa: ¿Tienes estos permisos ?:

<uses-permission android:name="android.permission.MANAGE_DOCUMENTS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

También creo que esto no es tan malo para probar:

public static final String KITKAT_VALUE = 1002;

  Intent intent;

    if (Build.VERSION.SDK_INT < 19){
                            intent = new Intent();
                            intent.setAction(Intent.ACTION_GET_CONTENT);
                            intent.setType("image/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                        } else {
                            intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
                            intent.addCategory(Intent.CATEGORY_OPENABLE);
                            intent.setType("image/*");
                            startActivityForResult(intent, KITKAT_VALUE);
                    }

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
   if (requestCode == KITKAT_VALUE ) {
     if (resultCode == Activity.RESULT_OK) {
       // do something here
     }
  }
}
Qiqke
fuente
1
He echado un vistazo rápido a la información y no estoy seguro de cómo se aplica
Ceri Turner
¿No tiene un archivo llamado AndroidManifest.xmldonde coloca todos los permisos como:<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> </manifest>
Qiqke
He añadido eso y todavía se bloquea
Ceri Turner
¿Estás utilizando un tercer servicio de aplicación? ¿Quizás ese 3º está usando algunos permisos que no pueden usar?
Qiqke
La aplicación de terceros a la que accede es la aplicación de fotos de teléfonos. Lo único en lo que puedo pensar es que cambié la forma en que accedió hace un tiempo y me pregunto si los permisos nunca se configuraron para mantener el acceso. Las imágenes recién agregadas de las fotos funcionan, pero parece que las más antiguas no. Así es como se agregan las imágenes: pastebin.com/5CcqXQQu
Ceri Turner