SAFでURIに対するアクセス許可の永続化

投稿日:  更新日:

Storage Access Framework(SAF)は、ファイルピッカーでアクセス対処のファイル(またはフォルダ)を指定する仕組みです。

指定されたURI(ファイル、フォルダ)は、アプリがアクセスする許可を付与したものになります。

そのまま、そのURIを使って読み書きが可能です。

ただし、このアクセス許可には期限があります。期限を過ぎれば失効します。

失効したら、再びファイルピッカーで指定すれば良いですが、ユーザーの操作を伴います。ユーザーのエクスペリエンス(使い易さ)は下がるでしょう!

そのような場合に、URIに対するアクセス許可を永続化できます。

※環境:Android Studio Narwhal Feature Drop | 2025.1.2 Patch 2
    androidx.datastore:datastore-preferences:1.1.7

スポンサーリンク

アクセス許可の期限

アクセス許可は、アプリのプロセスがOS内で稼働している間、有効です。

無効になるのは、次の操作を行った場合です。

 無効になる操作 
  • ・端末を再起動した後、アプリを起動
  • ・Recentリストからアプリをクリアした後、アプリを起動
  • ・アプリのストレージをクリアした後、アプリを起動

これらの操作は、アプリをプロセスごと停止し、新たなプロセスでアプリを起動するためです。

スポンサーリンク

アクセス許可の永続化

takePersistableUriPermissionを使い、永続化します。

        // Uriへアクセスする許可を永続化
        val _takeFlags: Int = FLAG_GRANT_READ_URI_PERMISSION or
                FLAG_GRANT_WRITE_URI_PERMISSION
        this@Activity.contentResolver.takePersistableUriPermission(uri, _takeFlags)
		//
スポンサーリンク

永続化の例

Storage Access Framework(SAF)でピッカーにより指定したフォルダを、アプリのワークフォルダにする例です。

ワークフォルダは、アプリの使い初めに一度だけ指定し、その後は同じフォルダを使い続けたいので、永続化します。

val Context.dataStore: DataStore<Preferences> by preferencesDataStore(name = "settings")
val WORK_FOLDER = stringPreferencesKey("work_folder")

class MainActivity : ComponentActivity() {

    private var workFolderUri: Uri? = null
    private val workFolderPicker = SafPicker { uri ->
        // Uriへアクセスする許可を永続化
        val _takeFlags: Int = FLAG_GRANT_READ_URI_PERMISSION or
                FLAG_GRANT_WRITE_URI_PERMISSION
        contentResolver.takePersistableUriPermission(uri, _takeFlags)
        // UriをDataStoreへ書き込み
        lifecycleScope.launch(Dispatchers.IO) {
            dataStore.edit { settings ->
                settings[WORK_FOLDER] = uri.toString()
            }
        }
        // Uriの保持
        workFolderUri = uri
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val _workFolderFlow: Flow<Uri?> = dataStore.data
            .map { preferences ->
                val _workFolder = preferences[WORK_FOLDER]
                _workFolder?.let { it.toUri() }
            }

        lifecycleScope.launch(Dispatchers.IO) {
            // UriをDataStoreから読み出し
            workFolderUri = _workFolderFlow.first()
            // Uri未定義ならば取得処理
            if(workFolderUri == null) {
                workFolderPicker.launch(TreeOpenIntent())
            }
        }

        enableEdgeToEdge()
        setContent { ... }
    }
}

アプリの設定をDataStoreで管理しています。

アプリは起動すると、アプリの設定(ワークフォルダ)をDataStoreから読み出します。※Flowを使った非同期処理になっています。

ワークフォルダのURIが未定義(null)ならば、ファイルピッカーを起動して、フォルダの指定をユーザに求めます。

そして、ピッカーの結果として受け取ったURI(フォルダ)を永続化し、DataStoreに書き込みます。

