【android】关于android10-11存储的一些知识
數據存儲簡述
| 應用專屬存儲空間 | 存儲應用專屬的文件 | 專屬存儲空間可以在內部存儲和外部存儲為用戶開辟專屬的目錄,可以用來存儲其它用戶不能訪問的文件,可以通過File api訪問,應用被卸載后文件同時被刪除,訪問不需要權限 |
| 共享存儲 | 存儲所有應用共享的數據 | 存儲您的應用打算與其他應用共享的文件,包括媒體、文檔和其他文件,可以使用MediaStoreapi訪問,應用卸載數據仍然存在,訪問需要申請存儲權限 |
外部存儲空間的使用
使用外部專屬存儲空間
在android4.4-android9的版本之中,應用被分配了外部專屬存儲空間,這個空間無需權限即可訪問,如果應用想訪問其它應用的外部專屬存儲空間(分區存儲),那么需要申請存儲權限。
android10以上的版本中,應用的外部存儲空間成為了應用的私有空間,任何應用不可以訪問其它應用的專屬存儲空間
外部專屬存儲空間位于應用的外部存儲中,我們可以在不申請權限的情況下訪問外部專屬存儲空間,外部專屬存儲空間可以在應用卸載后被刪除,專屬空間目錄媒體文件通常不應該被相冊等媒體應用收錄(也就是說相冊中不會展示這個目錄下的圖片)(我們自定義的圖片選擇器也不應該掃描這個目錄下的圖片)
在低于 android10 的版本中,這個目錄是對所有應用可見的
獲取目錄路徑:
-
getExternalFilesDir(""):/storage/emulated/0/Android/data/com.ananananzhuo.storage10demo/files
-
getExternalFilesDirs():獲取目錄下所有文件的列表
上面的代碼中會在外部專屬存儲目錄(/storage/emulated/0/Android/data/com.ananananzhuo.storage10demo/files)下創建一個安安安安安卓.txt的文件,這里我們沒有聲明和申請任何權限。執行代碼后去看文件選擇器中的展示如下:
在外部存儲中訪問非私有目錄則必須聲明申請權限
下面我們寫一個反面案例
提示沒有權限
將媒體文件存儲在外部專屬存儲目錄的媒體文件夾中
將圖片存儲到圖片文件夾中
成功存儲文件
媒體文件夾還有其他選項:
- Environment.DIRECTORY_MOVIES
- Environment.DIRECTORY_DOWNLOADS
- Environment.DIRECTORY_DOCUMENTS
- Environment.DIRECTORY_SCREENSHOTS
存儲媒體的時候我們應該盡量使用 Environment 中的字符串常量獲取媒體文件目錄
android10 以上版本能否使用 Environment.getExternalStorageDirectory 存取文件
高于android10的版本無法使用getExternalStorageDirectory api操作文件,因為 api 已經被刪除,低于android10可以繼續使用該 api
那么高于android10的版本我們應該如何訪問這部分的文件呢?別急,后續的共享存儲會詳細說明
android10以上版本如何獲取sd卡中普通目錄的圖片
我們可以通過SAF在android11以上版本獲取普通目錄圖片(即非專屬目錄,非共享目錄的圖片)
本例中的方法不適用于android10以下系統版本(強行使用會崩潰)
內部存儲
使用 openFileOutput 和 openFileInput 操作內部存儲
將一個文件存儲到內部存儲的 files 目錄下
openFileInput 方法和 openFileOutput 一樣的使用方式
fileList 獲取內部存儲全部文件路徑
getCacheDir 獲取內部存儲緩存文件
內部存儲緩存中的文件可能會在應用被卸載后被刪除,也可能在未卸載前被刪除(內部存儲空間不足的情況)。所以我們使用內部存儲空間緩存文件的時候需要先判斷文件是否存在
context.getCacheDir()共享存儲空間(android10 以上版本)
媒體
android10以上將媒體文件文件按類型保存在公共目錄上,可以使用 MediaStore 訪問媒體文件
以下表格列舉所有共享媒體文件類型
| 圖片 | 存儲在 Pictures 和 DICM 目錄中,系統將這些文件存放在 MediaStore.Images 中 | 無 |
| 視頻 | 存儲 DICM、Movies、Pictures 目錄中,系統將這些文件添加到 MediaStore.VIDEO 表中 | 無 |
| 音頻文件 | 存儲在 Alarms、Audiobooks、Music、Notifications、Podcasts、Ringtones 目錄中,系統將這些文件添加到 MediaStore.Audio 表中 | 無 |
| 下載文件 | 存儲在 Download 目錄下,系統將這些文件添加到 MediaStore.Download 表中 | 低于 android10 的版本中不可用 |
| 文件集合 | 存在于 MediaStore.Files 表中 | 如果使用了分區存儲,這個集合只會顯示本應用創建的照片、視頻、音頻文件 |
開啟分區存儲權限,媒體的處理
如果應用使用分區存儲,您需要在應用的清單中聲明 ACCESS_MEDIA_LOCATION 權限,然后在運行時申請此權限。申請方法后面會講
編寫一個相冊
關于android11版本MANAGE_EXTERNAL_STORAGE權限
android10的版本是不能訪問所有文件的,可能google也意識到這是不合理的,所以在android11的版本上重新支持了所有文件的訪問
在android11的系統版本上,如果想掃描應用的所有文件,那么可以聲明MANAGE_EXTERNAL_STORAGE權限
MANAGE_EXTERNAL_STORAGE權限需要使用Intent進行權限申請,會跳轉到一個系統頁面確認權限
需要說明的是:這種方式可以訪問共享存儲中的文件,但是不可以訪問專屬存儲目錄中的文件(Android/data)
如下方法可以判斷是否擁有MANAGE_EXTERNAL_STORAGE權限
Environment.isExternalStorageManager()聲明權限方式如下:
其它
權限方面
-
使用使用共享存儲空間訪問其它應用創建的應用需要申請存儲權限,自己應用本次安裝創建的文件不需要申請權限。
-
如果應用target版本大于 9,那么我們僅應該在<=9 的版本中進行權限申請,可以通過如下配置設置:
maxSdkVersion
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"android:maxSdkVersion="28" />- 如果應用使用了存儲兼容功能,那么仍然需要訪問存儲權限
存儲兼容指的就是我們準備升級android10但是暫時不想使用分區存儲
開啟使用存儲兼容只需要在 manifest 中 application 標簽聲明如下配置即可:
android:requestLegacyExternalStorage="true"切換媒體文件待處理狀態
如果應用操作可能非常耗時(例如寫入文件),那么在我們操作文件期間應該避免讓其他應用有處理文件的機會。我們可以通過將 ContentValue.put(MediaStore.Audio.Media.IS_PENDING, 1) 標記的值設為 1 來獲取此獨占訪問權限。這樣就只有我們的的應用可以操作該文件,直到我們的應用將 IS_PENDING 的值改回 0。
照片中的位置信息
相冊中的照片可能會包含敏感信息,例如位置信息,這個信息默認是不允許用戶進行查看的,如果想查看需要申請 ACCESS_MEDIA_LOCATION權限
關注公眾號學習更多知識
總結
以上是生活随笔為你收集整理的【android】关于android10-11存储的一些知识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: The Podfile (Podfile
- 下一篇: http上传文件原理