android - taking - FileProvider lanza una excepción en GetUriForFile
internal cache content provider (3)
Seguí el código de ejemplo en la referencia del desarrollador de Android en FileProviders pero no funcionará.
He configurado la ruta de los files/exports/
en la definición del proveedor de archivos en mi Manifiesto y los archivos de referencia existen en esa ruta.
En mi manifiesto:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.company.app.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" />
</provider>
Y en xml/file_paths.xml
<?xml version="1.0" encoding="UTF-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="exports" path="exports/"/>
</paths>
Luego trato de obtener el contenido-uri con el siguiente código:
Java.IO.File exportFile =
new Java.IO.File ("/data/data/com.company.app/files/exports/file.pdf");
Android.Net.Uri exportUri =
Android.Support.V4.Content.FileProvider.GetUriForFile (this, "com.company.app.fileprovider", exportFile);
Sin embargo me sale este error:
Exception of type ''Java.Lang.NullPointerException'' was thrown.
at Android.Runtime.JNIEnv.CallStaticObjectMethod (IntPtr jclass, IntPtr jmethod, Android.Runtime.JValue[] parms) [0x00064] in /Users/builder/data/lanes/monodroid-mlion-monodroid-4.10.2-branch/4b53fbd0/source/monodroid/src/Mono.Android/src/Runtime/JNIEnv.g.cs:1160
at Android.Support.V4.Content.FileProvider.GetUriForFile (Android.Content.Context context, System.String authority, Java.IO.File file) [0x00000] in <filename unknown>:0
at com.company.App.ImageAndSubtitle.cloudStorageDidDownloadFile (System.Object sender, com.company.App.CloudStorageEventArgs args) [0x001f7] in /app_path/Screens/ImageAndSubtitle.cs:187
--- End of managed exception stack trace ---
java.lang.NullPointerException
at android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243)
at android.support.v4.content.FileProvider.getPathStrategy(FileProvider.java:217)
at android.support.v4.content.FileProvider.getUriForFile(FileProvider.java:130)
at mono.java.lang.RunnableImplementor.n_run(Native Method)
at mono.java.lang.RunnableImplementor.run(RunnableImplementor.java:29)
at android.os.Handler.handleCallback(Handler.java:615)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4838)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:875)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:642)
at dalvik.system.NativeStart.main(Native Method)
Actualizar
Desde el código fuente de Android podría android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243)
hasta donde sé que este comando en android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243)
fallará y devolverá null
:
final ProviderInfo info = context.getPackageManager().resolveContentProvider(authority, PackageManager.GET_META_DATA);
Pero no tengo idea de por qué ...
Al intentar configurar un FileProvider para obtener un archivo PDF que se encuentra en el dispositivo y poder enviarlo por correo electrónico, también encontré esta excepción. Leyendo las diferentes respuestas, parece un poco complicado configurar manualmente el FileProvider (al menos esta primera vez) .
Finalmente, lo que funcionó para mí fue copiar los componentes de este ejemplo en un nuevo proyecto vacío: https://github.com/IanDarwin/Android-Cookbook-Examples/tree/master/PdfShare
Una vez que lo veo funcionando de forma independiente, puedo introducir los cambios en mi proyecto real.
Específicamente, aquí están los archivos para replicar:
1. AndroidManifest.xml : donde está toda la configuración complicada de FileProvider
2. file_paths.xml : este es un componente pequeño pero importante. En cuanto a SO, hay una variedad de respuestas sobre qué poner allí, sin embargo, solo con este proyecto me funcionó la configuración
3. MainActivity.java : la configuración de Java correspondiente para trabajar con lo que está configurado en el manifiesto; Y, por supuesto, no olvide el archivo de diseño asociado.
Este error ocurrió en mi caso porque había pasado un nombre de paquete incorrecto al segundo parámetro de GetUriForFile
. Utilicé BuildConfig.PACKAGE_NAME
que se resolvió en android.support.multidex que es incorrecto.
Finalmente encontré un buen código de ejemplo sobre cómo crear ContentProviders y FileProviders en https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider
El error real en mi código fue que en el archivo Manifest tenía la etiqueta de provider
fuera de la etiqueta de la application
, pero debía estar dentro. El Manifiesto debe verse así:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.company.app">
<uses-sdk android:minSdkVersion="13" />
<permission
android:name="com.company.app.fileprovider.READ"
android:description="@string/perm_read"
android:label="@string/perm_read_label"/>
<uses-permission android:name="com.company.app.fileprovider.READ"/>
<application android:label="MyApp">
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.company.app.fileprovider"
android:exported="false"
android:grantUriPermissions="true"
android:readPermission="com.company.app.fileprovider.READ">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
<uses-permission android:name="android.permission.INTERNET" />
</manifest>