※SAFの詳細は以下を参照(例は同じ関数を利用している)
外部ストレージへStorage Access Frameworkでアクセス
SAFのACTION_OPEN_DOCUMENT_TREEでフォルダを指定

※DataStoreの詳細は以下を参照
DataStore

スポンサーリンク

関連記事:

ストレージのリソースは、内部メモリー、外部メモリー、クラウドの3つがあります。 外部メモリーは、主にSDカードです。 このSDカードはAndroid端末の世代が進むにつれて、扱いを変えてきました。 リソースとSDカードを主眼に置いたストレージの変遷について、まとめます。 ※環境:Android Studio Narwhal | 2025.1.1 Patch 1 ...
Adoptable Storage(API≧23、Android 6.0)が導入されて、SDカードの扱い方をユーザ側で指定できるようになりました。 「Adoptable Storage」について、まとめます。 ※環境:Android Studio Narwhal | 2025.1.1 Patch 1 ...
ストレージはデータの用途別に記憶領域が分けられます。 保存先を守らないと、セキュリティリスクが発生したり、他のアプリと協調した動作が出来なくなったり、します。 ですので、適切な場所へデータを保存しましょう。 今回は「用途別記憶領域とボリューム」について、まとめます。 ※環境:Android Studio Narwhal | 2025.1.1 Patch 1 ...
ストレージへアクセスする方法は、「扱うデータの種類」「アクセス先」「セキュリティの確保」などの要件により、最適なアクセス方法が存在するので、使い分けが必要です。 今回は「アクセスする方法」について、まとめます。 ※環境:Android Studio Narwhal | 2025.1.1 Patch 1 ...
外部ストレージへアクセスするアプリは、パーミッション(許可)をユーザーから取得する必要があります。 パーミッションを得たアプリは、許可された権限の範囲内で、ストレージへアクセスが可能です。 これらは、ユーザーデータのプライバシー保護と密接に関係しています。 プライバシー保護をより強固にするために、パーミッションと権限の範囲の仕様は改変されてきました。 今回は、改変の歴史を辿りつつ、「パーミッションと権限の範囲」について、まとめます。 ※環境:Android Studio Narwhal | 2025.1.1 Patch 1 ...
Storage Access Framework(SAF)は、ファイルピッカーでアクセス対処のファイルを指定する仕組みです。 SAFはアンドロイドシステムに実装されています。SAFを用いれば、ピッカーを自作する必要はありません。 アプリ開発が楽になります。 しかも、指定された外部ストレージ上のファイルは、アプリに対するアクセス許可を付与したものになります。 改めて、許可の取得は不要です。そのまま、ファイルを読み書き出来ます。 今回は「外部ストレージへStorage Access Frameworkでアクセス」を、まとめます。 ※環境:Android Studio Narwhal Feature Drop | 2025.1.2 Patch 1 ...
Storage Access Framework(SAF)は、ファイルピッカーでアクセス対処のファイルを指定する仕組みです。 API≧21で、ACTION_OPEN_DOCUMENT_TREEアクションが追加され、フォルダを指定するリクエストが構築できるようになりました。 今回は「SAFのACTION_OPEN_DOCUMENT_TREEでフォルダを指定」について、まとめます。 ※環境:Android Studio Narwhal Feature Drop | 2025.1.2 Patch 1     androidx.documentfile:documentfile:1.1.0 ...
Storage Access Framework(SAF)は、ファイルピッカーでアクセス対処のファイルを指定する仕組みです。 ファイルピッカーの初期フォルダは、前回の状態が引き継がれます。 また、初期フォルダを意図的に指定することも可能です。 今回は「初期フォルダの指定方法」について、まとめます。 ※環境:Android Studio Narwhal Feature Drop | 2025.1.2 Patch 2 ...
useスコープ関数は、オブジェクトが確保したリソースの開放(close関数の実行)を自動的に行ってくれる関数です。 とてもお勧めのスコープ関数です。 ※環境:Android Studio Hedgehog | 2023.1.1 Patch 2 ...
スポンサーリンク