provider_paths fileprovider android android-camera android-fileprovider
http://www.axzae.com/downloads/CameraWithFileProvider.zip

provider_paths - fileprovider android



FileProvider no funciona con la cámara (2)

Intento hacer que la aplicación de la cámara almacene la salida en mi almacenamiento interno. También entiendo que las aplicaciones de terceros no pueden acceder al almacenamiento interno de mi aplicación PERO podemos hacerlo al exponer el directorio interno a través de FileProvider . He seguido la guía aquí:

Especifico mi AndroidManifest.xml de la siguiente manera:

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.stackoverflow.test.camerawithfileprovider" > <application> <activity ... </activity> <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.stackoverflow.test.camerawithfileprovider.fileprovider" android:exported="false" android:grantUriPermissions="true" > <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_provider_path" /> </provider> </application> </manifest>

file_provider_path.xml un archivo xml llamado file_provider_path.xml en /res/xml/ :

<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <files-path name="image_capture" path="public/" /> </paths>

Así es como creo y llamo el Intento de la cámara:

private static final int CAMERA_REQUEST_CODE = 5000; private static final String CAMERA_FP_AUTHORITY = "com.stackoverflow.test.camerawithfileprovider.fileprovider"; Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); Context context = MainActivity.this; File imagePath = new File(context.getFilesDir(), "public"); if (!imagePath.exists()) imagePath.mkdirs(); File newFile = new File(imagePath, "tmp.jpg"); Uri imageUri = FileProvider.getUriForFile(context, CAMERA_FP_AUTHORITY, newFile); //context.grantUriPermission("com.google.android.GoogleCamera", imageUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); Log.d("YouQi", "Image URI Passing to Camera: " + imageUri.toString()); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, CAMERA_REQUEST_CODE);

Cuando ejecuto la aplicación, puedo obtener el siguiente resultado de Logcat:

11-11 20:07:39.581 18303-18303/com.stackoverflow.test.camerawithfileprovider D/YouQi: Image URI Passing to Camera: content://com.stackoverflow.test.camerawithfileprovider.fileprovider/image_capture/tmp.jpg

Justo en el momento en que la cámara se cierra, presiono la siguiente excepción:

com.google.android.GoogleCamera E/AndroidRuntime: FATAL EXCEPTION: main com.google.android.GoogleCamera E/AndroidRuntime: Process: com.google.android.GoogleCamera, PID: 19420 com.google.android.GoogleCamera E/AndroidRuntime: java.lang.SecurityException: Permission Denial: opening provider android.support.v4.content.FileProvider from ProcessRecord{42e44f70 19420:com.google.android.GoogleCamera/u0a83} (pid=19420, uid=10083) that is not exported from uid 10312 com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1465) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Parcel.readException(Parcel.java:1419) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityManagerProxy.getContentProvider(ActivityManagerNative.java:2882) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityThread.acquireProvider(ActivityThread.java:4544) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2274) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1425) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:906) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openOutputStream(ContentResolver.java:669) com.google.android.GoogleCamera E/AndroidRuntime: at android.content.ContentResolver.openOutputStream(ContentResolver.java:645) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.camera.PhotoModule.onCaptureDone(PhotoModule.java:1281) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.camera.PhotoModule$8.onClick(PhotoModule.java:593) com.google.android.GoogleCamera E/AndroidRuntime: at android.view.View.performClick(View.java:4445) com.google.android.GoogleCamera E/AndroidRuntime: at android.view.View$PerformClick.run(View.java:18446) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:733) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) com.google.android.GoogleCamera E/AndroidRuntime: at android.os.Looper.loop(Looper.java:136) com.google.android.GoogleCamera E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:5146) com.google.android.GoogleCamera E/AndroidRuntime: at java.lang.reflect.Method.invokeNative(Native Method) com.google.android.GoogleCamera E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:515) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:732) com.google.android.GoogleCamera E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:566) com.google.android.GoogleCamera E/AndroidRuntime: at dalvik.system.NativeStart.main(Native Method)

¿Alguien puede ayudar a explicar por qué ocurre el problema? He creado un proyecto de muestra de mi problema: http://www.axzae.com/downloads/CameraWithFileProvider.zip

De todos modos, la aplicación funcionará si especifico explícitamente:

context.grantUriPermission( "com.google.android.GoogleCamera", imageUri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION );

Pero esto solo funcionará para los dispositivos nexus / cyanogen. La aplicación de la cámara Samsung podría usar un nombre de paquete diferente.


  1. No intente poner exported="true" como lo señala pskink , su aplicación se bloqueará en el momento en que se carga. FileProvider no está diseñado para funcionar en este estado.

  2. Intentó la solución CommonsWare de CommonsWare . No funciona. probablemente solo funcionará con el tipo de intento ACTION_SEND .

  3. Encontré la respuesta en esta publicación . Aparentemente, la forma de concesión manual es la única solución. Pero siempre podemos recorrer la lista de paquetes candidatos y otorgar Permiso a todos ellos.

    List<ResolveInfo> resInfoList = context.getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); for (ResolveInfo resolveInfo : resInfoList) { String packageName = resolveInfo.activityInfo.packageName; context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION); }


Tuve un problema similar, pero más tarde descubrí que tengo un error tipográfico en mi código. El error tipográfico estaba en AndroidManifest.xml, precisamente en la etiqueta en la línea "autoridades".

Para mi,

android:authorities="com..test.camerawithfileprovider.fileprovider"

no funciona (cuando llamo a la instancia de la cámara, la aplicación falla) pero si elimino "archivo" y reemplazo esa cadena de la siguiente manera:

android:authorities="com..test.camerawithfileprovider.provider"

mi aplicación funciona sin problemas (la aplicación toma la foto, la almacena y devuelve una vista previa de la actividad en la aplicación del cliente).

¿Tu aplicación también tiene el mismo problema?