Androidの全ファイルアクセス
Android でファイルマネージャなんかを作りたいときに役立つあれこれです。
はじめに:なるべくコンテンツプロバイダを使う
Android のファイルアクセスはFile
API とUri
とコンテンツプロバイダ使用する 2 通りに方法が存在しますが、セキュリティなどの観点から、基本的には後者を利用しましょう。例えばダウンロードフォルダにアクセスしたい時などはACTION_VIEW
Intent を使いますがこれの返り値はcontent
Uri になっています。これからなるべく FileAPI を使ってアクセスして欲しくない Google の意志が感じられます。。。
コンテンツプロバイダだとファイルマネージャは作れない
コンテンツプロバイダだとファイルの絶対パスが取得できないためファイルの階層構造を意識する必要があるファイルマネージャが作れません。
ではそんな時にどう作ればいいのかというのが本記事の主旨です。
本題:全ファイルアクセスするためには
FileAPI を用いてもデフォルトではファイルにアクセスする権限がないためにエラーが発生してしまいます。
なので権限を取得したりするなど厄介ごとが複数あるので要注意です。
公式ドキュメント
1. AndroidManifest で権限をリクエストする
AndroidManifest.xml で以下のように権限をリクエストします。ただしこれだけではまだ足りません。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<!-- ↓↓↓ ここ ↓↓↓ -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
<application>
...
2. アプリで権限をリクエストする
全ファイルにアクセスするためには特別な権限が必要なのでSettings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION
インテントを使って取得します。
Compose だと次のようになります。
val context = LocalContext.current
Button(onClick = {
val intent = Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION)
context.startActivity(intent)
}){
Text("権限をリクエスト")
}
表示されたボタンをクリックすると全ファイルをアクセスするための権限を付与するための設定画面が表示され、ユーザが設定をオンにすることでファイルにアクセスすることができるようになっています。
これで全ファイルにアクセスする準備が整いました。
3. ルートディレクトリの取得の仕方に注意
File("/")
ではルートディレクトリにアクセスできません。Environment.getExternalStorageDirectory()
(戻り値は File)を使用します。
val root = Environment.getExternalStorageDirectory()
val rootChildren = root.listFiles()
val rootName = root.name
...
Discussion