Android
Przechowywanie plików w pamięci wewnętrznej i zewnętrznej
Szukaj…
Składnia
- FileOutputStream openFileInput (nazwa ciągu)
- FileOutputStream openFileOutput (nazwa ciągu, tryb int)
- Plik (reż. Pliku, nazwa ciągu)
- Plik (ścieżka ciągu)
- Plik getExternalStoragePublicDirectory (typ ciągu)
- Plik getExternalFilesDir (typ ciągu)
Parametry
Parametr | Detale |
---|---|
Nazwa | Nazwa pliku do otwarcia. UWAGA: Nie może zawierać separatorów ścieżek |
tryb | Tryb pracy. Użyj MODE_PRIVATE do domyślnej operacji i MODE_APPEND aby dołączyć istniejący plik. Inne tryby obejmują MODE_WORLD_READABLE i MODE_WORLD_WRITEABLE , które były przestarzałe w API 17. |
reż | Katalog pliku, w którym ma zostać utworzony nowy plik |
ścieżka | Ścieżka do określenia lokalizacji nowego pliku |
rodzaj | Typ katalogu plików do pobrania. Może mieć null lub dowolne z poniższych: DIRECTORY_MUSIC , DIRECTORY_PODCASTS , DIRECTORY_RINGTONES , DIRECTORY_ALARMS , DIRECTORY_NOTIFICATIONS , DIRECTORY_PICTURES lub DIRECTORY_MOVIES |
Korzystanie z pamięci wewnętrznej
Domyślnie wszystkie pliki zapisywane w pamięci wewnętrznej są prywatne dla aplikacji. Nie są dostępne dla innych aplikacji ani dla użytkownika w normalnych okolicznościach. Pliki te są usuwane, gdy użytkownik odinstaluje aplikację .
Aby zapisać tekst w pliku
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();
}
Aby dołączyć tekst do istniejącego pliku
Użyj Context.MODE_APPEND
dla parametru trybu openFileOutput
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
Korzystanie z pamięci zewnętrznej
„Zewnętrzna” pamięć to inny rodzaj pamięci, której możemy używać do zapisywania plików na urządzeniu użytkownika. Ma kilka kluczowych różnic w stosunku do pamięci wewnętrznej, a mianowicie:
- Nie zawsze jest dostępny. W przypadku nośnika wymiennego (karty SD) użytkownik może po prostu usunąć pamięć.
- To nie jest prywatne. Użytkownik (i inne aplikacje) mają dostęp do tych plików.
- Jeśli użytkownik odinstaluje aplikację, pliki zapisane w katalogu pobranym za pomocą
getExternalFilesDir()
zostaną usunięte.
Aby korzystać z pamięci zewnętrznej, musimy najpierw uzyskać odpowiednie uprawnienia. Musisz użyć:
-
android.permission.WRITE_EXTERNAL_STORAGE
do czytania i pisania -
android.permission.READ_EXTERNAL_STORAGE
do czytania
Aby przyznać te uprawnienia, musisz je zidentyfikować w AndroidManifest.xml
jako takim
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
UWAGA: Ponieważ są to niebezpieczne uprawnienia, jeśli używasz interfejsu API poziomu 23 lub wyższego, musisz poprosić o uprawnienia w czasie wykonywania .
Przed próbą zapisu lub odczytu z pamięci zewnętrznej należy zawsze sprawdzić, czy nośnik pamięci jest dostępny.
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
}
Podczas zapisywania plików w pamięci zewnętrznej należy zdecydować, czy plik powinien zostać rozpoznany jako publiczny czy prywatny. Chociaż oba te typy plików są nadal dostępne dla użytkownika i innych aplikacji na urządzeniu, istnieje między nimi kluczowa różnica.
Pliki publiczne powinny pozostać na urządzeniu, gdy użytkownik odinstaluje aplikację. Przykładem pliku, który powinien zostać zapisany jako publiczny, byłyby zdjęcia zrobione za pośrednictwem aplikacji.
Pliki prywatne powinny zostać usunięte, gdy użytkownik odinstaluje aplikację. Te typy plików będą specyficzne dla aplikacji i nie będą przydatne dla użytkownika ani innych aplikacji. Dawny. pliki tymczasowe pobrane / używane przez twoją aplikację.
Oto jak uzyskać dostęp do katalogu Documents
dla plików publicznych i prywatnych.
Publiczny
// 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();
Prywatny
// 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: pamięć wewnętrzna i zewnętrzna - wyjaśnienie terminologii
Programiści Androida (głównie początkujący) są zdezorientowani, jeśli chodzi o terminologię pamięci wewnętrznej i zewnętrznej. Istnieje wiele pytań dotyczących Stackoverflow dotyczących tego samego. Wynika to głównie z faktu, że terminologia według Google / oficjalnej dokumentacji Androida jest zupełnie inna niż zwykłego użytkownika systemu Android. Dlatego pomyślałem, że udokumentowanie tego pomoże.
Co myślimy - Terminologia użytkownika (UT)
Pamięć wewnętrzna (UT) | Pamięć zewnętrzna (UT) |
---|---|
wbudowana pamięć wewnętrzna telefonu | wymienna karta Secure Digital (SD) lub pamięć micro SD |
Przykład: 32 GB pamięci wewnętrznej Nexusa 6P. | Przykład: przestrzeń dyskowa w wymiennych kartach SD dostarczanych przez dostawców takich jak Samsung, Sandisk, Stront, Transcend i inne |
Ale zgodnie z Dokumentacją / Przewodnikiem Androida - Terminologia Google (GT)
Pamięć wewnętrzna (GT):
Domyślnie pliki zapisane w pamięci wewnętrznej są prywatne dla Twojej aplikacji, a inne aplikacje nie mogą uzyskać do nich dostępu (podobnie jak użytkownik).
Pamięć zewnętrzna (GT):
Może to być wymienny nośnik pamięci (taki jak karta SD) lub pamięć wewnętrzna (niewymienna).
Pamięć zewnętrzna (GT) można podzielić na dwa typy:
Podstawowa pamięć zewnętrzna | Dodatkowa pamięć zewnętrzna lub pamięć wymienna (GT) |
---|---|
Jest to to samo, co wbudowana pamięć wewnętrzna telefonu (lub) Pamięć wewnętrzna (UT) | Jest to to samo, co wymienne miejsce na kartę micro SD (lub) Pamięć zewnętrzna (UT) |
Przykład: 32 GB pamięci wewnętrznej Nexusa 6P. | Przykład: przestrzeń dyskowa w wymiennych kartach SD dostarczanych przez dostawców takich jak Samsung, Sandisk, Stront, Transcend i inne |
Do tego typu pamięci można uzyskać dostęp na komputerze z systemem Windows, podłączając telefon do komputera kablem USB i wybierając opcję Aparat (PTP) w powiadomieniu o opcjach USB. | Do tego rodzaju pamięci można uzyskać dostęp na komputerze z systemem Windows, podłączając telefon do komputera kablem USB i wybierając opcję Przesyłanie plików w powiadomieniu o opcjach USB. |
W skrócie,
Pamięć zewnętrzna (GT) = Pamięć wewnętrzna (UT) i Pamięć zewnętrzna (UT)
Pamięć wymienna (GT) = Pamięć zewnętrzna (UT)
Pamięć wewnętrzna (GT) nie ma terminu w UT.
Pozwól mi wyjaśnić jasno,
Pamięć wewnętrzna (GT): Domyślnie pliki zapisane w pamięci wewnętrznej są prywatne dla Twojej aplikacji i inne aplikacje nie mają do nich dostępu. Użytkownik aplikacji nie może również uzyskać do nich dostępu za pomocą menedżera plików; nawet po włączeniu opcji „pokaż ukryte pliki” w menedżerze plików. Aby uzyskać dostęp do plików w pamięci wewnętrznej (GT), musisz zrootować swój telefon z Androidem. Ponadto, gdy użytkownik odinstaluje aplikację, pliki te zostaną usunięte / usunięte.
Tak więc pamięć wewnętrzna (GT) NIE jest tym, co uważamy za wewnętrzną pamięć Nexusa 6P o wielkości 32/64 GB
Ogólnie rzecz biorąc, lokalizacja pamięci wewnętrznej (GT) to: /data/data/your.application.package.appname/someDirectory/
Pamięć zewnętrzna (GT):
Każde urządzenie kompatybilne z Androidem obsługuje wspólną „pamięć zewnętrzną”, której można używać do zapisywania plików. Pliki zapisane w pamięci zewnętrznej są czytelne na całym świecie i mogą być modyfikowane przez użytkownika, jeśli umożliwiają przesyłanie plików na komputer przez pamięć masową USB.
Lokalizacja pamięci zewnętrznej (GT): może znajdować się w dowolnym miejscu w pamięci wewnętrznej (UT) lub w pamięci wymiennej (GT), tj. Na karcie micro SD. To zależy od producenta telefonu, a także od wersji systemu operacyjnego Android.
Aby odczytać lub zapisać pliki w pamięci zewnętrznej (GT), aplikacja musi uzyskać uprawnienia systemowe READ_EXTERNAL_STORAGE
lub WRITE_EXTERNAL_STORAGE
.
Na przykład:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Jeśli potrzebujesz zarówno odczytywać, jak i zapisywać pliki, musisz poprosić tylko o uprawnienie
WRITE_EXTERNAL_STORAGE
, ponieważ domyślnie wymaga ono również dostępu do odczytu.
W pamięci zewnętrznej (GT) możesz także zapisywać pliki, które są prywatne z aplikacjami
Ale,
Gdy użytkownik odinstaluje aplikację, ten katalog i cała jego zawartość zostaną usunięte.
Kiedy trzeba zapisywać pliki prywatne dla aplikacji w pamięci zewnętrznej (GT) ?
Jeśli masz do czynienia z plikami, które nie są przeznaczone do użytku przez inne aplikacje (takie jak tekstury graficzne lub efekty dźwiękowe używane tylko przez Twoją aplikację), powinieneś użyć prywatnego katalogu pamięci w pamięci zewnętrznej
Począwszy od Androida 4.4, czytanie lub zapisywanie plików w prywatnych katalogach aplikacji nie wymaga uprawnień
READ_EXTERNAL_STORAGE
lubWRITE_EXTERNAL_STORAGE
. Aby można było zadeklarować, że uprawnienia należymaxSdkVersion
tylko w niższych wersjach Androida, dodając atrybutmaxSdkVersion
:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
Metody przechowywania w pamięci wewnętrznej (GT):
Obie te metody są obecne w klasie Context
File getDir (String name, int mode)
File getFilesDir ()
Metody przechowywania w podstawowej pamięci zewnętrznej, tj. Pamięci wewnętrznej (UT):
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
Na początku wszyscy korzystali z Environment.getExternalStorageDirectory () , co wskazywało na podstawową podstawową pamięć zewnętrzną . W rezultacie podstawowa pamięć zewnętrzna została wypełniona losową zawartością.
Później dodano te dwie metody:
W klasie
Context
dodali getExternalFilesDir () , wskazując katalog specyficzny dla aplikacji w podstawowej pamięci zewnętrznej. Ten katalog i jego zawartość zostaną usunięte po odinstalowaniu aplikacji.Environment.getExternalStoragePublicDirectory () dla scentralizowanych miejsc do przechowywania dobrze znanych typów plików, takich jak zdjęcia i filmy. Ten katalog i jego zawartość NIE zostaną usunięte po odinstalowaniu aplikacji.
Metody przechowywania w pamięci wymiennej (GT), tj. Na karcie micro SD
Przed 19 poziomem API nie było oficjalnego sposobu przechowywania na karcie SD. Ale wielu mogłoby to zrobić przy użyciu nieoficjalnych bibliotek lub interfejsów API.
Oficjalnie jedna metoda została wprowadzona w klasie Context
na poziomie API 19 (Android wersja 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
Zwraca bezwzględne ścieżki do katalogów specyficznych dla aplikacji na wszystkich współużytkowanych / zewnętrznych urządzeniach pamięci, w których aplikacja może umieszczać trwałe pliki, które posiada. Te pliki są wewnętrzne dla aplikacji i zwykle nie są widoczne dla użytkownika jako nośnik.
Oznacza to, że zwróci ścieżki do obu typów pamięci zewnętrznej (GT) - pamięci wewnętrznej i karty Micro SD. Zasadniczo drugą ścieżką byłaby ścieżka przechowywania karty micro SD (ale nie zawsze). Musisz to sprawdzić, wykonując kod za pomocą tej metody.
Przykład z fragmentem kodu:
Stworzyłem nowy projekt Androida z pustą aktywnością, napisałem w środku następujący kod
protected void onCreate(Bundle savedInstanceState)
metoda 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);
Po wykonaniu powyższego kodu
Wynik:
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
Uwaga: podłączyłem telefon do komputera z systemem Windows; włączono obie opcje programisty, debugowanie USB, a następnie uruchomiono ten kod. Jeśli nie podłączysz telefonu ; ale zamiast tego uruchom to na emulatorze Androida , Twoje wyniki mogą się różnić. Mój model telefonu to Coolpad Note 3 - działający na Androidzie 5.1
Miejsca przechowywania w moim telefonie:
Miejsce przechowywania Micro SD : /storage/sdcard1
Lokalizacja pamięci wewnętrznej (UT) : /storage/sdcard0
.
Zauważ, że /sdcard
& /storage/emulated/0
również wskazują na pamięć wewnętrzną (UT). Ale są to dowiązania symboliczne do /storage/sdcard0
.
Aby jasno zrozumieć różne ścieżki przechowywania w Androidzie, proszę przejść przez tę odpowiedź
Oświadczenie: Wszystkie wyżej wymienione ścieżki przechowywania są ścieżkami w moim telefonie. Twoje pliki mogą nie być przechowywane w tych samych ścieżkach pamięci. Ponieważ lokalizacje / ścieżki przechowywania mogą się różnić w przypadku innych telefonów komórkowych w zależności od dostawcy, producenta i różnych wersji systemu operacyjnego Android.
Zapisz bazę danych na karcie SD (Backup DB na SD)
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;
}
}
nazwij tę metodę w ten sposób:
ExportDB („myDB.db”, „com.example.exam”, „/ myFolder”);
Pobierz katalog urządzeń:
Najpierw dodaj uprawnienia do przechowywania do odczytu / pobierania katalogu urządzenia.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Utwórz klasę modelu
//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;
}
}
Utwórz listę za pomocą modelu katalogu, aby dodać dane katalogu.
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
Pobierz katalog, używając następującej metody.
//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();
}
}
Wydrukuj listę katalogów w dzienniku.
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
Stosowanie
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
Aby pobrać wewnętrzne pliki / folder określonego katalogu, użyj tej samej metody, po prostu zmień argument, przekaż wybraną ścieżkę w argumencie i obsłuż odpowiedź.
Aby uzyskać rozszerzenie pliku:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}