Android 10 Scoped Storage

以前在知乎看到一個問題: 爲何安卓系統的文件夾如此凌亂?

相信全部使用 Android 手機的用戶都會有這個疑問,打開自帶的文件管理器,簡直是一臉懵,十萬個爲何瞬間涌上心頭。數據庫

爲何會有這麼多文件夾?緩存

這些文件夾究竟是幹嗎的?app

這個 app 我明明已經卸載了,爲何還有殘留文件?設計

這些我看不懂的文件夾,到底能不能刪除?3d

萬一刪除後我手機變磚了怎麼辦?code

......cdn

在該問題下面,得票最高的回答中的第一句話直中要害:由於開發者不遵照規範視頻

今年發佈的 Android 10 引入了全新的 Scoped Storage,恰巧 Android Dev Simmit 上面也提到了相關的內容,我會結合大會中的講解以及我本身的理解,爲你們帶來 Scoped Storage 的介紹,以及做爲開發者來講,哪些變化是須要咱們注意的。沒關注的小夥伴記得關注訂閱鴨!若是以爲這些文章有點意思,記得分享轉發評論點贊鴨!blog

咱們回到最開頭的問題:爲何 Android 系統文件夾如此混亂?那是由於一旦 App 拿到了 WRITE_EXTERNAL_STORAGE 這個權限以後,就能夠在你的根目錄下面肆意妄爲的創建無數文件夾,根本緣由就是由於開發者不遵照規範。圖片

正確的規範

根據官方文檔上面的介紹,咱們有四種方式存儲數據和文件:內部存儲、外部存儲、SharedPreferences 和數據庫。今天咱們所關注的地方是上圖中畫紅框的兩個,即內部存儲和外部存儲。爲了防止有些同窗不清楚這兩個存儲的定義和目的,我幫你們簡單回顧一下。

內部存儲

內部存儲目錄主要分爲 4 部分,如上圖所示。但咱們經常使用的是文件目錄和緩存目錄,在 Kotlin 中能夠分別經過 filesDir 和 cacheDir 得到。

內部存儲用來存儲應用的私有文件,且一般是應用的功能相關的必要文件。

其餘應用(和用戶)不能訪問這些文件(除非擁有 Root 訪問權限)。如此一來,內部存儲便很是適合保存用戶無需直接訪問的內部應用數據。在文件系統中,系統會爲每一個應用提供私有目錄,您能夠在該目錄中整理應用所需的任何文件。當用戶卸載您的應用時,保存在內部存儲中的文件也將隨之移除。

同時內部存儲中的緩存目錄,幫咱們暫時保留而非永久存儲某些數據。系統會在內部存儲空間不足時,經過刪除這些緩存文件以回收空間。

內部存儲目錄對應的路徑爲 /data/data/<包名>/files

內部存儲緩存目錄對應的路徑爲 /data/data/<包名>/cache

外部存儲

存儲於外部存儲中的文件意味着,這些文件不是應用程序中功能運行時的必要文件,但從技術上講用戶和其餘應用程序均可以訪問這些文件,但它們沒法爲應用程序外部的用戶提供價值,此目錄可視爲內部存儲的補充方案。

外部存儲對應的路徑爲 /storage/Android/data/<包名>/files

根據上面的定義,不管內部存儲或者外部存儲都應該只保存與咱們本身的 App 有關聯的數據。例如使用內部存儲保存用戶信息、使用外部存儲保存只有本 App 才能打開的專門格式的文件。須要注意當用戶卸載 App 的時候,內部存儲和外部存儲都會被自動刪除。

針對用戶行爲產生的文件,例以下載的圖片、保存的視頻等。Google 要求咱們保存在系統公共目錄中,這樣別的 App 也能訪問到這些文件,例如 Pictures、Downloads。這裏咱們把用戶行爲產生的文件分爲兩大類:多媒體文件和其餘文件,官方推薦多媒體文件存放在系統中有專門的目錄:Music、Movies、Pictures等,其餘文件一概保存在下載目錄中:Downloads。

因此到這裏我想問一下那些 App 的開發者,大家在開發的時候有讀過官方文檔嗎?

前面我也講到了在 Android 10.0 以前,存儲文件須要獲取 WRITE_EXTERNAL_STORAGE 權限,獲得這個權限以後,App 就能夠經過 Environment.getExternalStorageDirectory() 在根目錄下面隨意建立文件了,可是(劃重點!)Android 10.0 以後就不行了,沒想到吧?

Android 10 Scoped Storage

在 Android 10 上面,上圖中的兩個訪問根目錄的 API 已經被棄用了。

執行上面這段建立文件夾的代碼根本不會其任何做用,這樣 App 就再也沒法肆意建立文件夾了。咱們以前說了存儲文件須要 WRITE_EXTERNAL_STORAGE 權限,在 Android Q 中咱們操做內部和外部存儲時,再也不須要聲明任何權限,能夠直接使用。

同時文檔中也明確規定了,多媒體文件須要經過 MediaStore API 訪問,其餘文件經過系統內置文件管理器訪問(Storage Access Framework API)。

由於官方意識到,大多數 App 申請了權限以後,僅是爲了操做外部存儲目錄,因此他們不須要這麼多的訪問空間,同時也正是由於以前的存儲權限邏輯,給了其餘 App 漏洞去肆意的亂建文件夾,從而引起了用戶數據泄漏。因此 Google 取消了外部存儲權限限制,同時也增長了公共目錄的訪問限制。

因此 Scoped Storage 的設計原則就是:更好的管理文件、保護 App 的數據、保護用戶的數據。

說了這麼多,咱們來看一下 Scoped Storage 具體有哪些修改,以及咱們須要注意的地方,這裏我列出來一些重要的點供你們參考:

固然 Scoped Storage 也不是立刻強制執行,Google 給了必定的緩衝期讓開發者們有時間充分適配。

  1. targetSDK = 29, 默認開啓 Scoped Storage, 但可經過在 manifest 裏添加 requestLegacyExternalStorage = true 關閉

  2. targetSDK < 29, 默認不開啓 Scoped Storage, 但可經過在 manifest 裏添加requestLegacyExternalStorage = false 打開

若是你所作的 App 屬於文件管理器或數據備份應用,你須要在 Google Play 提交申請信息,得到白名單權限以後才能夠訪問除本身應用之外的文件。

這是官方依據 Scoped Storage 所劃分的存儲區域訪問圖。目前 Scoped Storage 部份內容還在調整,因此在如今的 Android 10 上面並無強制執行,這一切調整會在 Android 下一個 Release 上完善並開啓。

關於 Scoped Storage 的信息很雜也很碎,可是咱們只須要關注兩點就行了:

  1. 多媒體文件須要使用 MediaStore API 訪問

  2. 其餘文件須要使用 Storage Access Framework API 訪問

因此咱們 App 以後的適配工做也須要密切關注這兩個 API 的變化和更新,因爲我尚未仔細閱讀這兩個 API 的文檔作適配,因此暫時也就沒有多餘的適配代碼分享給你們,避免錯誤使用誤導你們,若是有哪些同窗已經開始了適配工做,歡迎寫一篇文章並私信我,和你們一塊兒分享你在適配過程當中的心得。

明天的推送中,我會爲你們帶來關於【Fragment 的如今以及將來】的最近進展,沒關注的小夥伴記得關注我以及個人公衆號【Android丨Kotlin】鴨!若是以爲這些文章有點意思,記得分享轉發評論點贊鴨!!

我是 wanbo 你們加油!

相關文章
相關標籤/搜索