關於Android 10.0適配


Android Q Beta 剛出,按照慣例國內是半年內不用理睬Q的,但是OPPO的一封要求適配Q的郵件要求盡快完成相關適配,不然應用會被下架。
本文將從三個角度介紹Android Q的部分適配問題,也是大家開發適配過程中大概率會遇到的問題:

Q 行為變更:所有應用 (不管targetSdk是多少,對所有跑在Q設備上的應用均有影響)
Q 行為變更:以 Android Q 為目標平台的應用(targetSDK == Q 才有影響)
項目升級遇到的問題
至於Q的新功能及SDK,項目中並沒有涉及,故暫不介紹,只放出鏈接AndroidQ新API及功能。

https://developer.android.com/preview/features

Q行為變更:所有應用
用戶隱私權限變更

AndroidQ引入了大量更改和限制以增強對用戶隱私的保護。

官方文檔將這一部分內容獨立於Q 行為變更:所有應用來介紹,是因為這一部分內容龐大且重要,個人認為Q的最大更新就是用戶隱私權限變更。具體變更的權限如下:

權限;   受影響應用;   如何啟用(影響范圍)

 

 

 

存儲權限

訪問和共享外部存儲設備中的文件的應用

adb shell sm set-isolated-storage on(下文詳述)

定位權限

在后台時請求訪問用戶位置信息的應用

這種權限策略在 Android Q 上始終處於啟用狀態

從后台啟動 Activity

不需要用戶互動就啟動 Activity 的應用

關閉允許系統執行后台活動開發者選項即可啟用限制

設備標識符(deviceId)

訪問設備序列號或 IMEI 的應用

在搭載 Android Q 的設備上安裝應用

無線掃描權限

使用 WLAN API 和 Bluetooth API 的應用

以 Android Q 為目標平台

 

 

 因為從后台啟動Activity權限和無線掃描權限兩種權限的變更影響較少。本文不作詳述,如有涉及請查閱官方文檔。

https://developer.android.com/preview/privacy/background-activity-starts

從后台啟動Activity權限變更僅針對與用戶毫無交互就啟動一個Activity的情況,(比如微信登陸授權)

以下會着重介紹存儲權限,定位權限和設備標識符三種權限的變更與適配。

存儲權限

Android Q 在外部存儲設備中為每個應用提供了一個“隔離存儲沙盒”(例如 /sdcard)。任何其他應用都無法直接訪問您應用的沙盒文件。由於文件是您應用的私有文件,因此您不再需要任何權限即可在外部存儲設備中訪問和保存自己的文件。此變更可讓您更輕松地保證用戶文件的隱私性,並有助於減少應用所需的權限數量。

沙盒,簡單而言就是應用專屬文件夾,並且訪問這個文件夾無需權限。谷歌官方推薦應用在沙盒內存儲文件的地址為Context.getExternalFilesDir()下的文件夾。比如要存儲一張圖片,則應放在Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)中。

以下將按訪問的目標文件的地址介紹如何適配。

1. 訪問自己文件:Q中用更精細的媒體特定權限替換並取消了 READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE權限,並且無需特定權限,應用即可訪問自己沙盒中的文件。

2. 訪問系統媒體文件:Q中引入了一個新定義媒體文件的共享集合,如果要訪問沙盒外的媒體共享文件,比如照片,音樂,視頻等,需要申請新的媒體權限:READ_MEDIA_IMAGES,READ_MEDIA_VIDEO,READ_MEDIA_AUDIO,申請方法同原來的存儲權限。

3. 訪問系統下載文件:對於系統下載文件夾的訪問,暫時沒做限制,但是,要訪問其中其他應用的文件,必須允許用戶使用系統的文件選擇器應用來選擇文件。

4. 訪問其他應用沙盒文件:如果你的應用需要使用其他應用在沙盒內創建的文件,請點擊使用其他應用的文件,本文不做介紹。

所以請判斷當應用運行在Q平台上時,取消對READ_EXTERNAL_STORAGE 和 WRITE_EXTERNAL_STORAGE兩個權限的申請。並替換為新的媒體特定權限。

關於存儲權限的(如何啟用)影響范圍

模擬器

在Android Q Beat1中,谷歌暫未開放存儲權限的改動。我們需要使用adb命令

adb shell sm set-isolated-storage on
來開啟模擬器對於存儲權限的變更來進行適配。

真機

