[Android Studio] 在Android 11下,讀寫外部儲存空間

升上Android 11以後,讀寫檔案變得額外的嚴苛。


就算給與

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
開發人員也無法對於外部的檔案進行存取了。即使你在UI提示使用者給與權限。
也是無法對外部的檔案進行讀取。
試過在程式碼中加入

File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator);
File[] fList = directory.listFiles();

如上面兩行程式碼,對Downloads資料夾的路徑查看Downlaods資料夾裡有什麼檔案。

如果是在Android 11下,是無法查看Downloads資料夾裡有什麼的。就算引導使用者至檔案管理程式抓取路徑,開發者也無法讀取既有的檔案路徑下的檔案內容(試過讀取CSV檔是失敗的)。

(PS: 同樣的情況查看Picture、Audio資料夾裡的資料也一樣的失敗的)


那我們如何在Android 11裡讀取手機裡的檔案呢?


1. 讀取Android 11手機裡的檔案

最簡單的方式就是讀取自己APP裡可以控制的資料夾。路徑如下:

/Android/media/yourAPP.packageName/

一開始APP安裝好後在media folder裡是不會有你開發的APP專用的資料夾

所以我會在程式裡面加一行,讓程式自動生成一個APP專用的資料夾,程式碼如下:

directory = new File(view.getContext().getExternalMediaDirs()[0] + File.separator);
// if the folder isn't exist, create it.
if (!directory.exists()) {
createFolder = directory.mkdirs();
}
PS: getExternalMediaDirs()[0]這個程式碼是用於抓取/Android/media/yourAPP.packageName/路徑用的

建立好之後,開發的APP就可以任意存取這個資料夾裡的任何檔案了。

注意: 如果刪除APP,APP的專用資料夾裡的檔案也會跟著一起消失


2. 寫入檔案到共用資料夾,並讀取檔案 (可讀可寫)

另外,<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

擁有以上兩種權限的APP,是可以對外部儲存空間進行寫入的,但讀取不行,能讀取的就只有你自己APP創立出來的檔案才可進行讀取。EX:在Downloads資料夾裡寫入一個CSV檔,你的程式就只能對這個檔案進行讀取,依然看不到Downloads下的任何不屬於你創建的檔案,看不到,指定其檔案路徑也讀不到檔案。

PS: 如果刪除APP,再重新安裝APP。那支APP對於之前建立過的檔案也沒有讀取的權限。


建立檔案:

在Downloads資料夾底下建立一個資料夾名為appData

directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + File.separator + "appData");

createFolder = true;

// if the folder MoneyList isn't exist, create it.
if (!directory.exists()) {
createFolder = directory.mkdirs();
}


讀取檔案:

File directory = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS), "");

// get all the files from a directory
File[] fList = directory.listFiles();


以上兩行為讀取Downloads共用資料夾底下,開發者APP讀取己創建的檔案。回傳的FList會有您自己創建的檔案名稱LIST,這也是開發者可以讀取的檔案(包含覆蓋、刪除動作)。


看了一下Android Developer,似乎是可以讀取共用資料夾裡的資料。但我怎麼試都試不出來。最多只能讀取共用資料夾裡,我自己建立的檔案。就是讀取不到,後來才把讀取這件事情轉移到APP專用的資料夾底下去執行讀取。


如果有更好的方法,歡迎在底下留言告訴我。謝謝


參考 references:

https://stackoverflow.com/questions/57116335/environment-getexternalstoragedirectory-deprecated-in-api-level-29-java



留言

熱門文章