web-dev-qa-db-ja.com

Android 7を使用したFileUriExposedException

写真をキャプチャしようとすると、このエラーが発生します:

致命的な例外:メインのAndroid.os.FileUriExposedException:file:///storage/emulated/0/fname_1498727381241.jpgは、Android.os.StrictMode.onFileUriExposed(StrictMode.Java:1799)のClipData.Item.getUri()を介してアプリを超えて公開されていますAndroid.net.Uri.checkFileUriExposed(Uri.Java:2346)at Android.content.ClipData.prepareToLeaveProcess(ClipData.Java:835)at Android.content.Intent.prepareToLeaveProcess(Intent.Java:9514)at Android.content。 Intent.prepareToLeaveProcess(Intent.Java:9499)at Android.app.Instrumentation.execStartActivity(Instrumentation.Java:1525)at Android.app.Activity.startActivityForResult(Activity.Java:4403)at Android.app.Activity.startActivityForResult(Activity .Java:4362)opteamit.com.belami.CommuniquerPartagerPhotosActivity $ 1.onClick(CommuniquerPartagerPhotosActivity.Java:46)at Android.view.View.performClick(View.Java:6261)at Android.view.View $ PerformClick.run(View .Java:23752)Android.os.Handler.handleCallback(Handler.Java:751)at Android.os.Handler.dispatchMessage(Hand ler.Java:95)Android.os.Looper.loop(Looper.Java:154)at Android.app.ActivityThread.main(ActivityThread.Java:6776)at Java.lang.reflect.Method.invoke(Native Method) com.Android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.Java:1496)at com.Android.internal.os.ZygoteInit.main(ZygoteInit.Java:1386)

以前は機能していましたが、Android 7(API 24)を使用しているため問題があるようです。

これは私のコードです:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                imageUri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "fname_" +
                        String.valueOf(System.currentTimeMillis()) + ".jpg"));
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE);
9
Jéwôm'

TargetSdkVersionが24以上の場合、FileProviderクラスを使用して特定のファイルまたはフォルダーにアクセスし、他のアプリからアクセスできるようにする必要があります。ここで説明するように、FileProviderがインポートされた依存関係で宣言されたFileProviderと競合しないように、FileProviderを継承する独自のクラスを作成します。

関連する議論を見つける こちら

Android 7なので、file:スキームをuriとして意図的に使用しないため、FileProviderを使用する必要があります。

6
Juvi

まあ、それを行う正しい方法は、FileProvider開発者で述べたように )を使用することです。しかし、FileProviderを追加せずにそれを行うためのいたずらな方法を見つけました。これは明らかに回避策ですが、動作します。

アクティビティで、次の行を追加します。

 StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
 StrictMode.setVmPolicy(builder.build());

これはURIの露出を単に無視し、アクセスを取得します。

はい、私はこれがベストプラクティスではないことを知っています。しかし、私はそれに代わるものを提供したかっただけです。

それでも、推奨される方法はFileProviderを使用することです。

20
Tushar Gogna