Android R如何訪問文件,修改文件,大家對R適配了嗎
心理分析:新Android特性一直都是面試官重點中的重點接下來,會問你他的原理 你是怎麼看。 它的優缺點。爲何比其餘的好。從原理層來解析。這纔是最難的。這篇文章 從原理層說明他們的區別android
更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS
免費獲取面試PDF合集git
Android R 愈來愈近了,最近 Google 又發佈了 Android R Beta 的第五個版本,眼瞅着這進度,在今年 R3 季度,Android R 就正式和用戶見面了,在此以前,開發者必然又是面臨的一波讓人頭疼的適配。github
瞭解新特性,首推應該去看官方文檔,官方已經給出了一份完整的新特性文檔,在發佈的這段時間,也一直在保持同步的更新。而做爲開發者,咱們更關心的是如何解決在咱們現有的 App 上,保證 Android R 的兼容性問題。面試
今天就給推薦給你們一份適配文檔,以開發者的角度列一份適配清單,在 Android R 還沒來以前,先了解須要作什麼,以及怎麼作,到時候纔不至於措手不及。ide
這份文檔的出自 OPPO 開放平臺,可能有人會以爲是 KPI 工程,可是你想一想這些廠商每一年耗巨資研發的旗艦機,用着最新的硬件,固然要搭配最新的系統,而用戶在旗艦機上的體驗,也是他們最關心的,因此每次 Android 發佈新系統,這些廠商也在推動本身應用市場上 App 的適配工做。ui
你只須要想一想他們作這件事的動機,就能知道這份文檔確定是花了心思的。文檔我看過一遍,從場景出發來分析緣由,並附上解決方案,頗有參考意義。google
文檔比較長,你們能夠先收藏,再跳躍閱讀看本身關注的點spa
本文檔是基於谷歌安卓R 的 beta1 版本的變動輸出的兼容性整改指導,若是後續 beta 版本有新的變動和新的特性,咱們也會刷新文檔的相關章節內容,請開發者持續關注。code
爲了讓用戶更好地控制本身的文件,並限制文件混亂的狀況,Android R 修改了 APP 訪問外部存儲中文件的方法。外部存儲的新特性被稱爲 Scoped Storage。視頻
Android R 仍然使用 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE 做爲面向用戶的存儲相關運行時權限,但如今即便獲取了這些權限,訪問外部存儲也受到了限制。APP 須要這些運行時權限的情景發生了變化,且各類狀況下外部存儲對 APP 的可見性也發生了變化。
在 Scoped Storage 新特性中,外部存儲空間被分爲兩部分:
● 公共目錄 :Downloads、Documents、Pictures 、DCIM、Movies、Music、Ringtones 等
● App-specific 目錄
Android R 規定了 APP 有兩種外部存儲空間視圖模式:Legacy View、Filtered View。
● Filtered View
● Legacy View
在 Android R 上,target SDK 大於或等於 29 的 APP 默認被賦予 Filtered View,反之則默認被賦予 Legacy View。APP 能夠在 AndroidManifest.xml
中設置新屬性 requestLegacyExternalStorage
來修改外部存儲空間視圖模式,true 爲 Legacy View,false 爲 Filtered View。可使用 Environment.isExternalStorageLegacy()
這個 API 來檢查 APP 的運行模式。APP 開啓 Filtered View 後,Scoped Storage 新特性對 APP 生效。
Android R 除了劃分外部存儲和定義 Filtered View,還在查詢、讀寫文件的一些細節上作了改進或限制,例如圖片文件中的地理位置信息將再也不默認提供、查詢 MediaProvider 得到的 DATA 字段再也不可靠、新增了文件的 Pending 狀態等等。這些細節的具體內容請參考適配方案章節。
Scoped Storage 對於 APP 訪問外部存儲方式、APP 數據存放以及 APP 間數據共享,都產生很大影響。請開發者注意如下的兼容性影響事項。
問題緣由: 直接使用自身 App-specific 目錄之外的路徑新建文件。
問題分析: 在 Android R 上,APP 只容許在自身 App-specific 目錄之內經過路徑生成的文件。
解決方案: APP 自身 App-specific 目錄下新建文件的方法與文件路徑,請參見 2.3.1;若是要在公共目錄下新建文件,使用 MediaStore 接口,請參見 2.3.2;若是要在任意目錄下新建文件,須要使用 SAF,請參見 2.3.3。
問題緣由 1: 直接使用路徑訪問公共目錄文件。
問題分析 1: 在 Android R 上,APP 默認只能訪問外部存儲設備上的 App-specific 目錄。
解決方法 1: 參見 2.3.2 和 2.3.3,使用 MediaStore 接口訪問公共目錄中的多媒體文件,或者使用 SAF 訪問公共目錄中的任意文件。注意:從 MediaStore 接口中查詢到的 DATA 字段將在 Android R 開始廢棄,不該該利用它來訪問文件或者判斷文件是否存在;從 MediaStore 接口或者 SAF 獲取到文件 Uri 後,請利用 Uri 打開 FD 或者輸入輸出流,而不要轉換成文件路徑去訪問。
問題緣由 2: 使用 MediaStore 接口訪問非多媒體文件。
問題分析 2: 在 Android R 上,使用 MediaStore 接口只能訪問公共目錄中的多媒體文件。
解決方法 2: 使用 SAF 向用戶申請文件或目錄的讀寫權限,請參見 2.3.3。
問題緣由: APP 將 App-specific 目錄中的私有文件分享給其餘 APP 時,使用了 file://
類型的 Uri。
問題分析: 在 Android R 上,因爲 App-specific 目錄中的文件是私有受保護的,其餘 APP 沒法經過文件路徑訪問。
解決方案: 參見 2.3.4,使用 FileProvider,將 content://
類型的 Uri 分享給其餘 APP。
問題緣由 1: 直接使用路徑訪問公共目錄文件。
問題分析 1: 同 2.2.2。
解決方案 1: 同 2.2.2,請使用正確的公共目錄文件訪問方式。
問題緣由 2: 使用 MediaStore 接口獲取公共目錄多媒體文件的 Uri 後,直接使用該 Uri 打開 OutputStream 或文件描述符。
問題分析 2: 在 Android R 上,修改公共目錄文件,須要用戶受權。
解決方案 2: 從 MediaStore 接口獲取公共目錄多媒體文件 Uri 後,打開 OutputStream 或 FD 時,注意 catch RecoverableSecurityException,而後向用戶申請該多媒體文件的刪改權限,請參見 2.3.2.6;使用 SAF 獲取到文件或目錄的 Uri 時,用戶已經受權讀寫,能夠直接使用,但要注意 Uri 權限的時效,請參見 2.3.3.6。
問題緣由: 將想要保留的文件保存在外部存儲的 App-specific 目錄下。
問題分析:在 Android R 上,卸載 APP 默認刪除 App-specific 目錄下的數據。
解決方案: APP 應該將想要保留的文件經過 MediaStore 接口保存到公共目錄下,請參見 2.3.2。默認狀況下,MediaStore 接口會將非媒體類文件保存到 Downloads 目錄下,推薦 APP 指定一級目錄爲 Documents。若是 APP 想要在卸載時保留 App-specific 目錄下的數據,要在 AndroidManifest.xml 中聲明 android:hasFragileUserData="true",這樣在 APP 卸載時就會有彈出框提示用戶是否保留應用數據。
問題緣由: 直接從圖片文件輸入流中解析地理位置數據。
問題分析: 因爲圖片的地理位置信息涉及用戶隱私,Android R 上默認不向 APP 提供該數據。
解決方案: 申請 ACCESS_MEDIA_LOCATION 權限,並使用 MediaStore.setRequireOriginal() 接口更新文件 Uri,請參見 2.3.5.1 。
問題緣由: Fota 升級後,APP 被卸載,從新安裝後沒法訪問到 APP 數據。
問題分析: Scoped Storage 新特性只對 Android R 上新安裝的 APP 生效。設備從 Android R 以前的版本升級到 Android R,已安裝的 APP 得到 Legacy View 視圖。這些 APP 若是直接經過路徑的方式將文件保存到了外部存儲上,例如外部存儲的根目錄,那麼 APP 被卸載後從新安裝,新的 APP 得到 Filtered View 視圖,沒法直接經過路徑訪問到舊數據,致使數據丟失。
解決方案: APP 應該修改保存文件的方式,再也不使用路徑的方式直接保存,而是採用 MediaStore 接口將文件保存到對應的公共目錄下。在 Fota 升級前,能夠將 APP 的用戶歷史數據經過 MediaStore 接口遷移到公共目錄下。此外,APP 應當改變訪問 App-specific 目錄之外的文件的方式,請使用 MediaStore 接口或者 SAF。
Android R Scoped Storage 新特性谷歌官方適配文檔:
https://developer.android.google.cn/preview/privacy/scoped-storage
OPPO 適配指導以下,分爲:訪問 APP 自身 App-specific 目錄文件、使用 MediaStore 訪問公共目錄、使用 SAF 訪問指定文件和目錄、分享 App-specific 目錄下文件和其餘細節適配。
無需任何權限,APP 便可直接使用文件路徑來讀寫自身 App-specific 目錄下的文件。獲取 App-specific 目錄路徑的接口以下表所示。
以下,以新建並寫入文件爲例。
final File[] dirs = getExternalFilesDirs("Documents"); File primaryDir = null; if (dirs != null && dirs.length > 0) { primaryDir = dirs[0]; } if (primaryDir == null) { return; } File newFile = new File(primaryDir.getAbsolutePath(), "MyTestDocument"); OutputStream fileOS = null; try { fileOS = new FileOutputStream(newFile); if (fileOS != null) { fileOS.write("file is created".getBytes(StandardCharsets.UTF_8)); fileOS.flush(); } } catch (IOException e) { LogUtil.log("create file fail"); } finally { try { if (fileOS != null) { fileOS.close(); } } catch (IOException e1) { LogUtil.log("close stream fail"); } }
APP 沒法直接訪問公共目錄下的文件。MediaStore 爲 APP 提供了訪問公共目錄下媒體文件的接口。APP 在有適當權限時,能夠經過 MediaStore 查詢到公共目錄文件的 Uri,而後經過 Uri 讀寫文件。
MediaStore 相關的 Google 官方文檔:
https://developer.android.google.cn/reference/android/provider/MediaStore
經過 MediaStore 提供的 Uri,使用 ContentResolver 的 insert 接口,將文件保存到公共目錄下。不一樣的 Uri,能夠保存到不一樣的公共目錄中
更多面試內容,面試專題,flutter視頻 全套,音視頻從0到高手開發。
關注GitHub:https://github.com/xiangjiana/Android-MS
免費獲取面試PDF合集