當滿足以下每個條件時,將開啟兼容模式,即不開啟Q設備中的存儲權限改動:

應用targetSDK<=P。
應用安裝在從 Android P 升級到 Android Q 的設備上。
但是當應用重新安裝(更新)時,不會重新開啟兼容模式,存儲權限改動將生效。

所以按官方文檔所說,無論targetSDK是否為Q,必須對應用進行存儲權限改動的適配。

在我的測試中,當targetSDK<=P,在Q Beat1版上申請兩個舊權限時會自動改成申請三個新權限,不會影響應用正常使用,但當targetSDK==Q時,申請舊權限將失敗並影響應用正常使用。

定位權限

為了讓用戶更好地控制應用對位置信息的訪問權限,Android Q 引入了新的位置權限 ACCESS_BACKGROUND_LOCATION。

與現有的 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION 權限不同,新權限僅會影響應用在后台運行時對位置信息的訪問權。除非應用的某個 Activity 可見或應用正在運行前台服務,否則應用將被視為在后台運行。

與iOS系統一樣,Q中也加入了后台位置權限ACCESS_BACKGROUND_LOCATION,如果應用需要在后台時也獲得用戶位置(比如滴滴),就需要動態申請ACCESS_BACKGROUND_LOCATION權限。

當然如果不需要的話,應用就無需任何改動,且谷歌會按照應用的targetSDK作出不同處理:

targetSDK <= P 應用如果請求了ACCESS_FINE_LOCATION 或 ACCESS_COARSE_LOCATION權限,Q設備會自動幫你申請ACCESS_BACKGROUND_LOCATION權限。

設備唯一標識符

從 Android Q 開始,應用必須具有 READ_PRIVILEGED_PHONE_STATE 簽名權限才能訪問設備的不可重置標識符(包含 IMEI 和序列號)。

許多用例不需要不可重置的設備標識符。如果您的應用沒有該權限,但您仍嘗試查詢標識符的相關信息。會返回空值或報錯。

設備唯一標識符需要特別注意,原來的READ_PHONE_STATE權限已經不能獲得IMEI和序列號,如果想在Q設備上通過

((TelephonyManager) getActivity() .getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId()
獲得設備ID,會返回空值(targetSDK<=P)或者報錯(targetSDK==Q)。且官方所說的READ_PRIVILEGED_PHONE_STATE權限只提供給系統app,所以這個方法算是廢了。

谷歌官方給予了設備唯一ID最佳做法,但是此方法給出的ID可變,可以按照具體需求具體解決。

本文給出一個不變和基本不重復的UUID方法。

public static String getUUID() {

String serial = null;

String m_szDevIDShort = "35" +
Build.BOARD.length() % 10 + Build.BRAND.length() % 10 +

Build.CPU_ABI.length() % 10 + Build.DEVICE.length() % 10 +

Build.DISPLAY.length() % 10 + Build.HOST.length() % 10 +

Build.ID.length() % 10 + Build.MANUFACTURER.length() % 10 +

Build.MODEL.length() % 10 + Build.PRODUCT.length() % 10 +

Build.TAGS.length() % 10 + Build.TYPE.length() % 10 +

Build.USER.length() % 10; //13 位

try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
serial = android.os.Build.getSerial();
} else {
serial = Build.SERIAL;
}
//API>=9 使用serial號
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
} catch (Exception exception) {
//serial需要一個初始化
serial = "serial"; // 隨便一個初始化
}
//使用硬件信息拼湊出來的15位號碼
return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();
}
雖然由於唯一標識符權限的更改會導致android.os.Build.getSerial()返回unknown,但是由於m_szDevIDShort是由硬件信息拼出來的,所以仍然保證了UUID的唯一性和持久性。

經測試上述方法完全相同的手機有可能重復,網上還有其他方案比如androidID,但是androidID可能由於機型原因返回null,所以個人任務兩種方法半斤八兩。設備ID的獲取一個版本比一個版本艱難,如果有好的方法歡迎指出。

minSDK警告

在 Android Q 中,當用戶首次運行以 Android 6.0(API 級別 23)以下的版本為目標平台的任何應用時,Android平台會向用戶發出警告。

如果此應用要求用戶授予權限,則系統會先向用戶提供調整應用權限的機會,然后才會允許此應用首次運行。

谷歌要求運行在Q設備上的應用targetSDK>=23,不然會向用戶發出警告。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM