Android 13 新特性及適配指南

2022-10-24 18:00:50

Android 13(API 33)2022年8月15日 正式釋出(釋出時間較往年早了一些),正式版Release原始碼也於當日被推播到AOSP Android開源專案。

截止到筆者撰寫這篇文章時,國內部分應用軟體開發廠商已逐步接到手機廠商(華米OV等)的新版本適配要求。當前,對於Android應用開發者來說,Android 13 的軟體相容適配已需提上工作日程。

為了貼合這篇文章的標題,本篇文章結合Android Developer官方檔案,圍繞Android13適配點Android13新特性兩個方面進行詳細說明。

適配點:

  • 細分媒體許可權:
    READ_EXTERNAL_STORAGE 細分為IAMGES、VIDEO、AUDIO許可權
    若設定 targetSdk>=33 則此項必需適配!
  • WebView調整:
    廢棄setAppCacheEnabledsetForceDark方法;
    若設定 targetSdk>=33 則此項必需適配!
  • 靜態廣播註冊:
    註冊靜態廣播時,需設定對其他應用的可見性
    若設定 targetSdk>=33 則此項必需適配!
  • 通知許可權:
    新增執行時通知許可權:POST_NOTIFICATIONS
    若設定 targetSdk>=33 則此項必需適配!
  • Wi-Fi :
    新增 NEARBY_WIFI_DEVICES 執行時許可權
    若設定 targetSdk>=33 則此項必需適配!
  • 身體感測器後臺許可權:
    新增 BODY_SENSORS_BACKGROUND 執行時許可權
    若設定 targetSdk>=33 則此項必需適配!
  • 剪下板內容隱藏:
    新增內容隱藏API
    根據業務需求,選擇性適配!
  • 非 SDK 介面的限制
    若設定 targetSdk>=33 則此項必需適配!

新特性:

  • 前臺服務管理器:
    系統新增前臺服務管理器
    系統新特性無需適配!

一、細分媒體許可權

從Android 13開始,以Android13(API 33+)為目標平臺的應用,系統新增執行時許可權READ_MEDIA_IAMGESREAD_MEDIA_VIDEOREAD_MEDIA_AUDIO 替代原有的READ_EXTERNAL_STORAGE許可權。

許可權 許可權說明
READ_MEDIA_IAMGES 圖片許可權
READ_MEDIA_VIDEO 視訊許可權
READ_MEDIA_AUDIO 音訊許可權

當應用升級到targetSdk>=33時:

  • 已授權READ_EXTERNAL_STORAGE許可權的應用:系統將自動賦予對應的細化許可權。
  • 未授權仍請求READ_EXTERNAL_STORAGE許可權:親測系統將不會授予任何許可權。

細分媒體許可權動態申請彈窗樣式:

  • 如果同時請求 READ_MEDIA_IMAGESREAD_MEDIA_VIDEO 許可權,系統將會提示如下許可權彈窗:
  • 如果請求 READ_MEDIA_AUDIO 許可權,系統將提示如下彈窗:

官方參考:
Android Developer 細分媒體許可權:
https://developer.android.google.cn/about/versions/13/behavior-changes-13

二、WebView

從Android 13開始,以Android13(API 33+)為目標平臺的應用,WebView存在以下方法與API調整:

  • WebSettings.setAppCacheEnabled() 方法廢棄
  • WebSettings.setForceDark() 方法廢棄

2.1 setAppCacheEnabled 廢棄

WebView 95+版本不再支援 setAppCacheEnabled

Chrome 85+版本不再支援AppCache

2.2 setForceDark 廢棄

從Android 13開始以Android13(API 33+)為目標平臺的應用,系統會根據應用的主題屬性isLightTheme,自動設定WebView的淺色或深色主題樣式(系統會根據 isLightTheme 來設定 prefers-color-scheme)。同時,開發者Webview設定主題樣式相關API WebSettings.setForceDark() 方法將被廢棄。
基於以上更改:

  • 若開發者仍需自定義Webview主題顏色,可以使用:
    WebSettings.setAlgorithmicDarkeningAllowed()WebSettingsCompat.setAlgorithmicDarkeningAllowed()方法。
  • 若開發者仍然使用WebSettings.setForceDark()系統將提示錯誤:
W/cr_WebSettings: setForceDark() is a no-op in an app with targetSdkVersion>=T

官方參考:
Android Developer 靜態廣播註冊官方介紹:
https://developer.android.google.cn/about/versions/13/behavior-changes-13

三、靜態廣播註冊

從Android 13開始,以Android13(API 33+)為目標平臺的應用,註冊靜態廣播時,需設定對其他應用的可見性

  • 若對其他應用可見,廣播註冊時設定:Context.RECEIVER_EXPORTED
  • 若僅應用內使用,廣播註冊時設定:Context.RECEIVER_NOT_EXPORTED
private void registerTestReceiver() {
    IntentFilter filter = new IntentFilter();
    filter.addAction("com.xiaxl.test.action");
    // api >= 33
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        // 跨應用間使用
        MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
        // 應用內使用
        //MainActivity.this.registerReceiver(mTestReceiver, filter, Context.RECEIVER_EXPORTED);
    }
    // api <= 32
    else {
        MainActivity.this.registerReceiver(mTestReceiver, filter);
    }
}

官方參考:
Android Developer 靜態廣播註冊官方介紹:
https://developer.android.google.cn/about/versions/13/features#java

四、通知許可權

Android 13 引入了一種新的執行時通知許可權:POST_NOTIFICATIONS
POST_NOTIFICATIONS 許可權級別被定義為dangerous 開發者使用該許可權時需動態申請,等待使用者主動授權:

  • 對於以Android13(API 33+)為目標平臺的應用
    在顯示Android通知欄時,一方面需要在AndroidManifest中宣告 android.permission.POST_NOTIFICATION,另一方面程式碼中需動態申請該通知欄許可權。
