為了讓用戶更好地控制自己的文件,并限制文件混亂情況添诉,Android Q 更改了應用訪問設備外部存儲空間中文件的方式嬉探。Android Q 用更精細的媒體特定權限替換了 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 權限,并且無需特定權限霸奕,應用即可訪問自己在外部存儲設備上的文件帮毁。這些變更會影響您的應用在外部存儲設備中保存和訪問文件的方式实苞。
本指南介紹了如何更新應用,以使其可以繼續(xù)共享烈疚、訪問和更新保存在外部存儲設備上的文件黔牵,還提供了兼容性注意事項,并說明了如何激活此行為變更爷肝。
針對應用私有文件的隔離存儲沙盒
Android Q 在外部存儲設備中為每個應用提供了一個“隔離存儲沙盒”(例如 /sdcard)猾浦。任何其他應用都無法直接訪問您應用的沙盒文件陆错。由于文件是您應用的私有文件,因此您不再需要任何權限即可在外部存儲設備中訪問和保存自己的文件金赦。此變更可讓您更輕松地保證用戶文件的隱私性音瓷,并有助于減少應用所需的權限數(shù)量。
如果用戶卸載了您的應用夹抗,系統(tǒng)就會清理隔離存儲沙盒中的文件
在外部存儲設備中存儲文件的最佳位置是Context.getExternalFilesDir()
返回的位置绳慎,因為此位置的行為方式在所有 Android 版本中都保持一致。使用此方法時漠烧,請在媒體環(huán)境中傳遞與您要創(chuàng)建或打開的文件類型對應的文件杏愤。例如,要訪問或保存應用私有圖片已脓,請調用 Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
声邦。
媒體文件的共享集合
應用創(chuàng)建了屬于相應用戶的文件,并且希望在卸載該應用時保留此用戶摆舟,則將這些文件保存到某個通用媒體集合(也稱為“共享集合”)中。共享集合包括:照片和視頻邓了、音樂和下載內容
查看其他應用的文件所需的權限
您的應用無需請求任何權限即可在這些共享集合中創(chuàng)建和修改自己的文件恨诱。但是,如果您的應用需要創(chuàng)建和修改其他應用已創(chuàng)建的文件骗炉,則必須先請求相應的權限:
訪問照片和視頻共享集合中其他應用的文件時照宝,需要READ_MEDIA_IMAGES
或 READ_MEDIA_VIDEO
權限(具體取決于您的應用需要訪問的文件類型)。
訪問音樂共享集合中其他應用的文件時句葵,需要 READ_MEDIA_AUDIO
權限厕鹃。
訪問共享集合
在請求必要的權限后,您的應用會使用 MediaStore API 訪問這些集合:
對于照片和視頻共享集合乍丈,請使用 MediaStore.Images 或 MediaStore.Video剂碴。
對于音樂共享集合,請使用 MediaStore.Audio轻专。
對于下載內容共享集合忆矛,請使用 MediaStore.Downloads。
對于 Android Q 上新安裝的應用请垛,對 getExternalStoragePublicDirectory() 的調用僅會提供對應用存儲在其隔離存儲沙盒中的文件的訪問權限催训。要始終擁有對其他應用的文件的訪問權限,請更新應用的邏輯以改用 MediaStore宗收。
保留您的應用在共享集合中的文件
默認情況下漫拭,當用戶卸載您的應用時,Android Q 會清理您保存到沙盒中的文件混稽。要在卸載應用時保留這些文件采驻,請使用存儲訪問框架审胚,或將文件保存到共享集合中。
要保留共享集合中的文件挑宠,請在相關的 MediaStore
集合中新插入一行菲盾,并用以下方法填充此行對應的列:
- 至少應為
DISPLAY_NAME
和MIME_TYPE
列提供值。 - (可選)您可以使用
PRIMARY_DIRECTORY
和SECONDARY_DIRECTORY
列來影響文件在磁盤上的存儲位置各淀。 - 保留
DATA
列不定義懒鉴。這樣一來,平臺便可以靈活地將文件保留在沙盒之外碎浇。
插入此行后临谱,您可以使用 ContentResolver.openFileDescriptor()
之類的 API 讀取新建文件的數(shù)據(jù)或向其中寫入數(shù)據(jù)。
但是奴璃,如果用戶稍后重新安裝了您的應用悉默,該應用將無法訪問這些文件,除非它執(zhí)行以下操作之一:
- 請求對集合的相應權限苟穆。
- 從存儲訪問框架向用戶發(fā)送請求抄课。
這種情況類似于一個應用嘗試訪問另一個應用的文件的情況
照片的特別注意事項
Android Q 新增了多項增強功能,讓用戶可以更好地控制在外部存儲設備中訪問照片的方式雳旅。
訪問照片中的位置信息
一些照片在其 Exif 元數(shù)據(jù)中包含位置信息跟磨,以便用戶查看照片的拍攝地點。由于此位置信息很敏感攒盈,因此默認情況下 Android Q 會對該信息進行遮蓋