🗂️

Androidの全ファイルアクセス

2022/11/24に公開約1,700字

Androidでファイルマネージャなんかを作りたいときに役立つあれこれです。

はじめに:なるべくコンテンツプロバイダを使う

AndroidのファイルアクセスはFile APIとUriとコンテンツプロバイダ使用する2通りに方法が存在しますが、セキュリティなどの観点から、基本的には後者を利用しましょう。例えばダウンロードフォルダにアクセスしたい時などはACTION_VIEWIntentを使いますがこれの返り値はcontent Uriになっています。これからなるべくFileAPIを使ってアクセスして欲しくないGoogleの意志が感じられます。。。

https://developer.android.com/guide/topics/providers/content-provider-basics?hl=ja

コンテンツプロバイダだとファイルマネージャは作れない

コンテンツプロバイダだとファイルの絶対パスが取得できないためファイルの階層構造を意識する必要があるファイルマネージャが作れません
ではそんな時にどう作ればいいのかというのが本記事の主旨です。

本題:全ファイルアクセスするためには

FileAPIを用いてもデフォルトではファイルにアクセスする権限がないためにエラーが発生してしまいます。
なので権限を取得したりするなど厄介ごとが複数あるので要注意です。

公式ドキュメント
https://developer.android.com/training/data-storage/manage-all-files?hl=ja

1. AndroidManifestで権限をリクエストする

AndroidManifest.xmlで以下のように権限をリクエストします。ただしこれだけではまだ足りません

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

ログインするとコメントできます