◆PROCESSING 逆引きリファレンス
カテゴリー:スマホ(AndroidMode)
様々なパスの取得(AndroidMode編)
【解説】
PROCESSINGにAndroidMode を導入する事で、PROCESSINGで開発したプログラムをAndroid端末上で動かす事ができるようになります。
AndroidModeの導入については「PROCESSINGをAndroid端末で動かすには(4.0版)」記事を参照してください。
Android端末は独特なストレージ領域の考え方を持っています。いろいろな領域を用途に応じて使い分ける仕組みとなっているのです。
Android端末の様々なパスについては下記ページなどが参考となります。
- Unmotivated 様
- Qiita :h_yama37 様:Android:SDカード(外部ストレージ)のパスを取得する方法(機種依存対策)
- TECHBOOSTER:Mhidaka 様:マルチユーザ対応 ANDROID 4.2以降の内部ストレージと外部ストレージ (4.4対応を追記)
非常にざっくりと書くと、Android端末のストレージ領域は3つのエリアから構成されています(実際には、これにキャッシュ領域が加わります)。
内部領域はアプリケーション専用の領域で、他のアプリケーションや、その端末の利用者からは見えない領域です。
外部領域はアプリケーション用の領域ですが、(権限を持つ)他のアプリケーションや、その端末の利用者からもアクセスできる領域です。
内部領域と外部領域は、アプリケーションのアンインストール時にデータが消去されます。
機種によっては、アプリケーションをアンインストールしてもデータが保持される「公開領域」をサポートしているものがあります。
公開領域は、(権限を持つ)全てのアプリケーションと利用者からアクセスが可能な領域となります。
PROCESSINGには、skechPath() など独自のパスを得る命令が幾つかあります。これらの命令は、getFilesDir()で得られる内部領域配下のパスを返します。
ストレージの各領域へアクセスする方法については、以下の記事も参考としてください。
【構文】
●内部領域へのパスを得る
String path = sketchPath( String where ) ;
●内部領域へのパスを得る
String path = savePath( String where ) ;
●内部領域へのパスを得る
String path = dataPath( String where ) ;
path : 取得したパス
where : 指定フォルダ配下のパス
●内部領域へのパスを得る(Android API)
File fl = Context . getFilesDir() ;
●外部領域へのパスを得る(Android API)
File fl = Context . getExternalFilesDir ( String where ) ;
●公開領域へのパスを得る(Android API)
File fl = Environment.getExternalStorageDirectory() ;
File fl = Environment.getExternalStoragePublicDirectory( String where ) ;
fl :Fileオブジェクト
where:指定フォルダ配下のパス
AndroidのAPIについては、下記Android Developers の公式リファレンスを参照して下さい。
【注意】
JavaModeでは引数なしのsketchPath() 命令がサポートされていましたが、AndroidModeでは引数が必須となっています。
JavaModeでは savePath() 命令に引数を与えると、スケッチフォルダ配下に引数で与えた名前のフォルダを自動生成してくれましたが、AndroidModeではフォルダ生成は行われません。
例:savePath( “where” ) ; とした場合
JavaMode :C:¥processing-3.3¥src¥sketch_170821a¥where フォルダが自動生成
AndroidMode:/data/data/pkgname/files/where というパスのみ返す
つまりAndroidModeでは、sketchPath()、savePath() の違いは無いと考えても良さそうです。
またAndroidModeでは、Windowsに特化したデスクトップのパスを返す desktopPath() 命令はサポートされていません。
sketchPath()、savePath()、dataPath()の各命令は全て、Context.getFilesDir() で得られる内部領域へのパスを戻します。外部領域、および公開領域のパスは、PROCESSINGの命令では取得できません。
これらの領域のパスを得るには、AndroidのAPIを利用する必要があります。
Android4.4以降、アプリケーションが内部領域や外部領域へアクセスする場合、特別なパーミッションは不要となりました。
ただし公開領域へアクセスするためには、WRITE_EXTERNAL_STORAGEやREAD_EXTERNAL_STORAGEパーミッションが必要となります。
また(当然ですが)他のアプリケーションから外部領域や公開領域へアクセスする場合は、しかるべきパーミッションが必要となります。
外部領域と公開領域はSDカードなどの外部ストレージ上に確保される事がありますが、必ずではありません。内部ストレージにこれらの領域を持つ端末もあるそうです。
外部領域や公開領域がSDカードか否かを調べるには、Environment.isExternalStorageRemovable() 命令を使って、該当フォルダが取外し可能なフォルダ(マウントポイント)かどうかを調べる工夫が必要となります。※
※Environment.isExternalStorageRemovable() 命令はAndroid5.0以降でサポートされた命令です。4.4以前の場合は、上記にあげた Qiita 様の記事等を参考にしてください。
【関連記事】
- PROCESSINGをAndroid端末で動かすには(4.0版)
- スケッチ関連のパスを取得するには
- ストレージのファイルをアクセスするには(AndroidMode編)
- 公開領域にアクセスするには(AndroidMode編)
サンプルプログラム
各パスを表示する例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
void setup(){ fullScreen(); //Activityを取得する Activity act = getActivity(); //ActivityはContextを継承しているので、キャスト Context con = (Context)act; println( "getFilesDir() : " + con.getFilesDir() ); println( "getExternalFilesDir() : " + con.getExternalFilesDir("") ); println( "getExternalStorageDirectory() : " + Environment.getExternalStorageDirectory() ); println( "getExternalStoragePublicDirectory() : " + Environment.getExternalStoragePublicDirectory("") ); println( "------------------------" ); println( "sketchPath() : " + sketchPath("") ); println( "savePath() : " + savePath("") ); println( "dataPath() : " + dataPath("") ); } void draw(){ background(128); } |
内部領域、外部領域、公開領域のパスを取得して表示しています。
processing.test.sketch_170821a はパッケージ名なので、スケッチ毎に異なります。
下記は ZTE Blade V580 Android 5.11 で試した結果です。各パスの具体的な位置は、機種やOSバージョンにより異なる可能性がありますので注意してください。
<出力サンプル>
getFilesDir() : /data/data/processing.test.sketch_170821a/files
getExternalFilesDir() : /storage/sdcard0/Android/data/processing.test.sketch_170821a/files
getExternalStorageDirectory() : /storage/sdcard0
getExternalStoragePublicDirectory() : /storage/sdcard0
————————
sketchPath() : /data/data/processing.test.sketch_170821a/files
savePath() : /data/data/processing.test.sketch_170821a/files
dataPath() : /data/data/processing.test.sketch_170821a/files/data/
SDカードか判定する例(Android5.0以上):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
import android.app.Activity; import android.content.Context; import android.os.Environment; void setup(){ fullScreen(); //Activityを取得する Activity act = getActivity(); //ActivityはContextを継承しているので、キャスト Context con = (Context)act; checkSdCard( con.getFilesDir().toString() ); checkSdCard( con.getExternalFilesDir("").toString() ); checkSdCard( Environment.getExternalStorageDirectory().toString() ); checkSdCard( Environment.getExternalStoragePublicDirectory("").toString() ); } void draw(){ background(128); } public boolean checkSdCard(String path) { boolean sdcard = false; if ( path != null) { File fl = new File( path ); // isExternalStorageRemovableはAndroid5.0から利用できるAPI。 // 取り外し可能かどうか(SDカードかどうか)を判定している。 if (Environment.isExternalStorageRemovable(fl)) { // 取り外し可能であればSDカード。 sdcard = true; println( "[" + path + "] is SD CARD" ); } else { //取り外しできないのでSDカードではない println( "[" + path + "] is Not SD CARD" ); } } return( sdcard ); } |
Qiita 様の記事を参考に、SDカードか判定する処理を行ってみました。
ZTE Blade V580 Android 5.11 では、外部領域と公開領域はSDカードであると判定されました。
<出力サンプル>
[/data/data/processing.test.sketch_170821b/files] is Not SD CARD
[/storage/sdcard0/Android/data/processing.test.sketch_170821b/files] is SD CARD
[/storage/sdcard0] is SD CARD
[/storage/sdcard0] is SD CARD
本ページで利用しているアイコン画像は、下記サイト様より拝借しております。各画像の著作権は、それぞれのサイト様および作者にあります。