targetSdkVersion 升級到29、30文件處理

android12要來了,很多老app還在29以下,該文章就是講述升級到29、30關於文件的處理。

在總結多種情況之前,我們再次確認下目前有哪些存儲目錄
  • 私有存儲 (Private Storage) : 每個應用在都擁有自己的私有目錄,其它應用看不到,彼此也無法訪問到該目錄。
  • 內部存儲私有目錄 (/data/data/packageName) ;
  • 外部存儲私有目錄 (/sdcard/Android/data/packageName);
  • 共享存儲 (Shared Storage) : 存儲其他應用可訪問文件, 包含媒體文件、文檔文件以及其他文件,對應設備DCIM、Pictures、Alarms、Music、Notifications、Podcasts、Ringtones、Movies、Download等目錄。
  • 外部存儲:Environment.getExternalStorageDirectory()獲取sdcard下的任意文件夾,在SDK29以上已經過期、失效。
Android版本迭代變化

在29版本後,只能操作本身內部存儲私有目錄、外部存儲私有目錄、共享存儲,但是依然可以通過android:requestLegacyExternalStorage="true"來設置(在AndroidManifest.xml中的application添加該配置),不啓用分區存儲,一切照舊。
但是30版本以後,就強制性的只能操作規定的目錄,這個時候依然有個兼容配置設置,android:preserveLegacyExternalStorage="true"(在AndroidManifest.xml中的application添加該配置),這個配置使得手機appSdk30版本以下,更新appSdk30版本以後,依然不啓用分區存儲,一切照舊。

那麼我簡單總結多種情況和解決方式:
  • targetSdkVersion = 28,運行後正常讀寫所有文件,如果不是必須的需求並且是新創建的項目的話,建議把文件按照規範存儲在外部存儲私有目錄 (/sdcard/Android/data/packageName)
  • targetSdkVersion = 29,targetSdkVersion 由 低版本 修改到 29,覆蓋安裝,運行後正常讀寫。
  • targetSdkVersion = 29,卸載舊應用,重新安裝新應用,如果讀寫外部存儲,程序崩潰 (open failed: EACCES (Permission denied))
  • targetSdkVersion = 29,添加android:requestLegacyExternalStorage="true"(不啓用分區存儲),讀寫正常不報錯
  • targetSdkVersion = 30,targetSdkVersion 由 低版本 修改到 30,覆蓋安裝,讀寫報錯,程序崩潰 (open failed: EACCES (Permission denied))
  • targetSdkVersion = 30,targetSdkVersion 由 低版本 修改到 30,覆蓋安裝,增加 android:preserveLegacyExternalStorage="true",讀寫正常不報錯
  • targetSdkVersion = 30,卸載舊應用,重新安裝新應用,不管設置任何配置,如果讀寫外部存儲,程序崩潰 (open failed: EACCES (Permission denied))
如果我app緩存文件存儲在外部存儲,那麼如何處理升級到30並且遷移文件呢?
  • 客戶app有重要文件在外部存儲
  • 客戶app要升級sdk到30
  • 要考慮新客戶安裝app

所以最終是設置android:preserveLegacyExternalStorage="true",所有目錄按照外部存儲私有目錄來進行讀寫操作,判斷外部存儲如果可以操作文件並且存在需要遷移的文件夾,先複製過來,並且需要增加一個全局緩存標記已經進行遷移成功。
如果用到數據庫切記先遷移文件後再初始化數據庫

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章