[Android] 外部ストレージにファイルを保存する WRITE_EXTERNAL_STORAGE

external storage 01 - [Android] 外部ストレージにファイルを保存する WRITE_EXTERNAL_STORAGE
こちらでアプリ内にファイルを保存を試しましたが、共用メモリの外部ストレージに保存することもできます。例えばカメラの画像などのある程度大きいファイルをたくさん保存するような領域です。

Android Studio 3.4.2
Android 9.+
AndroidX

 



EXTERNAL_STORAGE

 
外部ストレージとは、端末内の共用のストレージ領域あるいはSDカードを指しています。これは機種によって異なります。
 
昔はSDカードだけを指していたのですが、最近は端末内のパブリックなストレージも含みます。Googleの端末にはSDカードが無かったりします。
ストレージ オプション | Android Developers
 

storage 01 - [Android] 外部ストレージにファイルを保存する WRITE_EXTERNAL_STORAGEざっくりこんな感じ

 

 

パーミッション

 
外部ストレージへの読み書きには2つのパーミッションが必要です。
 
(1) AndroidManifest.xml にusers-permissionの記述を入れる

 
GoogleのDocumentでは読み書きの両方ではWRITE_EXTERNAL_STORAGEのみでいいようです。ストレージ オプション
 
(2) WRITE_EXTERNAL_STORAGE は dangerous permission なので、permission checkの実装が必要になります。これを実装するとユーザーに許可・不許可のダイアログを表示させ、ユーザーはいつでもアプリの許可設定を変更できます。
 
このpermission checkは実装がそこそこあります。テスト段階での確認をするだけならpermission checkをオミットすることができます。
 
permission checkの除外(テストのみ!)
最初は permission check 無しで実行して、External Storageを呼ぶところまで実行します。そこで止まってしまうかスルーするかもしれませんが終了。
 
該当アプリを「設定」から探し「権限」の項目にあるストレージをenableにします。
 
externalstorage 02 - [Android] 外部ストレージにファイルを保存する WRITE_EXTERNAL_STORAGE
 
これでユーザーがStorage permissionを許可した状態になります。
 
新規リリースでは邪道かもしれませんが、過去にリリースしたアプリの修正については、一時的にユーザーに説明して回避することもできるかもしれません。(そんな面倒なことを強いてでも使いたいというスグレモノアプリであればアリかもですネ)
 

permission check を含めた実装

 
Runtime Permissionの実装は以下参照ください。

Android 6.0からの変更として、既存アプリに大きな影響がでると思われるのがこの Runtime Permission だと言われて...
 

ファイルの読み書き

 
以前は外部ストレージのpathは
Environment.getExternalStorageDirectory().getPath()
によって取得できましたが非推奨になりました。

This method was deprecated in API level 29. To improve user privacy, direct access to shared/external storage devices is deprecated. When an app targets Build.VERSION_CODES.Q, the path returned from this method is no longer directly accessible to apps. Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

Reference: Environment | Android Developers

 
プライバシー向上のために、共有/外部ストレージデバイスへの直接アクセスはAPI29からできなくなり、以下がその代替として使えます。

ここでは Context#getExternalFilesDir を使います。
 
ファイルに書き込んで保存するために

  • FileOpenStream
  • OutputStreamWriter

を使ってみます。
 

 
読み出しです。

try-catch ではリソースの開放漏れが無いように、

finallyでclose()を入れるか
try-with-resourcesを使います

 

サンプルコード

 
まとめたコードです。
AndroidManifest.xml

 
MainActivity.java

 
isExternalStorageWritable()
これは、パーミッションとは別に、現在ストレージ領域を他の何かが処理をしていてアクセスすべきでない場合かどうかを確認しているものです。
isExternalStorageReadable()も同様です

activity_main.xml

 
リソース
strings.xml

 

 
実際に端末内のファイルとして保存されているか確認してみます。
Device File Explorerで覗くことができます。

external storage 02 - [Android] 外部ストレージにファイルを保存する WRITE_EXTERNAL_STORAGE
 
確かに、testfile.txtがストレージに作成されていて入力文字列が記述されています。
 
 
関連記事:

 
References:
ファイルを保存する
ストレージ オプション | Android Developers

誤字脱字、意味不明で分からにゃイ、
などのご意見はこちらから mailフォーム

ブックマークしておくと便利です このエントリーをはてなブックマークに追加




アプリ開発が上達するお勧め

アプリ開発を始めたけどわからないところがあり、誰かに聞きたいけど周りにはそんな人はいない…あるいは、会社で働いていて日中そんなに時間をとれないなど、オンラインのプログラミングスクールがいいでしょう、時間の制約がないところが一番の魅力です。

以下の3つはAndroidが学習できるオンラインスクールです。


TECH ACADEMY
Androidアプリコース



侍エンジニア塾
侍エンジニア塾 無料体験レッスン



CodeCamp
~約8,000名の受講生と80社以上の導入実績~
現役エンジニアのオンライン家庭教師CodeCamp





正直ネットや本では限界があります。直接(ネットで)誰か分かる人に聞いた方が早く解決して、上達も早いと思います。

尚、スクールがダメだと言う人がいますが、やる気があれば問題ありません。与えられるのを待っていてはいけないですね
欲しいものは取りに行くのです。


Google Pixel 3 XLグローバル版
SIMフリー 並行輸入品
6.3インチの大画面
背景をぼかすポートレートモード撮影


Anker PowerCore II Slim 10000
Power IQ 2.0搭載
iPhone & Android対応

シェアする

  • このエントリーをはてなブックマークに追加

フォローする