android外部存儲
⑴ Android各版本的外部存儲配置建議
採用分區存儲只能讀寫外部共享目錄。
採用非分區存儲是可以讀寫外部存儲任何目錄的。
注意:android10在分區存儲模式下不能用文件路徑讀寫外部共享文件,但在android11在分區存儲下又可以用文件路徑讀寫外部共享文件,所以如果您的項目存在通過文件路徑來讀寫外部共享文件,要在配置文件中設置 android:requestLegacyExternalStorage="true" 來適配android10
結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
a 應用從非分區存儲更新,結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
b 正常卸載安裝 結果 Environment.isExternalStorageLegacy() 為 flase ,採用的是分區存儲方法。
結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
結果 Environment.isExternalStorageLegacy() 為 false,採用的是分區存儲方法。
a、應用從非分區存儲更新,結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
b、應用正常卸載安裝或者從分區存儲更新,結果 Environment.isExternalStorageLegacy() 為 flase,採用的是分區存儲方法。
結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
a 應用從非分區存儲更新,結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
b 正常卸載安裝 結果 Environment.isExternalStorageLegacy() 為 flase ,採用的是分區存儲方法。
結果 Environment.isExternalStorageLegacy() 為 true,採用的是非分區存儲方法。
採用的是非分區存儲方法
⑵ Android外部存儲ExternalStorage
內存(emory)
內部存儲(ternalStorage)
1)storage或者mnt文件夾下
2) 通過:
Environment.getExternalStorageDirectory()
可以看到外部存儲的位置
3) 公有目錄(DCIM、DOWNLOAD等),要使用需要申請許可權。
4) 私有目錄(Android/data/應用包名),只能被當前應用訪問。
String path= Environment.getExternalStorageDirectory().getAbsolutePath() +"/Mytest.txt";
try {
if (!file.exists()) {
file.createNewFile();
}
}catch (IOException e) {
e.printStackTrace();
}
try {
if (!file.exists()) {
file.createNewFile();
}
FileOutputStream fos=new FileOutputStream(path,true);
String str=infoEdt.getText().toString();
fos.write(str.getBytes());//以位元組流的方式寫入
}catch (IOException e) {
e.printStackTrace();
}
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
其中第二條許可權可能會報錯,這時候解決辦法是:
在報錯的地方添加
tools:ignore="ProtectedPermissions"
同時在manifest標簽里添加;
xmlns:tools="http://schemas.android.com/tools"
FileInputStream fis =new FileInputStream(path);
byte[] b =new byte[1024];
int len = fis.read(b);//讀取fis位元組流,將其存儲在位元組數組b中,並返回數組的長度(位元組的個數)
String str2=new String(b,0,len);
txt.setText(str2);
注意:1、從外部存儲讀取文件不需要許可權
2、Android6.0以上對外部存儲(內存卡)共有目錄的讀寫需要運行時許可權(允許訪問內存卡),這個許可權需要用戶手動開啟,只在AndroidManifest.xml中申請是沒用的。
int permissionContextCompet.checkSelfPermission(context,permission) 檢查是否具有許可權
第一個參數,環境上下文(this),第二個參數,許可權名,Manifest.permission.WRITE_EXTERNAL_STORAGE,返回的是一個int類型的變數,將其與PackageManger.PERMISSION_GRANTED比較,等於則說明有許可權,不等於的話則要動態申請許可權:
if(permission!= PackageManager.PERMISSION_GRANTED){
//沒有許可權,則要申請許可權
}
ActivityCompet.reaquestPermissions(activity,permission,code) 請求許可權,第一個參數:activity 第二個參數:String類型的數組,裡面裝了各種許可權, 當有多項許可權需要申請的時候可以一起申請,第三個參數:一個int類型的請求碼,動態申請許可權的時候會觸發onRequestPermissionsResult()方法,如果在申請的過程中有什麼需要做的操作可以定義在該方法中,第三個參數請求嗎可以幫助知道是那個許可權的申請觸發了這個方法
int permission=ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if(permission!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==1){
//當前沒有什麼要處理的
}
}
通過:Environment.getExternalStorageDirectory()獲取到的是根目錄,通過在後面拼接目錄名稱,可以訪問到公有目錄
要獲取外部存儲目錄的私有目錄,可以通過:
1)Context.getExternalFilesDir(String type)獲取到SDCard/Android/data/包名/files/目錄,這個目錄下一般存放一些需要長時間保存的數據。這個參數是用於指定文件夾類型的(圖片,音樂,視頻...)。
2)Context。getExternalCacheDir()獲取到SDCard/Android/data/包名/cache/目錄,這個目錄下面一般存放一些臨時的緩存性的數據。
⑶ xamarin怎樣獲取android外卡路徑
xamarin怎樣獲取android外卡路徑
一部分手機將eMMC存儲掛載到 /mnt/external_sd 、/mnt/sdcard2 等節點,而將外置的SD卡掛載到 Environment.getExternalStorageDirectory()這個結點。
此時,調用Environment.getExternalStorageDirectory(),則返回外置的SD的路徑。
android 怎樣動態的獲取sd卡路徑
鏈接電腦USB調試情況下,在電腦上有新的磁碟顯示,一個SD的,一個手機的,打開SD的就可以找各文件夾路徑
Android怎樣獲取外部存儲器路徑
讀寫sdcard上的文件
其中讀寫步驟按如下進行:
1、調用Environment的getExternalStorageState()方法判斷手機上是否插了sd卡,且應用程序具有讀寫SD卡的許可權,如下代碼將返回true
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)
2、調用Environment.getExternalStorageDirectory()方法來獲取外部存儲器,也就是SD卡的目錄,或者使用"/mnt/sdcard/"目錄
3、使用IO流操作SD卡上的文件
注意點:手機應該已插入SD卡,對於模擬器而言,可通過mksdcard命令來創建虛擬存儲卡
必須在AndroidManifest.xml上配置讀寫SD卡的許可權
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
我怎樣才能獲得外部SD卡路徑為Android 4.0 +
1. 我想你需要這個外部SD卡:
new File("/mnt/external_sd/")
或
new File("/mnt/extSdCard/")
你的情況......
在更換Environment.getExternalStorageDirectory()您的作品,應在MNT目錄優先和工作在那裡檢查什麼..
你鍵入選擇哪個SD卡
File storageDir = new File("/mnt/");
if(storageDir.isDirectory()){
String[] dirList = storageDir.list();
TODO some type of selecton method?
}
怎樣獲取class路徑
- importjava.io.File;
-
publicclassFileTest{
-
publicstaticvoidmain(String[]args)throwsException{
-
System.out.println(Thread.currentThread().getContextClassLoader()
-
.getResource(""));
-
System.out.println(FileTest.class.getClassLoader().getResource(""));
-
System.out.println(ClassLoader.getSystemResource(""));
-
System.out.println(FileTest.class.getResource(""));
-
System.out.println(FileTest.class.getResource("/"));
-
Class文件所在路徑
-
System.out.println(newFile("/").getAbsolutePath());
-
System.out.println(System.getProperty("user.dir"));
-
System.out.println(System.getProperty("file.encoding"));
-
}
-
}
android 怎麼獲取相冊路徑
android手機4.2版本之前是一個方法,大於4.2版本又是一個方法。
注意:現在手機市場android版本2015面上半年平均4.4,現在是平均5.0了。
-
before
你網路一下,都能查到,很簡單.
-
after
private void startPickPhotoActivity() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("image/*"); Or 'image/ jpeg '
startActivityForResult(intent, RESULT_PICK_PHOTO_NORMAL);
}
獲得圖片返回的路徑
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent data) {
if (requestCode == RESULT_PICK_PHOTO_NORMAL) {
if (resultCode == RESULT_OK && data != null) {
選中圖片路徑
mFileName = MainActivity.getPath(getApplicationContext(),
data.getData());
if ("".equals(mFileName)) {
return;
}
Intent intent = new Intent(this, EditActivity.class);
intent.putExtra("pathName", mFileName);
startActivity(intent);
}
}
}
@TargetApi(Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
DocumentProvider
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
ExternalStorageProvider
if (UriUtils.isExternalStorageDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
if ("primary".equalsIgnoreCase(type)) {
return Environment.getExternalStorageDirectory() + "/"
+ split[1];
}
}
DownloadsProvider
else if (UriUtils.isDownloadsDocument(uri)) {
final String id = DocumentsContract.getDocumentId(uri);
final Uri contentUri = ContentUris.withAppendedId(
Uri.parse("content:downloads/public_downloads"),
Long.valueOf(id));
return UriUtils.getDataColumn(context, contentUri, null, null);
}
MediaProvider
else if (UriUtils.isMediaDocument(uri)) {
final String docId = DocumentsContract.getDocumentId(uri);
final String[] split = docId.split(":");
final String type = split[0];
Uri contentUri = null;
if ("image".equals(type)) {
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
} else if ("video".equals(type)) {
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
} else if ("audio".equals(type)) {
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
}
final String selection = MediaColumns._ID + "=?";
final String[] selectionArgs = new String[] { split[1] };
return UriUtils.getDataColumn(context, contentUri, selection,
selectionArgs);
}
}
MediaStore (and general)
else if ("content".equalsIgnoreCase(uri.getScheme())) {
Return the remote address
if (UriUtils.isGooglePhotosUri(uri))
return uri.getLastPathSegment();
return UriUtils.getDataColumn(context, uri, null, null);
}
File
else if ("file".equalsIgnoreCase(uri.getScheme())) {
return uri.getPath();
}
return null;
}
如何獲取android sdcard路徑
Environment.getExternalStorageDirectory()
android怎麼獲取U盤路徑
用Re管理器進入/mnt/目錄一個一個找
android怎麼獲取分區路徑
我們可以在adb中使用df 來查看分區情況。
1、跨分區不能用 MV命令來拷貝。但是可以用CP命令。如PWD,當前目錄為:/data/local/tmp 。
此目錄下有個busybox和1.txt文件。則利用CP命令拷貝如下:./busybox cp1.txt /system.
2、Android的用戶組有 System, root, shell
3、怎麼樣才能操作分區。
分區操作是需要許可權的。一般來說System分區的許可權限製得比較嚴,Data分區限制比較嚴,用戶可以操作的目錄有local,app目錄。比如/data/local/tmp.
data分區常用目錄:app , system , data ,local,misc 其中system,local可以進入並使用ls等命令。data,app可以進入,但不能用ls命令。
data/data目錄:存放的是所有APK程序數據的目錄,每個APK對就一個自己的Data目錄,就是在data/data/目錄下,會產生一個跟Package一樣的目錄。如有一個APK,它的包名叫.test.hello則,在data/data/目錄下會有一個.test.hello的目錄,這個APK只能操作此目錄,不能操作其它APK的目錄.這個在LINUX下叫做用戶進程只能操作自己的進程目錄.
data/app目錄:用戶安裝的APK放在這里。我們如果把APK放入這個文件夾下面的話,就算安裝好了。這就叫靜默安裝。不用管APK文件裡面的lib目錄下的庫文件,系統會自動幫我們放入調用庫的。
data/system目錄下面有packages.xml ,packages.list,appwidgets.xml, 等等一些記錄手機安裝的軟體,Widget等信息。
data/misc目錄:保存WIFI帳號,VPN設置信息等。如保存了一個WIFI連接帳號,則此目錄下的WIFI目錄下面可以查看到。
system分區常用目錄: app , lib, xbin, bin , media,framework.
system/app目錄:存放系統自帶的APK。沒有測試過是否將APK放入到System/app目錄下,也是靜默安裝APK。?
system/lib目錄:存放APK程序用到的庫文件。
system/bin目錄和system/xbin目錄:存放的是shell命令。
system/framework目錄:啟用Android系統所用到框架,如一些jar文件。
4 Android下面的目錄都是有許可權的,要操作目錄都需要有此許可權才能操作,如果沒有,則使用chomd777來修改.如果是分區根目錄,如/data分區, /system分區.都沒有許可權,則需要重新掛載. 使用 mount -oremount XX
⑷ 安卓內外部存儲完全解析 -- 別再弄混了
安卓開發離不開手機存儲,然而大部分人對於安卓開發中的存儲概念存在誤區,內部外部SD卡傻傻分不清?
以下引用來自對 官方文檔 的理解
呵呵呵,先別說話,然而重點來了(敲黑板),按照官方的說法,
內部存儲是指系統的存儲空間,沒有root是訪問不到的呦親,比如sharedPreferenced或者database都是保存在這裡面的。
外部存儲,又分為 2 部分:
然而現實中,常常有同事把手機那個32G,64G存儲叫做內部存儲= =,寶寶好累,人家明明是 ExternalStorage !!
希望本篇能讓大家對內外部存儲有一個正確鮮明的認識
getFilesDir()
路徑如下
文檔 雲:若想操作該路徑,你需要一個輸出流:
就像這樣:
注: this 是 context 對象
在
路徑下會看到新文件哦
如果你還想讀取的話, 文檔 雲:你需要一個輸入流:
Log如下
getCacheDir()
文檔 雲:
路徑如下:
特別的,還有getDir() :
getDir("- -!.txt", Context.MODE_PRIVATE).getAbsolutePath()
路徑如下:
app_是系統自己加上去的
內部存儲就是系統的存儲,沒有root你是看不到的,內部存儲最大特點就是可以用Context對象調用各個獲取路徑的方法。比如: context.fileList()
那就是
下的文件遍歷。
而 deleteFile("ABC") 就是
刪除下名為 ABC 的文件
</br></br></br>
操作外部存儲你首先需要以下許可權
當你申請了write許可權,那麼read許可權默認也就通過啦
再判斷狀態:
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState))
Environment.getExternalStorageDirectory()
這個路徑根據手機廠家不同會有些許變化
直接傳入 Environment 中的常量獲取相應的路徑,如下:
Environment.(Environment.DIRECTORY_ALARMS));
或者
Environment.(Environment.DIRECTORY_PICTURES));
公有目錄下,系統會區分不同類別 (例如鈴聲在系統設置中顯示為鈴聲而不是音樂)
4.4以後訪問該目錄不再需要許可權了
getExternalFilesDir(String type)
eg.
getExternalFilesDir(Environment.DIRECTORY_MUSIC)
特別的:ContextCompat下的
ContextCompat.getExternalFilesDirs(context,type)
返回一個File[],在4.4以後第一條數據默認外部主存儲目錄,第二條數據就是sd卡路徑啦,但是注意4.4之前是沒有第二條數據的哦
該目錄下的特點是卸載程序後,該目錄和其下所有文件均會被刪除
getExternalCacheDir()
注意,使用該目錄注意管理空間,你不能等系統幫你清理,而是自己清理不再需要的緩存
特別的:ContextCompat下的
ContextCompat.getExternalCacheDirs()
道理同上
發現特點了嗎朋友,無論外部內部,只有路徑中有包名,那麼就是私有的,而且是隨著程序的卸載而被刪除的, 有包名的路徑均是Context中的方法,而公有的路徑均是Environment調用的
這個貨真真是要了老命,一般的方法根部不好使,結合網上有的方法加上公司項目中的方法,總結如下:
百分百好用的獲取SD卡路徑方法:
最後集合 path 中的值就是SD卡根目錄
雖然無視版本百分百好用,但是如果你的手機有SD卡槽卻沒插SD卡,該方法最後 path 返回的是 null ,也就是說該方法無法判斷到底是沒插SD卡還是根本不支持SD卡
其實還有一種方法
String path = System.getenv("SECONDARY_STORAGE");
該方法只要你手機支持SD卡,無論你插沒插SD卡,均會返回SD卡路徑,但是 6.0及以上該方法被移除
Environment中源碼其實就是根據這個方法獲取路徑的
安卓官方文檔大家一定要看,他就是我們開發者的權威呀,聖經呀!!
⑸ Android 內部存儲/外部存儲 及 讀寫許可權
Android 使用 VFS (Virtual File System) 虛擬文件系統。VFS提供了供存儲設備掛載的節點,同一存儲設備經過分區後,不同的分區可以掛載到不同的節點上,如手機的內置存儲卡。
內置存儲卡 / 外置SD卡
內部存儲 / 外部存儲
VFS 的目錄以 / 為根節點,根節點下面又有不同的節點。物理存儲設備就是掛載到這些節點上。
內部存儲卡/外置SD卡 ≠ 內部存儲/外部存儲
首先明確, 內置存儲卡/外置SD卡 是在 物理層面 相對於 手機大眾用戶 來說的。
外置SD卡:可手動插拔的SD卡。
內置存儲卡:焊接在手機內部不可拆卸的存儲卡。
而, 內部存 /外部存儲 是在 文件系統邏輯層面 相對於 開發者 來說的,指具體的路徑。
一般針對某個應用而言的,屬於該應用的存儲路徑叫內部存儲,反之為外部存儲。
路徑: /data/data/package_name
/data/data/ 下都是已安裝應用的目錄,該目錄下包含的文件都是以包名作為文件名的目錄,例如 /data/data/com.sankuai.meituan
獲取內部存儲的方式如下:
其中,參數 mode 指創建模式,一種 4 種
注意: Android 7.0 以上 android.os.Build.VERSION.SDK_INT>=Build.VERSION_CODES.N 使用3/4 常量時,將會導致SecurityException,這意味著 不能通過名稱共享私有文件 。
嘗試共享 file://URI URI將會導致FileUriExposedException,StrictMode API政策禁止在您的應用外部公開file://URL。如果您的應用需要與其他應用共享私有文件,則可以使用 FileProvider 與 FLAG_GRANT_READ_URI_PERMISSION 配合使用。 Android 7.0 行為變更 通過FileProvider在應用間共享文件吧
外部存儲,可以是 外置SD卡 或 內置存儲卡的部分分區。
外部存儲,分為 公共目錄 和 私有目錄
獲取方式
檢查可用性的方法:
Android 4.3 以下,只能通過 Context#getExternalFilesDir(type) 來獲取外部存儲在內置存儲卡分區的私有目錄,無法獲取外置SD卡。
Android 4.3 開始,可以通過 Context#getExternalFilesDirs(type) 獲取一個File數組,包含了內置存儲卡分區和外置SD的私有目錄地址。
可以使用兼容庫的靜態方法 ContextCompate.getExternalFilesDirs() 兼容 4.3。
感謝以下文章作者
解析Android內部存儲、外部存儲的區別