1. ホーム
  2. android

[解決済み] android.os.FileUriExposedException: file:///storage/emulated/0/test.txt が Intent.getData() によりアプリの外部に公開された。

2022-03-23 23:57:19

質問

ファイルを開こうとすると、アプリがクラッシュしてしまいます。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);
    
    

説明されている全コードと解決策を参照してください。 はこちらです。