ファイルを開こうとするとアプリがクラッシュします。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 を使用する必要があります。ただし、私のアプリはルート ディレクトリ内のファイルを開く必要があります。何かアイデアはありますか?
ベストアンサー1
の場合targetSdkVersion >= 24
、他のアプリからアクセスできるようにするには、クラスを使用して特定のファイルまたはフォルダにアクセスできるようにする必要があります。FileProviderが、インポートされた依存関係で宣言されたFileProviderと競合しないようにするために、FileProvider
継承する独自のクラスを作成します。FileProvider
ここ。
file://
URI を URI に置き換える手順content://
:
- タグの下に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
内にファイルを作成します。フォルダーがまだ存在しない場合は、作成する必要がある場合があります。ファイルの内容を以下に示します。これは、ルート フォルダーの外部ストレージへのアクセスをexternal_filesという名前で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);
説明されている完全なコードとソリューションを参照してくださいここ。