Android
Lagring av filer i intern och extern lagring
Sök…
Syntax
- FileOutputStream openFileInput (String name)
- FileOutputStream openFileOutput (String name, int mode)
- File (File dir, String name)
- File (String path)
- File getExternalStoragePublicDirectory (Stringtyp)
- File getExternalFilesDir (String type)
parametrar
Parameter | detaljer |
---|---|
namn | Namnet på filen som ska öppnas. OBS! Kan inte innehålla sökvägsavskiljare |
läge | Driftläge. Använd MODE_PRIVATE för standardåtgärd och MODE_APPEND att lägga till en befintlig fil. Andra lägen inkluderar MODE_WORLD_READABLE och MODE_WORLD_WRITEABLE , som båda avskrivs i API 17. |
dir | Katalog över filen för att skapa en ny fil i |
väg | Sökväg för att ange platsen för den nya filen |
typ | Typ av filkatalog att hämta. Kan vara null eller något av följande: DIRECTORY_MUSIC , DIRECTORY_PODCASTS , DIRECTORY_RINGTONES , DIRECTORY_ALARMS , DIRECTORY_NOTIFICATIONS , DIRECTORY_PICTURES or DIRECTORY_MOVIES |
Använda intern lagring
Som standard är alla filer som du sparar till Intern lagring privata för din applikation. De kan inte nås av andra applikationer eller av användaren under normala omständigheter. Dessa filer raderas när användaren avinstallerar applikationen .
Att skriva text till en fil
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();
}
Lägga till text i en befintlig fil
Använd Context.MODE_APPEND
för Context.MODE_APPEND
för openFileOutput
fileOutputStream = openFileOutput(fileName, Context.MODE_APPEND);
Använda extern lagring
"Extern" lagring är en annan typ av lagring som vi kan använda för att spara filer på användarens enhet. Det har några viktiga skillnader från "Intern" lagring, nämligen:
- Det är inte alltid tillgängligt. När det gäller ett flyttbart medium (SD-kort) kan användaren helt enkelt ta bort lagringsutrymmet.
- Det är inte privat. Användaren (och andra applikationer) har åtkomst till dessa filer.
- Om användaren avinstallerar appen kommer filerna du sparar i katalogen som hämtas med
getExternalFilesDir()
att tas bort.
För att kunna använda extern lagring måste vi först få rätt behörigheter. Du måste använda:
-
android.permission.WRITE_EXTERNAL_STORAGE
för läsning och skrivning -
android.permission.READ_EXTERNAL_STORAGE
för att bara läsa
För att ge dessa behörigheter måste du identifiera dem i din AndroidManifest.xml
som sådan
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
OBS: Eftersom det är farliga behörigheter om du använder API-nivå 23 eller högre, måste du begära behörigheterna vid körning .
Innan du försöker skriva eller läsa från extern lagring bör du alltid kontrollera att lagringsmediet är tillgängligt.
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
}
När du skriver filer till extern lagring bör du bestämma om filen ska erkännas som offentlig eller privat. Även om båda dessa typer av filer fortfarande är tillgängliga för användaren och andra applikationer på enheten finns det en viktig skillnad mellan dem.
Offentliga filer ska finnas kvar på enheten när användaren avinstallerar appen. Ett exempel på en fil som bör sparas som offentligt skulle vara foton som tas via din applikation.
Privata filer bör alla tas bort när användaren avinstallerar appen. Dessa typer av filer skulle vara appspecifika och inte vara användbara för användaren eller andra applikationer. Ex. tillfälliga filer som laddats ned / används av din applikation.
Så här får du tillgång till Documents
för både offentliga och privata filer.
offentlig
// 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();
Privat
// 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: Intern och extern lagring - Terminologi förtydligande
Android-utvecklare (främst nybörjare) har förvirrats vad gäller intern och extern lagringsterminologi. Det finns många frågor om Stackoverflow om samma. Detta beror främst på att terminologi enligt Google / officiell Android-dokumentation skiljer sig mycket från den vanliga Android OS-användaren. Därför trodde jag att det skulle hjälpa att dokumentera detta.
Vad vi tycker - Användarens terminologi (UT)
Intern lagring (UT) | Extern lagring (UT) |
---|---|
telefonens inbyggda internminne | avtagbart Secure Digital (SD) -kort eller micro SD-lagring |
Exempel: Nexus 6P: s interna minne på 32 GB. | Exempel: lagringsutrymme i flyttbara SD-kort som tillhandahålls av leverantörer som samsung, sandisk, strontium, transcend och andra |
Men enligt Android-dokumentation / guide - Googles terminologi (GT)
Intern lagring (GT):
Som standard är filer som är sparade på den interna lagringen privata för din applikation och andra applikationer har inte åtkomst till dem (inte heller kan användaren).
Extern lagring (GT):
Detta kan vara ett flyttbart lagringsmedium (som ett SD-kort) eller ett internt (icke-flyttbart) lagringsutrymme.
Extern lagring (GT) kan kategoriseras i två typer:
Primär extern lagring | Sekundär extern lagring eller flyttbar lagring (GT) |
---|---|
Detta är samma sak som telefonens inbyggda interna minne (eller) Intern lagring (UT) | Detta är samma sak som avtagbar micro SD-kortlagring (eller) Extern lagring (UT) |
Exempel: Nexus 6P: s interna minne på 32 GB. | Exempel: lagringsutrymme i flyttbara SD-kort som tillhandahålls av leverantörer som samsung, sandisk, strontium, transcend och andra |
Denna typ av lagring kan nås på Windows PC genom att ansluta din telefon till PC via USB-kabel och välja Camera (PTP) i meddelandet om USB-alternativ. | Den här typen av lagring kan nås på Windows-datorn genom att ansluta din telefon till PC via USB-kabel och välja Filöverföring i meddelandet om USB-alternativ. |
I ett nötskal,
Extern lagring (GT) = Intern lagring (UT) och extern lagring (UT)
Flyttbar lagring (GT) = Extern lagring (UT)
Intern lagring (GT) har inte en term i UT.
Låt mig förklara klart,
Intern lagring (GT): Som standard är filer som sparats på den interna lagringen privata för din applikation och andra applikationer har inte tillgång till dem. Din appanvändare kan inte heller komma åt dem med filhanteraren; även efter att ha aktiverat alternativet "visa dolda filer" i filhanteraren. För att få åtkomst till filer i Intern lagring (GT) måste du rota din Android-telefon. När användaren avinstallerar din applikation tas dessutom dessa filer bort / raderas.
Så intern lagring (GT) är INTE vad vi tycker som Nexus 6P: s interna minne på 32/64 GB
I allmänhet skulle platsen för intern lagring (GT) vara: /data/data/your.application.package.appname/someDirectory/
Extern lagring (GT):
Varje Android-kompatibel enhet stöder en delad "extern lagring" som du kan använda för att spara filer. Filer som sparats på den externa lagringen är världsläsbara och kan ändras av användaren när de gör det möjligt för USB-masslagring att överföra filer till en dator.
Extern lagringsplats (GT): Det kan vara var som helst i din interna lagring (UT) eller i din flyttbara lagring (GT), dvs micro SD-kort. Det beror på telefonens OEM och även på Android OS-version.
För att kunna läsa eller skriva filer på extern lagring (GT) måste din app förvärva READ_EXTERNAL_STORAGE
eller WRITE_EXTERNAL_STORAGE
.
Till exempel:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
...
</manifest>
Om du behöver både läsa och skriva filer måste du bara begära
WRITE_EXTERNAL_STORAGE
behörighet, eftersom det implicit också kräverWRITE_EXTERNAL_STORAGE
.
I extern lagring (GT) kan du också spara filer som är app-privata
Men,
När användaren avinstallerar din applikation raderas den här katalogen och allt dess innehåll.
När behöver du spara filer som är app-privata i Extern Storage (GT) ?
Om du hanterar filer som inte är avsedda för andra appar att använda (t.ex. grafiska strukturer eller ljudeffekter som endast används av din app), bör du använda en privat lagringskatalog på den externa lagringen
Från och med Android 4.4 kräver inte läsning eller skrivning av filer i din apps privata kataloger
READ_EXTERNAL_STORAGE
ellerWRITE_EXTERNAL_STORAGE
. Så du kan förklara att tillstånd ska begäras endast i de lägre versionerna av Android genom att lägga till attributetmaxSdkVersion
:
<manifest ...>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
...
</manifest
Metoder för att lagra i intern lagring (GT):
Båda dessa metoder finns i kontextklass
File getDir (String name, int mode)
File getFilesDir ()
Metoder för att lagra i primär extern lagring, dvs. intern lagring (UT):
File getExternalStorageDirectory ()
File getExternalFilesDir (String type)
File getExternalStoragePublicDirectory (String type)
I början använde alla Environment.getExternalStorageDirectory () , som pekade på roten till Primär extern lagring . Som ett resultat fylldes primär extern lagring med slumpmässigt innehåll.
Senare tillsattes dessa två metoder:
I
Context
lägger de till getExternalFilesDir () och pekade på en appspecifik katalog på Primär extern lagring. Den här katalogen och dess innehåll kommer att raderas när appen avinstalleras.Environment.getExternalStoragePublicDirectory () för centraliserade platser för att lagra kända filtyper, som foton och filmer. Den här katalogen och dess innehåll raderas INTE när appen avinstalleras.
Metoder för att lagra i Removable Storage (GT) dvs. mikro SD-kort
Före API-nivå 19 fanns det inget officiellt sätt att lagra på SD-kort. Men många kan göra det med inofficiella bibliotek eller API: er.
Officiellt introducerades en metod i Context
i API-nivå 19 (Android version 4.4 - Kitkat).
File[] getExternalFilesDirs (String type)
Det returnerar absoluta sökvägar till applikationsspecifika kataloger på alla delade / externa lagringsenheter där applikationen kan placera ihållande filer den äger. Dessa filer är interna i applikationen och är vanligtvis inte synliga för användaren som media.
Det betyder att det kommer att returnera vägar till båda typerna av extern lagring (GT) - Internt minne och Micro SD-kort. I allmänhet skulle den andra vägen vara lagringsvägen för micro SD-kort (men inte alltid). Så du måste kolla in det genom att köra koden med den här metoden.
Exempel med kodavsnitt:
Jag skapade ett nytt Android-projekt med tom aktivitet, skrev följande kod inuti
protected void onCreate(Bundle savedInstanceState)
metod för 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);
Efter att ha utfört ovanstående kod,
Produktion:
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
Obs! Jag har anslutit min telefon till Windows PC; aktiverade både utvecklaralternativ, USB-felsökning och körde sedan den här koden. Om du inte ansluter din telefon ; men istället kör detta på Android-emulator , kan din produktion variera. Min telefonmodell är Coolpad Note 3 - körs på Android 5.1
Lagringsplatser på min telefon:
Micro SD-lagringsplats : /storage/sdcard1
Intern lagringsplats (UT) : /storage/sdcard0
.
Observera att /sdcard
& /storage/emulated/0
också pekar på Intern lagring (UT). Men det här är symlänkar till /storage/sdcard0
.
För att tydligt förstå olika lagringsvägar i Android, gå igenom det här svaret
Friskrivningsklausul: Alla lagringsvägar som nämns ovan är vägar på min telefon. Dina filer kanske inte lagras på samma lagringsvägar. Eftersom lagringsplatserna / banorna kan variera på andra mobiltelefoner beroende på din leverantör, tillverkare och olika versioner av Android OS.
Spara databas på SD-kort (säkerhetskopierings-DB på 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;
}
}
kalla den här metoden på detta sätt:
ExportDB ( "myDB.db", "com.example.exam", "/ myFolder");
Hämta enhetskatalog:
Lägg först till lagringstillstånd för att läsa / hämta enhetskatalogen.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Skapa modellklass
//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;
}
}
Skapa lista med katalogmodell för att lägga till katalogdata.
//define list to show directory
List<DirectoryModel> rootDir = new ArrayList<>();
Hämta katalogen med följande metod.
//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();
}
}
Skriv ut kataloglistan i loggen.
//print directory list in logs
private void printDirectoryList() {
for (int i = 0; i < rootDir.size(); i++) {
Log.e(TAG, "printDirectoryLogs: " + rootDir.get(i).toString());
}
}
Användande
//to Fetch Directory Call function with root directory.
String rootPath = Environment.getExternalStorageDirectory().toString(); // return ==> /storage/emulated/0/
getDirectory(rootPath );
För att hämta inre filer / mapp med en specifik katalog använda samma metod, ändra bara argument, passera den aktuella valda sökvägen i argument och hantera svar för samma.
Så här får du filändelse:
private String getExtension(String filename) {
String filenameArray[] = filename.split("\\.");
String extension = filenameArray[filenameArray.length - 1];
Log.d(TAG, "getExtension: " + extension);
return extension;
}