Android
Bestanden opslaan in interne en externe opslag
Zoeken…
Syntaxis
- FileOutputStream openFileInput (tekenreeksnaam)
- FileOutputStream openFileOutput (tekenreeksnaam, int-modus)
- Bestand (Bestandsmap, Stringnaam)
- Bestand (Stringpad)
- Bestand getExternalStoragePublicDirectory (type string)
- Bestand getExternalFilesDir (tekenreekstype)
parameters
Parameter | Details |
---|---|
naam | De naam van het te openen bestand. OPMERKING: Kan geen padscheidingstekens bevatten |
mode | Bedrijfsmodus. Gebruik MODE_PRIVATE voor standaardbewerking en MODE_APPEND om een bestaand bestand toe te voegen. Andere modi zijn MODE_WORLD_READABLE en MODE_WORLD_WRITEABLE , die beide zijn verouderd in API 17. |
dir | Directory van het bestand om een nieuw bestand in te maken |
pad | Pad om de locatie van het nieuwe bestand op te geven |
type | Type bestandsmap om op te halen. Kan null , of een van de volgende: DIRECTORY_MUSIC , DIRECTORY_PODCASTS , DIRECTORY_RINGTONES , DIRECTORY_ALARMS , DIRECTORY_NOTIFICATIONS , DIRECTORY_PICTURES of DIRECTORY_MOVIES |
Interne opslag gebruiken
Standaard zijn alle bestanden die u opslaat in Interne opslag privé voor uw toepassing. Ze zijn niet toegankelijk voor andere applicaties, noch voor de gebruiker onder normale omstandigheden. Deze bestanden worden verwijderd wanneer de gebruiker de toepassing verwijdert .
Tekst naar een bestand schrijven
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();
}
Tekst toevoegen aan een bestaand bestand
Gebruik Context.MODE_APPEND
voor de parameter mode van openFileOutput
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
Externe opslag gebruiken
"Externe" opslag is een ander type opslag dat we kunnen gebruiken om bestanden op te slaan op het apparaat van de gebruiker. Het heeft enkele belangrijke verschillen met "Interne" opslag, namelijk:
- Het is niet altijd beschikbaar. In het geval van een verwijderbaar medium (SD-kaart) kan de gebruiker eenvoudig de opslag verwijderen.
- Het is niet privé. De gebruiker (en andere toepassingen) hebben toegang tot deze bestanden.
- Als de gebruiker de app verwijdert, worden de bestanden die u opslaat in de map die is opgehaald met
getExternalFilesDir()
verwijderd.
Om externe opslag te gebruiken, moeten we eerst de juiste machtigingen verkrijgen. U moet het volgende gebruiken:
-
android.permission.WRITE_EXTERNAL_STORAGE
voor lezen en schrijven -
android.permission.READ_EXTERNAL_STORAGE
voor alleen lezen
Om deze machtigingen te verlenen, moet u ze als zodanig identificeren in uw AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
OPMERKING: Aangezien het gevaarlijke machtigingen zijn als u API-niveau 23 of hoger gebruikt, moet u de machtigingen tijdens runtime aanvragen.
Voordat u probeert te schrijven of lezen van externe opslag, moet u altijd controleren of het opslagmedium beschikbaar is.
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
}
Wanneer u bestanden naar de externe opslag schrijft, moet u beslissen of het bestand moet worden herkend als openbaar of privé. Hoewel beide typen bestanden nog steeds toegankelijk zijn voor de gebruiker en andere toepassingen op het apparaat, is er een belangrijk onderscheid tussen beide.
Openbare bestanden moeten op het apparaat blijven staan wanneer de gebruiker de app verwijdert. Een voorbeeld van een bestand dat als Public moet worden opgeslagen, zijn foto's die via uw toepassing zijn genomen.
Privébestanden moeten allemaal worden verwijderd wanneer de gebruiker de app verwijdert. Dit soort bestanden zou app-specifiek zijn en niet van nut zijn voor de gebruiker of andere applicaties. Ex. tijdelijke bestanden gedownload / gebruikt door uw applicatie.
U kunt als volgt toegang krijgen tot de map Documents
voor zowel openbare als privébestanden.
Openbaar
// 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();
Privaat
// 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: interne en externe opslag - Terminologie verduidelijking
Android-ontwikkelaars (voornamelijk beginners) zijn verward met betrekking tot interne en externe opslagterminologie. Er zijn veel vragen over Stackoverflow over hetzelfde. Dit komt vooral door het feit dat de terminologie volgens Google / officiële Android-documentatie heel anders is dan die van de normale Android OS-gebruiker. Daarom dacht ik dat het documenteren hiervan zou helpen.
Wat we denken - User's Terminology (UT)
Interne opslag (UT) | Externe opslag (UT) |
---|---|
ingebouwd intern geheugen van de telefoon | verwijderbare Secure Digital (SD) -kaart of micro SD-opslag |
Voorbeeld: 32 GB intern geheugen van Nexus 6P. | Voorbeeld: opslagruimte in verwijderbare SD-kaarten die worden geleverd door leveranciers zoals Samsung, Sandisk, Strontium, Transcend en andere |
Maar volgens Android Documentation / Guide - Google's Terminology (GT)
Interne opslag (GT):
Bestanden die zijn opgeslagen in de interne opslag zijn standaard privé voor uw toepassing en andere toepassingen hebben er geen toegang toe (noch kan de gebruiker).
Externe opslag (GT):
Dit kan een verwijderbaar opslagmedium (zoals een SD-kaart) of een interne (niet-verwijderbare) opslag zijn.
Externe opslag (GT) kan worden onderverdeeld in twee soorten:
Primaire externe opslag | Secundaire externe opslag of verwisselbare opslag (GT) |
---|---|
Dit is hetzelfde als het ingebouwde interne geheugen van de telefoon (of) Interne opslag (UT) | Dit is hetzelfde als verwijderbare micro SD-kaartopslag (of) Externe opslag (UT) |
Voorbeeld: 32 GB intern geheugen van Nexus 6P. | Voorbeeld: opslagruimte in verwijderbare SD-kaarten die worden geleverd door leveranciers zoals Samsung, Sandisk, Strontium, Transcend en andere |
Dit type opslag is toegankelijk op Windows-pc door uw telefoon via een USB-kabel op de pc aan te sluiten en Camera (PTP) te selecteren in de melding USB-opties. | Dit type opslag is toegankelijk op Windows-pc door uw telefoon via een USB-kabel op de pc aan te sluiten en Bestandsoverdracht te selecteren in de melding USB-opties. |
In een notendop,
Externe opslag (GT) = Interne opslag (UT) en Externe opslag (UT)
Verwisselbare opslag (GT) = Externe opslag (UT)
Internal Storage (GT) heeft geen term in UT.
Laat me het duidelijk uitleggen,
Interne opslag (GT): bestanden die zijn opgeslagen in de interne opslag zijn standaard privé voor uw toepassing en andere toepassingen hebben hier geen toegang toe. Uw app-gebruiker heeft er ook geen toegang toe via Bestandsbeheer; zelfs na het inschakelen van de optie "Verborgen bestanden weergeven" in Bestandsbeheer. Om toegang te krijgen tot bestanden in Interne opslag (GT), moet u uw Android-telefoon rooten. Wanneer de gebruiker uw toepassing verwijdert, worden deze bestanden bovendien verwijderd / verwijderd.
Dus interne opslag (GT) is NIET wat we denken als het 32/64 GB interne geheugen van de Nexus 6P
Over het algemeen zou de locatie van de interne opslag (GT) zijn: /data/data/your.application.package.appname/someDirectory/
Externe opslag (GT):
Elk Android-compatibel apparaat ondersteunt een gedeelde "externe opslag" die u kunt gebruiken om bestanden op te slaan. Bestanden die zijn opgeslagen in de externe opslag zijn wereldwijd leesbaar en kunnen door de gebruiker worden gewijzigd wanneer ze USB-massaopslag inschakelen om bestanden op een computer over te zetten.
Externe opslag (GT) locatie: het kan overal in uw interne opslag (UT) of in uw verwijderbare opslag (GT) zijn, dwz een micro SD-kaart. Het hangt af van de OEM van uw telefoon en ook van de Android OS-versie.
Om bestanden op de externe opslag (GT) te kunnen lezen of schrijven, moet uw app de READ_EXTERNAL_STORAGE
of WRITE_EXTERNAL_STORAGE
hebben.
Bijvoorbeeld:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Als u bestanden zowel moet lezen als schrijven, hoeft u alleen de
WRITE_EXTERNAL_STORAGE
machtiging aan te vragen, omdat deze impliciet ook leestoegang vereist.
In Externe opslag (GT) kunt u ook bestanden opslaan die app-privé zijn
Maar,
Wanneer de gebruiker uw toepassing verwijdert, worden deze map en alle inhoud verwijderd.
Wanneer moet u app-privé opslaan in External Storage (GT) ?
Als u bestanden verwerkt die niet bedoeld zijn om door andere apps te worden gebruikt (zoals grafische structuren of geluidseffecten die alleen door uw app worden gebruikt), moet u een privéopslagmap op de externe opslag gebruiken
Beginnend met Android 4.4, vereist het lezen of schrijven van bestanden in de privé-mappen van uw app niet de
READ_EXTERNAL_STORAGE
ofWRITE_EXTERNAL_STORAGE
. U kunt dus verklaren dat de toestemming alleen voor de lagere versies van Android moet worden aangevraagd door het kenmerkmaxSdkVersion
toe te voegen:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
Methoden om op te slaan in Interne opslag (GT):
Beide methoden zijn aanwezig in de contextklasse
File getDir (String name, int mode)
File getFilesDir ()
Methoden om op te slaan in primaire externe opslag, dwz interne opslag (UT):
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
In het begin gebruikte iedereen Environment.getExternalStorageDirectory () , die naar de root van primaire externe opslag wees. Als gevolg hiervan werd primaire externe opslag gevuld met willekeurige inhoud.
Later zijn deze twee methoden toegevoegd:
In de klasse
Context
hebben ze getExternalFilesDir () toegevoegd, wijzend naar een app-specifieke map op primaire externe opslag. Deze map en de inhoud ervan worden verwijderd wanneer de app wordt verwijderd.Environment.getExternalStoragePublicDirectory () voor gecentraliseerde plaatsen om bekende bestandstypes op te slaan, zoals foto's en films. Deze map en de inhoud ervan worden NIET verwijderd wanneer de app wordt verwijderd.
Methoden om op te slaan in Removable Storage (GT) dwz micro SD-kaart
Vóór API-niveau 19 was er geen officiële manier om op een SD-kaart op te slaan. Maar velen zouden het kunnen doen met behulp van niet-officiële bibliotheken of API's.
Officieel werd één methode geïntroduceerd in Context
klasse in API-niveau 19 (Android-versie 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
Het retourneert absolute paden naar applicatiespecifieke mappen op alle gedeelde / externe opslagapparaten waar de applicatie permanente bestanden kan plaatsen die het bezit. Deze bestanden zijn intern in de toepassing en zijn meestal niet zichtbaar voor de gebruiker als media.
Dat betekent dat het paden naar beide typen externe opslag (GT) retourneert - intern geheugen en Micro SD-kaart. Over het algemeen zou het tweede pad het opslagpad van een micro SD-kaart zijn (maar niet altijd). Dus je moet het bekijken door de code met deze methode uit te voeren.
Voorbeeld met codefragment:
Ik creëerde een nieuw Android-project met lege activiteit, schreef de volgende code erin
protected void onCreate(Bundle savedInstanceState)
methode van 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);
Na het uitvoeren van bovenstaande code,
Output:
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
Opmerking: ik heb mijn telefoon verbonden met Windows PC; beide ontwikkelaaropties ingeschakeld, USB-foutopsporing en vervolgens deze code uitgevoerd. Als u uw telefoon niet aansluit ; maar voer dit in plaats daarvan uit op Android-emulator , uw uitvoer kan variëren. Mijn telefoonmodel is Coolpad Note 3 - draait op Android 5.1
Opslaglocaties op mijn telefoon:
Micro SD-opslaglocatie : /storage/sdcard1
Interne opslag (UT) locatie : /storage/sdcard0
.
Merk op dat /sdcard
& /storage/emulated/0
ook wijzen op Internal Storage (UT). Maar dit zijn symlinks naar /storage/sdcard0
.
Om duidelijk te begrijpen verschillende opslagcapaciteiten paden in Android, Ga door middel van dit antwoord
Disclaimer: Alle hierboven genoemde opslagpaden zijn paden op mijn telefoon. Uw bestanden worden mogelijk niet op dezelfde opslagpaden opgeslagen. Omdat de opslaglocaties / paden op andere mobiele telefoons kunnen variëren, afhankelijk van uw leverancier, fabrikant en verschillende versies van Android OS.
Database opslaan op SD-kaart (Backup DB op 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;
}
}
noem deze methode op deze manier:
ExportDB ( "myDB.db", "com.example.exam", "/ myfolder");
Apparaatmap ophalen:
Voeg eerst Opslagrechten toe om de apparaatmap te lezen / op te halen.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Maak modelklasse
//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;
}
}
Maak een lijst met het mapmodel om mapgegevens toe te voegen.
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
Haal de map op met behulp van de volgende methode.
//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();
}
}
Directorylijst in logboek afdrukken.
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
Gebruik
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
Om interne bestanden / mappen van een specifieke map op te halen, gebruikt u dezelfde methode, wijzigt u gewoon het argument, geeft u het huidige geselecteerde pad door in argument en verwerkt u de reactie daarvoor.
Om bestandsextensie te krijgen:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}