見出し画像

【Android】OSバージョンアップに伴うストレージの仕様変更についてまとめてみた

はじめに  


こんにちは、SHIFT DAAE(ダーエ)テクノロジーGのイケモトです。
今回はAndroidのOSバージョンアップに伴うストレージの仕様についてまとめました。

AndroidはOSバージョンアップごとにストレージの仕様が大きく変更されることがあり、その仕様は年々複雑化しています。そのため、ストレージを扱っているアプリをバージョンアップする際、どのような対応をすれば良いかが分かりにくいことがあります。

そこで、OSごとのストレージに関する仕様をまとめることでAndroidアプリのバージョンアップの際に役立てることができると思い、執筆しました。

前提


  • Android Developerのリリースノート の内容を元にまとめています。

  • Android4.4より前のバージョンに関しては、公式のバージョン情報 に記載されていないため、まとめの範囲外としています。

  • Android15に関しても、本記事の執筆時点(2024年5月)では、バージョンがBeta1のため対象外としました。

Androidのストレージに関する簡単なおさらい


Androidのストレージを分類すると以下の4つになります。

  • アプリ専用の内部ストレージ

  • アプリ専用の外部ストレージ

  • メディアファイル用の共有ストレージ

  • ドキュメント・その他のファイル用の共有ストレージ

勘違いされやすいのは、内部ストレージと外部ストレージの違いです。この違いは、保存場所や他のアプリからのアクセスの可否に関係しており、端末の内蔵ストレージか取り外し可能なSDカードかとは直接関係していません

Android14での各ストレージを図で表すと下のようになります。

画像

各OSごとでの仕様変更


Android4.4

Android5.0

  • SAFの機能が拡張され、ACTION_OPEN_DOCUMENT_TREE Intentを使うことでディレクトリ全体に読み書きの権限を付与できるようになりました。

Android6.0

  • 実行時パーミッションチェックが実装されました

    • この実装によってWRITE_EXTERNAL_STORAGE 権限を付与するために、実行時パーミッションチェックを利用して権限付与をする必要ができました。

Android7

  • プライベートファイルへのセキュリティを高めるために、アプリのプライベートディレクトリのパーミッションは0700になりました。

  • SharedPreferencesのMODE_WORLD_READABLEモードとMODE_WORLD_WRITEABLEモードが使用できなくなりました。

    • ファイル共有を行うにはFileProvider を使う必要が生じました。

  • DownloadManager においてプライベートディレクトリにダウンロードされたファイルは共有できなくなりました。

    • Android 7.0未満向けアプリでは外部ストレージに置かれたファイルのみ COLUMN_LOCAL_FILENAME でアクセスできますが、公式がこの方法を非推奨としています。

  • file:// で始まるURIを利用してアプリ間でファイル共有を行なっていた場合、FileProviderを利用してcontent:// で始まるURIに置き換える必要が生じました。

Android8

Android8はファイルに関する仕様変更はありません

Android9

  • 他のアプリからアプリ固有のファイル へのアクセスが制限されるようになりました。

    • 内部ストレージに保存されているファイルはアクセス不可、外部ストレージに関しては適切なストレージ権限が付与されていれば、他のアプリに属するアプリ固有のファイルにアクセスできるようになります。

  • Android9から、他のアプリとファイル共有するのにContentProvider の使用が推奨されています。

Android10

  • Scoped Storage が追加されました。

    • これにより、外部ストレージ内のファイルはSAFもしくはMedia Store API 経由でしかアクセスできなくなりました。

    • 移行措置として、TargetSdkVersion29以下のアプリにおいてはrequestLegacyExternalStorage オプションを使うことで、この仕様を回避できます。

  • Media Store API に MediaStore.Downloads テーブルが追加されました。

Android11

