[解決済み] android.os.FileUriExposedException: file:///storage/emulated/0/test.txt が Intent.getData() によりアプリの外部に公開された。
質問
ファイルを開こうとすると、アプリがクラッシュしてしまいます。Android Nougat以下では動作するのですが、Android Nougatではクラッシュしてしまいます。システムパーティションからではなく、SDカードからファイルを開こうとしたときだけクラッシュします。何らかのパーミッションの問題でしょうか?
サンプルコードです。
File file = new File("/storage/emulated/0/test.txt");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "text/*");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent); // Crashes on this line
ログを表示します。
<ブロッククオートandroid.os.FileUriExposedException: file:///storage/emulated/0/test.txt を通してアプリの外に公開されました。 Intent.getData()
編集する
Android Nougatをターゲットにした場合。
file://
URIは使用できなくなりました。そのため
content://
URIを使用します。しかし、私のアプリはルートディレクトリのファイルを開く必要があります。何かアイデアはありますか?
解決方法は?
もし、あなたの
targetSdkVersion >= 24
を使用する必要があります。
FileProvider
クラスを使って、特定のファイルやフォルダにアクセスできるようにし、他のアプリからアクセスできるようにします。を継承した独自のクラスを作成します。
FileProvider
のように、インポートされた依存関係で宣言された FileProvider と競合しないようにするためです。
ここで
.
置き換えの手順
file://
URIを
content://
URIです。
-
FileProviderを追加する
<provider>
タグをAndroidManifest.xml
の下に<application>
タグを使用します。に一意の権威を指定する。android:authorities
属性の競合を避けるために、インポートされた依存関係には${applicationId}.provider
といったよく使われる権限を持っています。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
...
<application
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
</application>
</manifest>
-
次に
provider_paths.xml
のファイルをres/xml
フォルダーに格納されます。フォルダがまだ存在しない場合は作成が必要な場合があります。ファイルの内容は以下の通りです。ルートフォルダーの外部ストレージへのアクセスを共有したいことが記述されています。(path=".")
という名前で 外部ファイル .
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="external_files" path="."/>
</paths>
-
最後のステップは、以下のコードの行を
Uri photoURI = Uri.fromFile(createImageFile());
になります。
Uri photoURI = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", createImageFile());
-
編集する。 システムにファイルを開かせるためにインテントを使用している場合、次の行を追加する必要があるかもしれません。
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
説明されている全コードと解決策を参照してください。 はこちらです。
関連
-
Androidのadbデバイスがオフラインであることが判明
-
armeabi-v7a armeabi arm64-v8a パラメータの意味説明
-
デフォルトのアクティビティが見つからない場合の対処法
-
アンドロイドプロジェクトのパッケージングにgradleを使用する際の問題点
-
Android のパッケージングに失敗し、Android リソースのリンクに失敗したことを示すプロンプトが表示される
-
アプリケーションがメインスレッドで過剰に作業している可能性があります。
-
Windowsのadbシェルでデータディレクトリにアクセスするとパーミッションが拒否される
-
Android ProgressBarの色を変更する
-
Android ProgressBarのスタイルカラーを変更する
-
アンドロイドリストビュー
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
AAPT2エラーについて:詳しくはログをご確認ください。
-
AndroidエミュレーターのADBサーバーがACKしない問題
-
android E/RecyclerView﹕ アダプタが接続されていないため、レイアウトをスキップする。
-
ArrayAdapter は、リソース ID が TextView であることが必要です。
-
ActivityはOnFragmentInteractionListenerを実装しなければならないに関する質問
-
アンドロイドスタジオのエラーを解決する --> Error:(1, 0) id 'com.android.application' を持つプラグインが見つかりません。
-
ConstraintLayoutのいくつかのプロパティの概要(RelativeLayoutの強化版、LinearLayoutの比例プロパティを含む、階層ツールの削減)。
-
問題 ---- Android ---- ActivityManager: Error: アクティビティクラス{xx/xx.MainActivity}が存在しない
-
Androidのカラーグラデーション実装のまとめ
-
アンドロイドの遅延実行のいくつかの方法