21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

【Android】対象別範囲ストレージとSAF

Last updated at Posted at 2019-09-06
1 / 8

SAF(StorageAccessFramework)とは?

  • Androidでストレージ周りを取り扱う仕組みのこと。
  • filepathではなく、Uriを使いコンテンツを特定する。
  • Contentスキーマなので、Uri.fromFile()による相互変換は効かない。
  • 特定のアプリは2020のアップデートで全てのSDKバージョンで対応必須になる(後述)
これは利用できない.
// uri <- file
val uri = Uri.fromFile(file)

// file <- uri
val file = File(uri.path)

filepathでよくない?

  • アプリ内領域を使う分にはfilepathでよい。
  • getExternalFilesDir()はそのまま利用可能。
  • アプリ内領域なので、アプリストレージを消去とかしたら当然消える
// 使える
Context.getExternalFilesDir()

// 使えない(API29よりDeprecated)
Environment.getExternalStorageDirectory()
Environment.getExternalStoragePublicDirectory()

じゃあどういうときに使うの

  • [対象範囲別ストレージ]
    (https://developer.android.com/preview/privacy/scoped-storage)
  • AndroidQより外部ストレージのアクセスが更に厳格化された
  • 2020のアップデートでは全てのSDKバージョンで対応必須にするとのこと
  • 外部アプリが作成したものにアクセスする、外部ストレージに書き込みを行う等
  • SAFを介して権限をユーザに要求することでアクセスが許可されるようになる

何を使えばいいかの判断

判断材料 使うもの
アプリ内のみで使います Content.getExternalFilesDir()
アプリ外でメディアを永続保存・共有します MediaStore + ContentResolver
アプリ外でファイルを永続保存・共有します SAF + ContentResolver

SAFの基本

  • Intentを投げてピッカーを開く
  • ユーザが操作する
  • onActivityResultでUriを受け取って処理
fun performFileSearch() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        addCategory(Intent.CATEGORY_OPENABLE)
        type = "image/*"
    }
    startActivityForResult(intent, READ_REQUEST_CODE)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) {
    if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
        resultData?.data?.also { uri ->
            Log.i(TAG, "Uri: $uri")
            showImage(uri)
        }
    }
}

SAFで権限付きアクセス

  1. 権限を要求するIntentを発行
  2. ユーザがいいよって言う
  3. Resultでuriを受け取り、ContentResolverでクエリを発行

SDカード保存(Android9以前)

  • CreateAccessIntentの廃止により、権限を覚えさせておくことができなくなった?
    • リフレクションでパスを強引に取得したりURIいじくり回して権限を覚えさせるとか試されているらしい -> リンク

Screenshot_20190905-195443.png


MediaStore

対象別範囲ストレージで外部に存在するが、それがメディア(画像・音楽・音声)である場合はMediaStoreからUriを取得できる

  • 写真 - 保存場所: MediaStore.Images
  • 動画 - 保存場所: MediaStore.Video
  • 音楽ファイル - 保存場所: MediaStore.Audio

AndroidDeveloperに書いてあることが昨日と違う・・・最新情報を確認してください。

21
17
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?