
隨著時間的推移,Android 已經發展到支持各種存儲設備類型和功能。所有版本的 Android 都支持具有傳統存儲的設備,包括便攜式和模擬存儲。便攜式存儲可以由物理介質提供,如 SD 卡或 USB,用於臨時數據傳輸/文件存儲。物理媒體可能會在設備上保留很長時間,但不會綁定到設備上,並且可能會被移除。 SD 卡從 Android 1.0 開始就可以作為便攜式存儲使用; Android 6.0 添加了 USB 支持。模擬存儲是通過模擬層公開一部分內部存儲來提供的,並且從 Android 3.0 開始就可用。
從 Android 6.0 開始,Android 支持adoptable storage ,它由物理介質提供,如 SD 卡或 USB,經過加密和格式化,表現得像內部存儲。可採用的存儲可以存儲所有類型的應用程序數據。
權限
對外部存儲的訪問受到各種 Android 權限的保護。從 Android 1.0 開始,寫訪問受到WRITE_EXTERNAL_STORAGE
權限的保護。從 Android 4.1 開始,讀取訪問受到READ_EXTERNAL_STORAGE
權限的保護。
從Android 4.4開始,外部存儲設備上的文件的所有者、組和模式現在根據目錄結構進行合成。這使應用程序能夠在外部存儲上管理其特定於包的目錄,而無需它們擁有廣泛的WRITE_EXTERNAL_STORAGE
權限。例如,包名為com.example.foo
的應用程序現在可以在沒有權限的情況下自由訪問外部存儲設備上的Android/data/com.example.foo/
。這些綜合權限是通過將原始存儲設備包裝在 FUSE 守護進程中來實現的。
從 Android 10 開始,以 Android 9 及更低版本為目標平台的應用默認使用傳統存儲,並且可以選擇使用獨立存儲。針對 Android 10 且默認使用隔離存儲的應用可以暫時選擇退出。使用控制存儲模型的清單屬性requestLegacyExternalStorage
來更改默認狀態。
由於READ_EXTERNAL_STORAGE
和WRITE_EXTERNAL_STORAGE
權限都是軟限制的,如果安裝程序沒有將應用列入白名單,則該權限僅控制對聽覺和視覺收藏的訪問,而無法訪問 SD 卡。即使應用程序請求傳統存儲,這也適用。有關硬限制和軟限制的更多信息,請參閱Android 10 中的硬限制和軟限制。
如果安裝程序將權限列入白名單,則在傳統模式下運行的應用程序將獲得非隔離權限行為。該權限控制 SD 卡訪問以及音頻和視頻收藏。當應用程序以 Android 9 或更低版本為目標並且未選擇加入獨立存儲,或者它以 Android 10 為目標並選擇退出時,就會發生這種情況。
白名單狀態只能在安裝時指定,在安裝應用程序之前不能更改。
有關設置READ_EXTERNAL_STORAGE
權限的更多信息,請參閱PackageInstaller.SessionParams類中的setWhitelistedRestrictedPermissions()
。
Android 13 引入了精細的媒體權限,以支持應用訪問其他應用創建的媒體文件。應用程序必須請求粒度媒體權限中列出的一項或多項粒度媒體權限,而不是READ_EXTERNAL_STORAGE
權限。
運行時權限
Android 6.0 引入了一種新的運行時權限模型,其中應用程序在運行時需要時請求功能。由於新模型包含READ/WRITE_EXTERNAL_STORAGE
權限,因此平台需要動態授予存儲訪問權限,而無需終止或重啟已運行的應用程序。它通過維護所有已安裝存儲設備的三個不同視圖來實現此目的:
-
/mnt/runtime/default
顯示給沒有特殊存儲權限的應用程序,以及adbd
和其他系統組件所在的根命名空間。 -
/mnt/runtime/read
顯示給具有READ_EXTERNAL_STORAGE
的應用程序(為 Android 10 設置LEGACY_STORAGE
) -
/mnt/runtime/write
顯示給具有WRITE_EXTERNAL_STORAGE
的應用程序
在 Zygote fork 時,我們為每個正在運行的應用程序創建一個掛載命名空間,並將適當的初始視圖綁定掛載到位。稍後,當授予運行時權限時, vold
會跳轉到已經運行的應用程序的掛載命名空間,並將升級後的視圖綁定掛載到位。請注意,權限降級始終會導致應用程序被終止。
用於實現此功能的setns()
功能至少需要 Linux 3.8,但補丁已成功反向移植到 Linux 3.4。 PermissionsHostTest
CTS 測試可用於驗證正確的內核行為。