<!-- AndroidManifest許可權宣告 -->
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xiaxl.test">
	
    <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
</manifest>


// Java程式碼動態申請POST_NOTIFICATIONS許可權
if (Build.VERSION.SDK_INT >= 33) {
    int checkPermission =
            ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.POST_NOTIFICATIONS);
    if (checkPermission != PackageManager.PERMISSION_GRANTED) {
        //動態申請
        ActivityCompat.requestPermissions(MainActivity.this, new String[]{
                Manifest.permission.POST_NOTIFICATIONS}, PERMISSION_REQUEST_CODE);
    } else {
        //showRecordNotification();
    }
} else {
    //showRecordNotification();
}

POST_NOTIFICATIONS 動態授權申請彈窗如下圖所示:

  • 對於以Android12(API 32-)為目標平臺的應用
    對於以API 32-為目標平臺的應用,執行在Android13及以上裝置中時,當應用第一次顯示通知時,系統會自動彈出以下提示框,要求使用者動態授權

官方參考:
Android Developer 通知執行時許可權官方介紹:
https://developer.android.google.cn/guide/topics/ui/notifiers/notification-permission

五、Wi-Fi 許可權

從Android 13開始,Android系統新增了NEARBY_WIFI_DEVICES許可權,將原有的ACCESS_FINE_LOCATION許可權 與 Wi-Fi能力使用進行了區分(避免早先開發者使用Wi-Fi能力時,需要請求使用者位置許可權,從而引起使用者的歧義)。

從Android 13開始,開發者只要不通過Wi-Fi推導使用者的物理位置將無需再請求 ACCESS_FINE_LOCATION 許可權,同時官方總結了新增許可權NEARBY_WIFI_DEVICES的如下使用場景:

官方參考:
Android Developer NEARBY_WIFI_DEVICES:
https://developer.android.google.cn/reference/android/Manifest.permission

六、剪下板內容隱藏

從Android 13(API 33)開始,Android剪下板新增了一項新API
Android 13(API 33)開始,使用者可以選擇使用API PersistableBundle#(ClipDescription.EXTRA_IS_SENSITIVE, true)隱藏要複製到剪下板的使用者賬戶、密碼登敏感資訊。

相關API使用舉例如下:

private void addData2Clipboard() {
    ClipboardManager clipboardManager = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
    ClipData clipData = ClipData.newPlainText("111111", "我是密碼");
    ClipDescription description = clipData.getDescription();
    // 隱私內容:剪下板加密
    PersistableBundle persistableBundle = new PersistableBundle();
    if (Build.VERSION.SDK_INT >= 33) {
        persistableBundle.putBoolean(ClipDescription.EXTRA_IS_SENSITIVE, true);
    } else {
        persistableBundle.putBoolean("android.content.extra.IS_SENSITIVE", true);
    }
    description.setExtras(persistableBundle);
    // 剪下板新增加密內容
    clipboardManager.setPrimaryClip(clipData);
}

不使用新API使用新API隱藏敏感資訊,剪下板前後對比如下所示:

七、身體感測器後臺許可權

從Android 13開始,以Android13(API 33+)為目標平臺的應用,在後臺存取身體感測器(例如心率、體溫和血氧飽和度)時,除了需要請求現有的 BODY_SENSORS 許可權外,還需要請求 BODY_SENSORS_BACKGROUND 許可權。

官方參考:
Android Developer BODY_SENSORS_BACKGROUND:
https://developer.android.google.cn/reference/android/Manifest.permission

八、非 SDK 介面限制

官方從 Android 9(API 級別 28)開始,逐步開始對應用使用的非 SDK 介面實施了限制。
如果你的APP通過參照非 SDK 介面或嘗試使用反射或 JNI 來獲取控制程式碼,這些限制就會起作用。官方給出的解釋是為了提升使用者體驗、降低應用崩潰風險

8.1、非SDK介面檢測工具

官方給出了一個檢測工具,下載地址:veridex
https://android.googlesource.com/platform/prebuilts/runtime/+archive/master/appcompat.tar.gz

veridex使用方法:

appcompat.sh --dex-file=apk.apk

8.2、blacklist、greylist、greylist-max-o、greylist-max-p含義

以上截圖中,blacklist、greylist、greylist-max-o、greylist-max-p含義如下:

  • blacklist 黑名單:禁止使用的非SDK介面,執行時直接Crash(因此必須解決)
  • greylist 灰名單:即當前版本仍能使用的非SDK介面,但在下一版本中可能變成被限制的非SDK介面
  • greylist-max-o: 在targetSDK<=O中能使用,但是在targetSDK>=P中被禁止使用的非SDK介面
  • greylist-max-p: 在targetSDK<=P中能使用,但是在targetSDK>=Q中被禁止使用的非SDK介面

官方參考:
Android Developer 非SDK介面限制:
https://developer.android.google.cn/guide/app-compatibility/restrictions-non-sdk-interfaces

九、前臺服務管理器

從Android 13(API 33)開始,Android通知欄中新增了一項新特性
使用者可以選擇在通知欄中通過「前臺服務管理器」,對「正在執行的前臺服務」進行停止操作。

參考

Android Developer:Andoid13
https://developer.android.google.cn/about/versions/13

AOSP:Android13版本說明
https://source.android.google.cn/docs/setup/start/android-13-release

GoogleSource:Android13_r3
https://android.googlesource.com/platform/build/+/refs/tags/android-13.0.0_r4

= THE END =

文章首發於公眾號」CODING技術小館「,如果文章對您有幫助,歡迎關注我的公眾號。