Android
Memorizzazione di file in Archiviazione interna ed esterna
Ricerca…
Sintassi
- FileOutputStream openFileInput (nome stringa)
- FileOutputStream openFileOutput (Nome stringa, modalità int)
- File (dir file, nome stringa)
- File (percorso stringa)
- File getExternalStoragePublicDirectory (String type)
- File getExternalFilesDir (Tipo di stringa)
Parametri
Parametro | Dettagli |
---|---|
nome | Il nome del file da aprire. NOTA: non può contenere separatori di percorso |
modalità | Modalità operativa. Utilizzare MODE_PRIVATE per l'operazione predefinita e MODE_APPEND per aggiungere un file esistente. Altre modalità includono MODE_WORLD_READABLE e MODE_WORLD_WRITEABLE , entrambe deprecate in API 17. |
dir | Directory del file per creare un nuovo file in |
sentiero | Percorso per specificare la posizione del nuovo file |
genere | Tipo di directory dei file da recuperare. Può essere null o uno dei seguenti elementi: DIRECTORY_MUSIC , DIRECTORY_PODCASTS , DIRECTORY_RINGTONES , DIRECTORY_ALARMS , DIRECTORY_NOTIFICATIONS , DIRECTORY_PICTURES o DIRECTORY_MOVIES |
Utilizzo dell'archiviazione interna
Per impostazione predefinita, qualsiasi file salvato in Archiviazione interna è privato per la tua applicazione. Non è possibile accedervi da altre applicazioni, né dall'utente in circostanze normali. Questi file vengono cancellati quando l'utente disinstalla l'applicazione .
Scrivere un testo in un file
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();
}
Per aggiungere testo a un file esistente
Utilizzare Context.MODE_APPEND
per il parametro mode di openFileOutput
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
Uso dell'archiviazione esterna
L'archiviazione "esterna" è un altro tipo di archiviazione che è possibile utilizzare per salvare i file sul dispositivo dell'utente. Ha alcune differenze chiave rispetto allo storage "interno", vale a dire:
- Non è sempre disponibile. Nel caso di un supporto rimovibile (scheda SD), l'utente può semplicemente rimuovere la memoria.
- Non è privato. L'utente (e altre applicazioni) hanno accesso a questi file.
- Se l'utente disinstalla l'app, i file salvati nella directory recuperata con
getExternalFilesDir()
verranno rimossi.
Per utilizzare Storage esterno, dobbiamo prima ottenere le autorizzazioni appropriate. Dovrai usare:
-
android.permission.WRITE_EXTERNAL_STORAGE
per la lettura e la scrittura -
android.permission.READ_EXTERNAL_STORAGE
per la sola lettura
Per concedere queste autorizzazioni, dovrai identificarle nel tuo AndroidManifest.xml
come tale
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
NOTA: poiché si tratta di autorizzazioni pericolose se si utilizza API di livello 23 o superiore, sarà necessario richiedere le autorizzazioni in fase di runtime .
Prima di tentare di scrivere o leggere da Storage esterno, è necessario verificare sempre che il supporto di memorizzazione sia disponibile.
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
}
Quando si scrivono file nell'archivio esterno, è necessario decidere se il file deve essere riconosciuto come pubblico o privato. Sebbene entrambi questi tipi di file siano ancora accessibili all'utente e ad altre applicazioni sul dispositivo, esiste una distinzione fondamentale tra di essi.
I file pubblici devono rimanere sul dispositivo quando l'utente disinstalla l'app. Un esempio di un file che dovrebbe essere salvato come pubblico sarebbero le foto che sono state prese attraverso la tua applicazione.
I file privati devono essere rimossi tutti quando l'utente disinstalla l'app. Questi tipi di file potrebbero essere specifici per le app e non essere utili all'utente o ad altre applicazioni. Ex. file temporanei scaricati / utilizzati dalla tua applicazione.
Ecco come accedere alla directory Documents
per file pubblici e privati.
Pubblico
// 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();
Privato
// 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: archiviazione interna ed esterna - Chiarimento terminologico
Gli sviluppatori Android (principalmente principianti) sono stati confusi riguardo la terminologia di archiviazione interna ed esterna. Ci sono molte domande su Stackoverflow riguardanti lo stesso. Ciò è dovuto principalmente al fatto che la terminologia secondo la documentazione Google / ufficiale di Android è molto diversa da quella del normale utente del sistema operativo Android. Quindi ho pensato che documentarlo sarebbe stato d'aiuto.
Cosa pensiamo - User's Terminology (UT)
Memoria interna (UT) | Memoria esterna (UT) |
---|---|
memoria interna incorporata nel telefono | scheda Secure Digital (SD) rimovibile o memoria micro SD |
Esempio: memoria interna da 32 GB del Nexus 6P. | Esempio: spazio di archiviazione in schede SD rimovibili fornite da venditori come Samsung, Sandisk, Stronzio, Trascendi e altri |
Ma, secondo la documentazione / guida di Android - Google's Terminology (GT)
Memoria interna (GT):
Per impostazione predefinita, i file salvati nella memoria interna sono privati per l'applicazione e altre applicazioni non possono accedervi (né l'utente può).
Memoria esterna (GT):
Può trattarsi di un supporto di memorizzazione rimovibile (come una scheda SD) o di una memoria interna (non rimovibile).
External Storage (GT) può essere classificato in due tipi:
Storage esterno primario | Memoria esterna secondaria o memoria rimovibile (GT) |
---|---|
Questo è lo stesso della memoria interna incorporata del telefono (o) della memoria interna (UT) | Questo è lo stesso della memoria micro SD rimovibile (o) Memoria esterna (UT) |
Esempio: memoria interna da 32 GB del Nexus 6P. | Esempio: spazio di archiviazione in schede SD rimovibili fornite da venditori come Samsung, Sandisk, Stronzio, Trascendi e altri |
È possibile accedere a questo tipo di archiviazione su Windows PC collegando il telefono al PC tramite cavo USB e selezionando Fotocamera (PTP) nella notifica delle opzioni USB. | È possibile accedere a questo tipo di archiviazione su Windows PC collegando il telefono al PC tramite cavo USB e selezionando Trasferimento file nella notifica delle opzioni USB. |
In poche parole,
Storage esterno (GT) = Internal Storage (UT) e External Storage (UT)
Archivi rimovibili (GT) = Storage esterno (UT)
Internal Storage (GT) non ha un termine in UT.
Lasciami spiegare chiaramente
Internal Storage (GT): per impostazione predefinita, i file salvati nella memoria interna sono privati per l'applicazione e altre applicazioni non possono accedervi. Anche l'utente dell'app non può accedervi utilizzando il file manager; anche dopo aver abilitato l'opzione "mostra file nascosti" nel file manager. Per accedere ai file in Archiviazione interna (GT), devi eseguire il root del tuo telefono Android. Inoltre, quando l'utente disinstalla l'applicazione, questi file vengono rimossi / eliminati.
Quindi Internal Storage (GT) NON è ciò che pensiamo come memoria interna 32/64 GB di Nexus 6P
Generalmente, la posizione di Internal Storage (GT) sarebbe: /data/data/your.application.package.appname/someDirectory/
Storage esterno (GT):
Ogni dispositivo compatibile con Android supporta una "memoria esterna" condivisa che è possibile utilizzare per salvare i file. I file salvati nella memoria esterna sono leggibili da tutto il mondo e possono essere modificati dall'utente quando abilitano la memorizzazione di massa USB per trasferire file su un computer.
Posizione di archiviazione esterna (GT): potrebbe trovarsi in qualsiasi punto della memoria interna (UT) o nella memoria rimovibile (GT), ad esempio la scheda micro SD. Dipende dall'OEM del tuo telefono e anche dalla versione del SO Android.
Per leggere o scrivere file su Storage esterno (GT), l'app deve acquisire le autorizzazioni di sistema READ_EXTERNAL_STORAGE
o WRITE_EXTERNAL_STORAGE
.
Per esempio:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Se è necessario sia leggere che scrivere file, è necessario richiedere solo l'autorizzazione
WRITE_EXTERNAL_STORAGE
, poiché richiede implicitamente anche l'accesso in lettura.
In External Storage (GT) , puoi anche salvare i file che sono app-private
Ma,
Quando l'utente disinstalla l'applicazione, questa directory e tutto il suo contenuto vengono cancellati.
Quando è necessario salvare i file che sono app-private in External Storage (GT) ?
Se gestisci file che non sono destinati ad altre app (come trame grafiche o effetti sonori utilizzati solo dalla tua app), dovresti utilizzare una directory di archiviazione privata nella memoria esterna
A partire da Android 4.4, leggere o scrivere file nelle directory private della tua app non richiede le autorizzazioni
READ_EXTERNAL_STORAGE
oWRITE_EXTERNAL_STORAGE
. Quindi puoi dichiarare che il permesso dovrebbe essere richiesto solo nelle versioni inferiori di Android aggiungendo l'attributomaxSdkVersion
:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
Metodi per memorizzare in Internal Storage (GT):
Entrambi questi metodi sono presenti nella classe Context
File getDir (String name, int mode)
File getFilesDir ()
Metodi per archiviare nello Storage esterno primario ie Internal Storage (UT):
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
All'inizio, tutti usavano Environment.getExternalStorageDirectory () , che puntava alla radice di Primary External Storage . Di conseguenza, lo Storage esterno primario era pieno di contenuti casuali.
Successivamente, sono stati aggiunti questi due metodi:
Nella classe
Context
, hanno aggiunto getExternalFilesDir () , che punta a una directory specifica dell'applicazione su Primary External Storage. Questa directory e il suo contenuto verranno eliminati quando l'app viene disinstallata.Environment.getExternalStoragePublicDirectory () per luoghi centralizzati per archiviare tipi di file ben noti, come foto e filmati. Questa directory e il suo contenuto NON saranno cancellati quando l'app viene disinstallata.
Metodi per archiviare in Archivi rimovibili (GT) cioè micro SD card
Prima del livello API 19 , non esisteva un modo ufficiale di memorizzare nella scheda SD. Ma molti potrebbero farlo usando librerie o API non ufficiali.
Ufficialmente, un metodo è stato introdotto nella classe Context
in livello API 19 (versione Android 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
Restituisce percorsi assoluti alle directory specifiche dell'applicazione su tutti i dispositivi di archiviazione condivisi / esterni in cui l'applicazione può posizionare i file permanenti che possiede. Questi file sono interni all'applicazione e in genere non sono visibili all'utente come supporto.
Ciò significa che restituirà percorsi per entrambi i tipi di memoria esterna (GT) - memoria interna e scheda Micro SD. Generalmente il secondo percorso sarebbe il percorso di archiviazione della scheda micro SD (ma non sempre). Quindi è necessario verificarlo eseguendo il codice con questo metodo.
Esempio con lo snippet di codice:
Ho creato un nuovo progetto Android con attività vuote, ho scritto il seguente codice all'interno
protected void onCreate(Bundle savedInstanceState)
metodo di 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);
Dopo aver eseguito il codice sopra,
Produzione:
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
Nota: ho collegato il mio telefono a PC Windows; abilitato entrambe le opzioni sviluppatore, debug USB e quindi eseguito questo codice. Se non si collega il telefono ; ma eseguirlo su un emulatore Android , l'output potrebbe variare. Il mio modello di telefono è Coolpad Note 3 - in esecuzione su Android 5.1
Posizioni di archiviazione sul mio telefono:
Posizione di memoria Micro SD : /storage/sdcard1
Posizione di archiviazione interna (UT) : /storage/sdcard0
.
Nota che /sdcard
e /storage/emulated/0
puntano anche a Internal Storage (UT). Ma questi sono /storage/sdcard0
simbolici a /storage/sdcard0
.
Per comprendere chiaramente diversi percorsi di archiviazione in Android, perfavore segui questa risposta
Dichiarazione di non responsabilità: tutti i percorsi di archiviazione menzionati sopra sono percorsi sul mio telefono. I tuoi file potrebbero non essere memorizzati su stessi percorsi di archiviazione. Perché, le posizioni / percorsi di archiviazione possono variare su altri telefoni cellulari a seconda del produttore, del produttore e delle diverse versioni del sistema operativo Android.
Salva database su scheda SD (backup DB su 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;
}
}
chiama questo metodo in questo modo:
ExportDB ( "myDB.db", "com.example.exam", "/ myFolder");
Recupera la directory dei dispositivi:
Prima di tutto Aggiungi autorizzazione di archiviazione per leggere / recuperare la directory del dispositivo.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Crea classe modello
//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;
}
}
Crea una lista usando il modello di directory per aggiungere i dati della directory.
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
Recupera la directory usando il seguente metodo.
//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();
}
}
Stampa l'elenco delle directory nel registro.
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
uso
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
Per recuperare i file interni / cartella della directory specifica utilizzare lo stesso metodo basta cambiare argomento, passare il percorso corrente selezionato in argomento e gestire la risposta per lo stesso.
Per ottenere l'estensione del file:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}