The Exception is:
file:// Uri exposed through ClipData.Item.getUri()
java.lang.Throwable: file:// Uri exposed through ClipData.Item.getUri()
at android.os.StrictMode.onFileUriExposed(StrictMode.java:1618)
at android.net.Uri.checkFileUriExposed(Uri.java:2341)
at android.content.ClipData.prepareToLeaveProcess(ClipData.java:808)
at android.content.Intent.prepareToLeaveProcess(Intent.java:7926)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1506)
at android.app.Activity.startActivityForResult(Activity.java:3832)
at android.app.Activity.startActivityForResult(Activity.java:3783)
at android.support.v4.app.FragmentActivity.startActivityFromFragment(Unknown Source)
at android.support.v4.app.Fragment.startActivityForResult(Unknown Source)
at me.chunyu.ChunyuDoctor.Utility.w.takePhoto(Unknown Source)
at me.chunyu.ChunyuDoctor.Dialog.ChoosePhotoDialogFragment.takePhoto(Unknown Source)
at me.chunyu.ChunyuDoctor.Dialog.ChoosePhotoDialogFragment.access$000(Unknown Source)
at me.chunyu.ChunyuDoctor.Dialog.b.onClick(Unknown Source)
at me.chunyu.ChunyuDoctor.Dialog.ChoiceDialogFragment.onClick(Unknown Source)
at android.view.View.performClick(View.java:4848)
at android.view.View$PerformClick.run(View.java:20270)
at android.os.Handler.handleCallback(Handler.java:815)
at android.os.Handler.dispatchMessage(Handler.java:104)
at android.os.Looper.loop(Looper.java:194)
at android.app.ActivityThread.main(ActivityThread.java:5643)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:960)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
My code is here:
public static void takePhoto(Fragment fragment, int token, Uri uri) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (uri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
}
fragment.startActivityForResult(intent, token);
}
I searched the similar problems and solutions. And modify the code as follow:
public static void takePhoto(Fragment fragment, int token, Uri uri) {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
if (uri != null) {
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1);
}
fragment.startActivityForResult(intent, token);
}
But it is also not work.
It happend on Android 5.1 While work well on Android 4.3. Is there anyone meet the same problem? Ask for some advance. Waiting online...
So, I was actually reading about this, and it seems the correct solution to handle this is the following:
Notice there is a note that google says to create a "content://" file instead of a "file://" based resource.
This is from google:
Note: We are using getUriForFile(Context, String, File) which returns a content:// URI. For more recent apps targeting Android N and higher, passing a file:// URI across a package boundary causes a FileUriExposedException. Therefore, we now present a more generic way of storing images using a FileProvider.
Also, you will need to setup the following:
Now, you need to configure the FileProvider. In your app's manifest, add a provider to your application:
Note: (Taken from google's site)
Make sure that the authorities string matches the second argument to getUriForFile(Context, String, File). In the meta-data section of the provider definition, you can see that the provider expects eligible paths to be configured in a dedicated resource file, res/xml/file_paths.xml. Here is the content required for this particular example:
If you would like more information: read up here https://developer.android.com/training/camera/photobasics.html
Besides the solution using the FileProvider, there is another way to work around this. Simply put in Application.onCreate() method. In this way the VM ignores the file URI exposure.
The reason of this error is that file:// uri scheme no more supported because the security is exposed. https://code.google.com/p/android/issues/detail?id=203555
And We can not use file:// uri any more after with targetSDK 'N'. https://commonsware.com/blog/2016/03/14/psa-file-scheme-ban-n-developer-preview.html
So, answer is right. Anyone who use file:// have change content:// to provide kinds of local files.
To sum up : file:// scheme is now not allowed to be attached with Intent on targetSdkVersion 24 (Android Nougat)
You have to Change your code if you plan to support api 24+ two links : https://developer.android.com/training/camera/photobasics.html https://inthecheesefactory.com/blog/how-to-share-access-to-file-with-fileprovider-on-android-nougat/en
I have already resolved this problem.
First, this problem occurred because
StrictMode
prevents passing URIs with afile://
scheme.So there are two solutions:
Change
StrictMode
. See similar problem and its code. But for our apps, it is not realistic to modify the Android source code.Use another URI scheme, instead of
file://
. For example,content://
related toMediaStore
.So I chose the second method:
Also, there is another solution.