Android11では、他のバージョンに比べて大幅な改修が入りました。

  • Android10で実装されたScoped Storageが強制的に適応されるようになりました。 

    • 仮にAndroid10へのアップデートタイミングでrequestLegacyExternalStorage=false を記述していても無視されます。

  • 外部ストレージ上にアプリ固有のディレクトリが作成できなくなりました。

    • Android11からはContext.getExternalFilesDirs で取得できるパス以下にしかアプリ固有のディレクトリが作成できなくなりました。

  • Java File API と fopen()などのネイティブ メソッドを経由することでメディアファイルにアクセスできるようになりました。

  • Android11以降では、他のアプリからは内部/外部ストレージのアプリ固有のデータに一切アクセスすることができなくなりました。

    • この変更により、WRITE_EXTERNAL_STORAGE権限が不要となりました。

  • SAF経由でアクセス権を付与できるディレクトリに制限がつきました。

    • ACTION_OPEN_DOCUMENT_TREEIntentを利用した場合は、以下のディレクトリには権限が付与できません。

      • 内部ストレージのルートディレクトリ

      • SDカードのルートディレクトリ

      • Download ディレクトリ

    • ACTION_OPEN_DOCUMENT_TREE または ACTION_OPEN_DOCUMENTIntentを利用した場合は、以下のディレクトリには権限が付与できません。

      • Android/data/ とその配下のディレクトリ

      • Android/obb/ とその配下のディレクトリ

  • ファイルマネージャーやファイルのバックアップ & リストアといった機能を持つアプリに向けて、Manage External Storage権限が追加されました。

    • この権限を使うと外部ストレージを全て読むことができるようになります。

    • ただし、この権限を有効にしたアプリをGoogle Play Storeにリリースしたい場合、一定の基準 をクリアしないとリリースできないようになります。

Android12

新機能追加がメインなため、必須の改修はないです。

  • Media Store API の MediaStore.Audio テーブルに録音音声を保存および識別するための Recordings/ ディレクトリが追加されました。

  • MANAGE_MEDIA 権限が新しく追加されました。

    • アプリが毎回確認ダイアログを表示せずにメディアファイルの移動、変更、削除を行えるようにするための権限です。

  • Media Store API のgetMediaUri メソッドが、MediaDocumentsProvider形式のURIに対してもサポートするようになりました。

  • StorageManager にgetManageSpaceActivityIntent が追加されました。

    • 他のファイルマネージャーなどにアクティビティを公開したい場合に利用します。

Android13

  • TargetSdkVersion >= 33のアプリにおいて、他のアプリが作成したメディアファイルにアクセスしたい場合、READ_EXTERNAL_STORAGE権限ではなく、各メディアの種類に応じた権限を付与させる必要が生じました。

    • ただし、既にアプリに対して READ_EXTERNAL_STORAGE 権限を付与されていた場合はOSアップデート時に自動でそれぞれのメディアに応じたREAD_MEDIA_*権限が付与されます。

画像

Android14

  • アプリがREAD_MEDIA_IMAGESおよびREAD_MEDIA_VIDEO権限の許可を要求した際に、ユーザーは写真と動画への部分的なアクセス権 を付与できるようになりました。

    • ユーザーがどの写真や動画にアクセス権を付与するかは、PhotoPicker を通して選択されます。

    • この仕様は、Android14以上をターゲットとする場合のみ適応されます。

ファイルストレージに関するユースケース


こちらに関しては、公式が開発ガイド を提供していますので、このガイドを一読することをおすすめします。

ただし、Android 13およびAndroid 14に関連するREAD_MEDIA_*権限に関する記載がこのガイドには抜けているため、その点については注意が必要です。

おわりに


今回はAndroidのファイルストレージに関する仕様をまとめました。
OSのバージョンが上がるたびにファイル操作が複雑になっていることが伝わったかと思います。

自身がファイルを扱うアプリに携わっている場合、AndroidのOSバージョンアップの際はファイルストレージの仕様に変更がないかをしっかりと確認するようにしましょう。

\もっと身近にもっとリアルに!DAAE公式X/


執筆者プロフィール:Ikemoto Fumito
Unity・C#でのゲーム開発やKotlin・JavaでのAndroidアプリ実装を主に行ってました。 最近はまたAndroidに返ってきました。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplashAzamat E


みんなにも読んでほしいですか?

オススメした記事はフォロワーのタイムラインに表示されます!

ピックアップされています

SHIFT DAAEブログ

  • 122本

コメント

コメントを投稿するには、 ログイン または 会員登録 をする必要があります。
「無駄をなくしたスマートな社会の実現」を目指し、ソフトウェア製品の開発、運用、マーケティングなどあらゆる立場から携わるSHIFT Groupの公式note。エンタメ・ゲーム業界から、Web系、金融/製造/小売りなどのエンタープライズ業界まで広い知見を活かした情報を発信しています。
【Android】OSバージョンアップに伴うストレージの仕様変更についてまとめてみた|SHIFT Group 技術ブログ
word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word word

mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1
mmMwWLliI0fiflO&1