Android
内部および外部ストレージへのファイルの保存
サーチ…
構文
- FileOutputStream openFileInput(文字列名)
- FileOutputStream openFileOutput(文字列名、intモード)
- ファイル(ファイルディレクトリ、文字列名)
- ファイル(文字列パス)
- ファイルgetExternalStoragePublicDirectory(String型)
- ファイルgetExternalFilesDir(String型)
パラメーター
パラメータ | 詳細 |
---|---|
名 | 開くファイルの名前。注:パス区切り文字は使用できません。 |
モード | 動作モード。使用MODE_PRIVATE デフォルトの動作のために、そしてMODE_APPEND 既存のファイルを追加します。その他のモードには、 MODE_WORLD_READABLE とMODE_WORLD_WRITEABLE がありますが、どちらもAPI 17では非推奨です。 |
指 | 新しいファイルを作成するためのファイルのディレクトリ |
パス | 新しいファイルの場所を指定するパス |
タイプ | 取得するファイルの種類。 null 、またはDIRECTORY_MUSIC 、 DIRECTORY_PODCASTS 、 DIRECTORY_RINGTONES 、 DIRECTORY_ALARMS 、 DIRECTORY_NOTIFICATIONS 、 DIRECTORY_PICTURES 、またはDIRECTORY_MOVIES いずれかになります。 |
内部ストレージの使用
デフォルトでは、内部ストレージに保存するファイルはアプリケーション専用です。通常の状況下では、他のアプリケーションやユーザーはアクセスできません。 これらのファイルは、ユーザーがアプリケーションをアンインストールすると削除されます 。
ファイルにテキストを書き込むには
String fileName= "helloworld";
String textToWrite = "Hello, World!";
FileOutputStream fileOutputStream;
try {
fileOutputStream = openFileOutput(fileName, Context.MODE_PRIVATE);
fileOutputStream.write(textToWrite.getBytes());
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
既存のファイルにテキストを追加するには
openFileOutput
modeパラメータにContext.MODE_APPEND
を使用する
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
外部ストレージの使用
「外部」ストレージは、ファイルをユーザーのデバイスに保存するために使用できる別のタイプのストレージです。 「内部」ストレージとの主な違いは次のとおりです。
- 常に利用可能なわけではありません。リムーバブルメディア(SDカード)の場合、ユーザーは単にストレージを取り外すことができます。
- 私的ではありません。ユーザー(および他のアプリケーション)はこれらのファイルにアクセスできます。
- ユーザーがアプリケーションをアンインストールすると、
getExternalFilesDir()
取得したディレクトリに保存したファイルは削除されます。
外部ストレージを使用するには、まず適切な権限を取得する必要があります。次のものを使用する必要があります:
これらの権限を付与するには、 AndroidManifest.xml
その権限を識別する必要があります
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
注: APIレベル23以上を使用している場合は危険なアクセス 権であるため、実行時にアクセス権を要求する必要があります 。
外部ストレージへの書き込みまたは読み取りを試みる前に、必ずストレージメディアが使用可能であることを確認する必要があります。
String state = Environment.getExternalStorageState();
if (state.equals(Environment.MEDIA_MOUNTED)) {
// Available to read and write
}
if (state.equals(Environment.MEDIA_MOUNTED) ||
state.equals(Environment.MEDIA_MOUNTED_READ_ONLY)) {
// Available to at least read
}
外部ストレージにファイルを書き込むときは、ファイルをパブリックまたはプライベートとして認識するかどうかを決定する必要があります。これらの種類のファイルは、デバイス上のユーザーや他のアプリケーションから引き続きアクセスできますが、それらの間には大きな違いがあります。
ユーザーがアプリをアンインストールすると、公開されたファイルは端末に残ります。パブリックとして保存する必要があるファイルの例は、アプリケーションを通じて取得される写真です。
ユーザーがアプリをアンインストールすると、プライベートファイルはすべて削除されます。これらのタイプのファイルはアプリ固有のものであり、ユーザーや他のアプリケーションには使用できません。 Ex。アプリケーションによってダウンロード/使用される一時ファイル。
パブリックファイルとプライベートファイルの両方についてDocuments
ディレクトリにアクセスする方法は次のとおりです。
パブリック
// Access your app's directory in the device's Public documents directory
File docs = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_DOCUMENTS), "YourAppDirectory");
// Make the directory if it does not yet exist
myDocs.mkdirs();
プライベート
// Access your app's Private documents directory
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOCUMENTS),
"YourAppDirectory");
// Make the directory if it does not yet exist
myDocs.mkdirs();
Android:内部および外部ストレージ - 用語の明確化
Android開発者(主に初心者)は、内部および外部のストレージ用語について混乱しています。同じことについてはStackoverflowに関する多くの質問があります。これは主に、Google /公式Androidのドキュメントに基づく用語が、通常のAndroid OSユーザーの用語とはかなり異なるという事実に起因しています。したがって、私はこれを文書化すると助けになると思いました。
私たちが考えること - ユーザーの用語(UT)
内部ストレージ(UT) | 外部ストレージ(UT) |
---|---|
携帯電話の内蔵メモリ | 取り外し可能なセキュアデジタル(SD)カードまたはマイクロSD記憶装置 |
例: Nexus 6Pの32 GB内蔵メモリ | 例: samsung、sandisk、ストロンチウム、超越などのベンダーが提供するリムーバブルSDカードのストレージスペース |
しかし、 Androidのドキュメント/ガイド - Googleの用語(GT)によると 、
内部ストレージ(GT):
デフォルトでは、内部ストレージに保存されているファイルはアプリケーションのプライベートなもので、他のアプリケーションはアクセスできません(またユーザーはアクセスできません)。
外部ストレージ(GT):
これは、リムーバブル記憶媒体(SDカードなど)または内部(非リムーバブル)記憶装置にすることができます。
外部ストレージ(GT)は、2つのタイプに分類することができます。
主要外部ストレージ | 二次外部ストレージまたはリムーバブルストレージ(GT) |
---|---|
これは、電話機内蔵の内部メモリ(または)内部ストレージ(UT)と同じです。 | リムーバブルマイクロSDカードストレージ(または)外部ストレージ(UT)と同じです。 |
例: Nexus 6Pの32 GB内蔵メモリ | 例: samsung、sandisk、ストロンチウム、超越などのベンダーが提供するリムーバブルSDカードのストレージスペース |
このタイプのストレージは、USBケーブルを使用して電話をPCに接続し、USBオプションの通知でカメラ(PTP)を選択することで、Windows PC上でアクセスできます。 | このタイプのストレージは、USBケーブルを使用して携帯電話をPCに接続し、USBオプションの通知でファイル転送を選択することによって、Windows PC上でアクセスできます。 |
手短に、
外部ストレージ(GT)=内部ストレージ(UT)および外部ストレージ(UT)
リムーバブルストレージ(GT)=外部ストレージ(UT)
内部ストレージ(GT)にはUTの用語はありません。
私にはっきりと説明しましょう、
内部ストレージ(GT):デフォルトでは、内部ストレージに保存されたファイルはアプリケーションのプライベートなものであり、他のアプリケーションはそのファイルにアクセスできません。あなたのアプリケーションユーザーはファイルマネージャを使ってそれらにアクセスすることもできません。ファイルマネージャで「隠しファイルを表示」オプションを有効にした後でも。内部ストレージ(GT)のファイルにアクセスするには、Android端末をルートする必要があります。さらに、ユーザーがアプリケーションをアンインストールすると、これらのファイルは削除/削除されます。
したがって、内部ストレージ(GT)はNexus 6Pの32/64 GB内蔵メモリとは思えません
一般に、 内部ストレージ(GT)の場所は次のようになります: /data/data/your.application.package.appname/someDirectory/
外部ストレージ(GT):
すべてのAndroid対応デバイスは、ファイルを保存するために使用できる共有の「外部ストレージ」をサポートしています。外部ストレージに保存されたファイルは世界中で読み取り可能で、USB大容量ストレージがコンピュータ上のファイルを転送できるようにすると、ユーザーが変更することができます。
外部ストレージ(GT)の場所:内部ストレージ(UT)またはリムーバブルストレージ(GT)のどこにでも置くことができます(micro SDカード)。これは、お使いの携帯電話のOEMとAndroid OSのバージョンによって異なります。
外部ストレージ(GT)上のファイルを読み書きするには、アプリがREAD_EXTERNAL_STORAGE
またはWRITE_EXTERNAL_STORAGE
システム権限を取得する必要があります。
例えば:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
ファイルの読み取りと書き込みの両方を行う必要がある場合は、暗黙的に読み取りアクセス権も必要とするため、
WRITE_EXTERNAL_STORAGE
権限のみを要求する必要があります。
外部ストレージ(GT)では、 アプリプライベートなファイルを保存することもできます
しかし、
ユーザーがアプリケーションをアンインストールすると、このディレクトリとそのすべての内容が削除されます。
外部ストレージ(GT)に アプリ専用のファイルをいつ保存する必要がありますか?
他のアプリケーションが使用するためのものではないファイル(グラフィックテクスチャやアプリケーションのみで使用されるサウンドエフェクトなど)を扱う場合は、外部ストレージ上のプライベートストレージディレクトリを使用する必要があります
Android 4.4以降、アプリのプライベートディレクトリにあるファイルの読み取りや書き込みには、
READ_EXTERNAL_STORAGE
またはWRITE_EXTERNAL_STORAGE
権限は必要ありません。したがって、maxSdkVersion
属性を追加することで、Androidの下位バージョンでのみアクセス許可を要求する必要があることを宣言できます。
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
内部ストレージ(GT)に格納する方法:
これらのメソッドはどちらもContextクラスに存在します
File getDir (String name, int mode)
File getFilesDir ()
プライマリ外部ストレージ、つまり内部ストレージ(UT)に格納する方法:
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
最初は、誰もがPrimary External Storageの ルートを指し示すEnvironment.getExternalStorageDirectory()を使用しました。その結果、プライマリ外部ストレージはランダムなコンテンツで満たされました。
その後、これらの2つのメソッドが追加されました。
Context
クラスでは、 getExternalFilesDir()を追加し、プライマリ外部ストレージのアプリケーション固有のディレクトリを指していました。このディレクトリとその内容は 、アプリケーションのアンインストール時に削除されます。Environment.getExternalStoragePublicDirectory()は、写真やムービーのようなよく知られたファイルタイプを格納する場所を集中管理します。このディレクトリとその内容は 、アプリケーションのアンインストール時に削除されません 。
リムーバブルストレージ(GT)、すなわちマイクロSDカードに格納する方法
APIレベル19以前は、SDカードに保存する正式な方法はありませんでした 。しかし、多くの人が非公式の図書館やAPIを使ってそれを行うことができます。
正式には、APIレベル19(Androidバージョン4.4 - Kitkat)のContext
クラスに1つのメソッドが導入されました。
File[] getExternalFilesDirs (String type)
これは、アプリケーションが所有する永続ファイルを置くことができるすべての共有/外部ストレージ・デバイス上のアプリケーション固有ディレクトリーへの絶対パスを戻します。これらのファイルはアプリケーションの内部にあり、通常はメディアとしてユーザーに表示されません。
つまり、内部メモリとマイクロSDカードの両方のタイプの外部ストレージ(GT)へのパスが返されます。一般的に、 第2の経路は、マイクロSDカードの記憶経路である(常にではない)。だから、このメソッドでコードを実行してチェックアウトする必要があります。
コードスニペットの例:
空のアクティビティを持つ新しいアンドロイドプロジェクトを作成し、内部に次のコードを書きました
protected void onCreate(Bundle savedInstanceState)
の方法MainActivity.java
File internal_m1 = getDir("custom", 0);
File internal_m2 = getFilesDir();
File external_m1 = Environment.getExternalStorageDirectory();
File external_m2 = getExternalFilesDir(null);
File external_m2_Args = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File external_m3 = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
File[] external_AND_removable_storage_m1 = getExternalFilesDirs(null);
File[] external_AND_removable_storage_m1_Args = getExternalFilesDirs(Environment.DIRECTORY_PICTURES);
上記のコードを実行した後、
出力:
internal_m1: /data/data/your.application.package.appname/app_custom
internal_m2: /data/data/your.application.package.appname/files
external_m1: /storage/emulated/0
external_m2: /storage/emulated/0/Android/data/your.application.package.appname/files
external_m2_Args: /storage/emulated/0/Android/data/your.application.package.appname/files/Pictures
external_m3: /storage/emulated/0/Pictures
external_AND_removable_storage_m1 (first path):
/storage/emulated/0/Android/data/your.application.package.appname/files
external_AND_removable_storage_m1 (second path):
/storage/sdcard1/Android/data/your.application.package.appname/files
external_AND_removable_storage_m1_Args (first path):
/storage/emulated/0/Android/data/your.application.package.appname/files/Pictures
external_AND_removable_storage_m1_Args (second path): /storage/sdcard1/Android/data/your.application.package.appname/files/Pictures
注:私は自分の電話をWindows PCに接続しました。開発者向けオプション、USBデバッグの両方を有効にしてから、このコードを実行しました。 あなたの携帯電話を接続していない場合。 Androidのエミュレータでこれを実行すると、出力が異なる場合があります。私の携帯電話モデルはCoolpad Note 3 - Android 5.1で動作しています
私の電話の保管場所:
マイクロSDストレージの場所 : /storage/sdcard1
内部ストレージ(UT)の場所 : /storage/sdcard0
/sdcard
& /storage/emulated/0
も内部ストレージ(UT)を指していることに注意してください。しかし、これらは/storage/sdcard0
へのシンボリックリンク/storage/sdcard0
。
Androidのさまざまなストレージパスをはっきりと理解するには、 この回答をご覧ください
免責事項:上記のすべてのストレージパスは、 私の電話のパスです。ファイルは、同じストレージパスに保存されないことがあります。ベンダー、メーカー、Android OSのバージョンによっては、保存場所/パスが他の携帯電話で異なる場合があります。
SDカードにデータベースを保存する(SDのバックアップDB)
public static Boolean ExportDB(String DATABASE_NAME , String packageName , String folderName){
//DATABASE_NAME including ".db" at the end like "mayApp.db"
String DBName = DATABASE_NAME.substring(0, DATABASE_NAME.length() - 3);
File data = Environment.getDataDirectory();
FileChannel source=null;
FileChannel destination=null;
String currentDBPath = "/data/"+ packageName +"/databases/"+DATABASE_NAME; // getting app db path
File sd = Environment.getExternalStorageDirectory(); // getting phone SD card path
String backupPath = sd.getAbsolutePath() + folderName; // if you want to set backup in specific folder name
/* be careful , foldername must initial like this : "/myFolder" . dont forget "/" at begin of folder name
you could define foldername like this : "/myOutterFolder/MyInnerFolder" and so on ...
*/
File dir = new File(backupPath);
if(!dir.exists()) // if there was no folder at this path , it create it .
{
dir.mkdirs();
}
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd_HH-mm-ss");
Date date = new Date();
/* use date including file name for arrange them and preventing to make file with the same*/
File currentDB = new File(data, currentDBPath);
File backupDB = new File(backupPath, DBName +"("+ dateFormat.format(date)+").db");
try {
if (currentDB.exists() && !backupDB.exists()) {
source = new FileInputStream(currentDB).getChannel();
destination = new FileOutputStream(backupDB).getChannel();
destination.transferFrom(source, 0, source.size());
source.close();
destination.close();
return true;
}
return false;
} catch(IOException e) {
e.printStackTrace();
return false;
}
}
このメソッドを以下のように呼び出します。
ExportDB( "myDB.db"、 "com.example.exam"、 "/ myFolder");
デバイスディレクトリを取得:
最初にデバイスディレクトリを読み込み/取得するためのストレージ権限を追加します。
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
モデルクラスを作成する
//create one directory model class
//to store directory title and type in list
public class DirectoryModel {
String dirName;
int dirType; // set 1 or 0, where 0 for directory and 1 for file.
public int getDirType() {
return dirType;
}
public void setDirType(int dirType) {
this.dirType = dirType;
}
public String getDirName() {
return dirName;
}
public void setDirName(String dirName) {
this.dirName = dirName;
}
}
ディレクトリモデルを使用してリストを作成し、ディレクトリデータを追加します。
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
次の方法でディレクトリを取得します。
//to fetch device directory
private void getDirectory(String currDir) { // pass device root directory
File f = new File(currDir);
File[] files = f.listFiles();
if (files != null) {
if (files.length > 0) {
rootDir.clear();
for (File inFile : files) {
if (inFile.isDirectory()) { //return true if it's directory
// is directory
DirectoryModel dir = new DirectoryModel();
dir.setDirName(inFile.toString().replace("/storage/emulated/0", ""));
dir.setDirType(0); // set 0 for directory
rootDir.add(dir);
} else if (inFile.isFile()) { // return true if it's file
//is file
DirectoryModel dir = new DirectoryModel();
dir.setDirName(inFile.toString().replace("/storage/emulated/0", ""));
dir.setDirType(1); // set 1 for file
rootDir.add(dir);
}
}
}
printDirectoryList();
}
}
ディレクトリリストをログに出力します。
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
使用法
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
特定のディレクトリの内部ファイル/フォルダをフェッチするには、引数を変更するだけで同じ方法を使用し、現在選択されているパスを引数に渡し、同じ応答を処理します。
ファイル拡張子を取得するには:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}