问题
I followed the example code on the android developer reference on FileProviders but it won't work.
I have setup the path files/exports/
in the file provider definition in my Manifest and the referenced files does exist at that path.
In my Manifest:
<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>
And in 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>
Then I try to get the content-uri with the following code:
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);
However I get this 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)
Update
From the Android source code I could hunt that down so far as I now know that this command in android.support.v4.content.FileProvider.parsePathStrategy(FileProvider.java:243)
will fail and return null
:
final ProviderInfo info = context.getPackageManager().resolveContentProvider(authority, PackageManager.GET_META_DATA);
But I have no idea why...
回答1:
I finally found good example code on how to create ContentProviders and FileProviders on https://github.com/commonsguy/cw-omnibus/tree/master/ContentProvider
The actual error in my code was that in the Manifest file I had the provider
tag outside of the application
tag, but it must be inside.
The Manifest must look like this:
<?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>
回答2:
In trying to set up a FileProvider for getting a PDF file that is on the device and being able to email it out, I ran into this exception as well. Reading the different answers out there - it seems a bit complicated to get the FileProvider set up correctly by hand (at least this first time around).
Finally what worked for me was to copy the components from this example into an empty new project: https://github.com/IanDarwin/Android-Cookbook-Examples/tree/master/PdfShare
Once I see it working in the standalone, then I'm able to bring in the changes to my actual project.
Specifically, here are the files to replicate:
1. AndroidManifest.xml - where all the tricky FileProvider config is
- https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/AndroidManifest.xml
2. file_paths.xml - This is a small but important component. Looking on SO there are a variety of answers for what to put there, however only from this project did the set up work for me
- https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/res/xml/file_paths.xml
3. MainActivity.java - the corresponding Java setup to work with what's configured in the manifest; and of course don't forget the associated layout file
- https://github.com/IanDarwin/Android-Cookbook-Examples/blob/master/PdfShare/src/main/java/com/example/pdfshare/MainActivity.java
回答3:
This error occurred in my case because I had passed an incorrect package name to the second parameter of GetUriForFile
. I used BuildConfig.PACKAGE_NAME
which resolved to android.support.multidex which is incorrect.
来源:https://stackoverflow.com/questions/21931169/fileprovider-throws-exception-on-geturiforfile