Android 15 Beta版本釋出!開發者如何應對新的版本限制?

前言

Android 15 於近日發布了 Beta版
新版本稱作 VanillaIceCream 香草冰淇淋

以下是roadmap:

其中詳細日程可參考:官網

Android 15上所有應用會影響
軟體包行為修改
  • 在class ApplicationInfo
    過去存在一個名為FLAG_STOPPED的標籤
    其行為是指目前是否app為停止狀態
    過去停止狀態的判定為 用戶強制停止應用程式時被設定,應用程式會保持此狀態。

  • 另一方便要讓系統判定app離開停止狀態的話
    過去可以透過使用者點擊開啟app、或一些互動視窗打開app可以改變狀態

    ↪ 這邊是官方原文
    directly launching the app or indirectly interacting with the app.
    (through the sharesheet or a widget, selecting the app as live wallpaper, etc.)
    指出android14可透過使用者點擊開啟app一些互動視窗間接打開
    其中舉的例子有sharesheetwidget選擇當作壁紙等等

  • 對比最新Android 15 系統中的 FLAG_STOPPED 有以下修改與擴充。
    1. 現在當系統判定為 FLAG_STOPPED時會停止所有pending intents的操作
    2. 當系統發現離開 FLSG_STOPPED時 會發送ACTION_BOOT_COMPLETED廣播
      官方指出可讓開發者透過此廣播恢復pending intent.

    ↪ 這邊是官方原文說明15對FLAG_STOPPED判定的調整:
    Apps should only be removed from the stopped state through direct or indirect user action.
    也就是說只有 直接或非直接的動作 會改變被系統判定為停止狀態

  • 從上述可以理解出對此狀態判定更嚴格了

    ↪ 不過上述原文看起來沒有明確指出何謂indirect user action.
    後續有遇到可參考

  • 另外可以透過 Application StartInfo.wasForceStopped() 方法判斷上述狀態。
支援16 KB page sizes
  • 官方針對RAM運用的策略做優化
    過去android只支援4 KB memory page sizes
    現在提升到16 KB page sizes
    並預計明年上到Google Play(15上已有,但不確定是不是到時候會強制16KB編譯的app ✨)
    將page size提升主要是為了優化ram密集型的工作,使其用起來更有效率
    不過這是針對軟體的優化
    主要是針對未來製造商陸續研發出更大、更高效能的ram時app能順利運行且具有兼容性
    page size 是用來表示記憶體裡面的操作單位,通常是2的次方,如:2KB、4KB、8KB等。

  • app開發者影響:
    ↪ 若有使用Ndk編譯、直接或間接使用到SDK編譯可能會需要重新配置16 KB page sizes的app



    短期內專案應該不太受影響
    未來等正式上線Google play 可能會遇到16 KB page sizes 相關問題


✅ 遇到兼容問題可以參考官網調整編譯方式

  • 判別是不是會受到影響可透過android studioAPK Analyzer來判斷編譯的是否用到native code(或指令反編譯去看)
    ↪ 把apk拖到android studio 內
    ↪ 查看lib資料夾是否出現任意.so檔(全稱shared object)
    若出現則表示你的appnative code編譯出來的
    沒出lib 或 .so 則代表可能native code

✅ 官方指出有用到native code則需要rebuild app to 16KB device.

這邊有幾種初判斷參考:
↪ 使用到任何C/C++ (native) code,通常是加入NDK相關,或JNI等等。
↪ 使用的任何第三方庫用到任意native labraries。
↪ 使用任意第三方的builder若使用任意native libraries。

  • 下圖是16 KB page sizes這項功能優化後
    對系統效能的提升
新增 Private space功能

此功能為新增一個隱藏app的空間或類似應用鎖
需輸入密碼才能打開存取應用
不過官方目前上面提示有bug

實測模擬器也找不到該功能
不過官方有提到該功能會限制app可見性
Because apps in the private space have restricted visibility,
後面可以用的時候可再看看自己的app放進去會不會有問題
如:不確定像是QueryAllPackagesPermission`的功能會不會跟預期不同
到時候可再試試

最小Target SDK 改為 24
  • 跟上版android 14類似,一樣是為了避免用太舊的api鑽一些漏洞
    android 15上 target需要大於24才能安裝
    裝不了會顯示INSTALL_FAILED_DEPRECATED_SDK_VERSION
    一樣可以用下列指令 安裝不符合規定的apk

    adb install --bypass-low-target-sdk-block FILENAME.apk
    

UI/UX調整

UI/UX調整
  • 移除開發者選項中的predictive back animations
    並且讓開發者可在app中設置

    <application
        ...
        android:enableOnBackInvokedCallback="true"
        ... >
    ...
    </application>
    

    ✅ 看看predictive back animations是什麼 :參考

棄用

日常淘汰部份api: 參考api棄用

以Android 15為目標的應用會影響
foreground services相關調整
  • 禁止在BOOT_COMPLETED廣播時啟動以下foreground service
    • dataSync
    • camera
    • mediaPlayback
    • phoneCall
    • mediaProjection
    • microphone

↪ 若強行啟動會拋ForegroundServiceStartNotAllowedException

  • 針對dataSync的終極審判
    ↪ dataSync的service現在每24hr內只能跑6hr,時間到了系統會呼叫Service.onTimeout(int, int)
    此時必需在收到timeout幾秒內呼叫Service.stopSelf()
    ↪ 若時間到了沒有呼叫stopSelf,則出現錯誤
    A foreground service of ##fgs_type did not stop within its timeout: ##component_name.
    ↪ 當系統呼叫Service.onTimeout(int, int)則該service不再被認為是foreground service
    ↪ 在目前beta2版本拋出的錯誤視為ANR,但在後續會改成exception.
    ↪ 上述限制為所有dataSync service共同遵守,如:24hr內已經執行4hr dataSync,則接下來其他dataSync只能執行2hr ↪ 或者官方推薦遷移成其他方式:替代方案

  • 新增forground service type:mediaProcessing
    ↪ 此type跟上面dataSync有相同的規則
    mediaProcessing的service現在每24hr內只能跑6hr,時間到了系統會呼叫Service.onTimeout(int, int)
    此時必需在收到timeout幾秒內呼叫Service.stopSelf()
    ↪ 當系統呼叫Service.onTimeout(int, int)則該service不再被認為是foreground service
    ↪ 官方提供的替代方案與上方dataSync不同:替代方案

  • 上述type要reset timer 文件中是提到
    用戶把app移到前景才會reset


  • 也可嘗試使用special case

    • 點此查看
    • 不過官方會需要提供說明並經過審核才能上架
限制透過持有SYSTEM_ALERT_WINDOW來啟動foreground service的限制
  • 之前透過SYSTEM_ALERT_WINDOW來啟動foreground service 即使app是在背景也可以work
    現在需加一個步驟:需透過TYPE_APPLICATION_OVERLAY起動一個overlay window且需要是可見的
    ↪ 若未達成上述新需求則拋ForegroundServiceStartNotAllowedException.
勿擾模式行為變更
  • Target sdk Android 15 以上的app不再支援設置勿擾模式Do Not Disturb (DND)global statepolicy
    ↪ 影響到之前透過setInterruptionFilter(INTERRUPTION_FILTER_ALL)做設置的app
針對OpenJDK 17的改變
  • Android 15針對此調整了api使用方式,有用到可以再注意
    使用以下function format 字串時新增exception
    • String.format(String, Object[])
    • String.format(Locale, String, Object[])
    • Formatter.format(String, Object[])
    • Formatter.format(Locale, String, Object[])

↪ 當誤用$0的時候會拋出 IllegalFormatArgumentIndexException: Illegal format argument index = 0

  //work
  val formattedString = String.format("Name: %1$s, Age: %2$d", name, age);
  //exception
  val formattedString = String.format("Name: %0$s, Age: %1$d", name, age);
  • 針對此issue 調整Random class 現在Random.ints()不會返回跟Random.nextInt()相同的值 所以現在不應該預期兩者是==
    • Random.ints(long)
    • Random.ints(long, int, int)
    • Random.ints(int, int)
    • Random.ints()
更安全的後台啟動Activity
  • 從 Android 10 起後台 activity 啟動就受到限制,而 Android 15 透過添加其他控制,來防止惡意後台應用程式將其他應用程式帶到前台。
  • 現在新增一種flag能設定,背景activity無法打開另一個app的activity

    <application android:allowCrossUidActivitySwitchFromBelow="false" >
    

    實際修改為:要打開的activity跟stack最上層 app UID不匹配的話則無法打開 ↪ 用來防止app打開另一個不同的app

  • 其他針對後台啟動activity的限縮
    • 現在PendingIntent預設關掉背景啟動activity(block background activity launches)
使用者體驗UI改善
  • 此調整針對使用者體驗調整,此處大概描述下:
    • Edge-to-edge enforcement:邊到邊強制執行,android 15上會對畫面直邊緣強制內縮 不過有提到使用material 3不會受此影響,實測使用material 3的app確實與原本UI一至

      其他UI如有可能受影響可注意


      ↪ 上方第三個圖為使用windowInsets.getInsets之類的去做調整後
      或者可以使用material 3

    • elegantTextHeight attribute defaults to true:預設elegantTextHeight屬性為true

    • Stable configuration:針對configuration相關的行為調整,可能影響螢幕轉向、system bar尺寸的判斷相關
      直接點此看
    • Locale-aware default line height for EditText:根據不同語言來調整edittext的高度可能變不同

      ✅ 可再看看如果變動後是否可接受
      如要取消可以直接把 useLocalePreferredLineHeightForMinimum attribute 設為 false
    • TextView width changes for complex letter shapes:預設文字的寬度指派規則有所調整
      使得複雜的文字有更多空間
      ✅ 若想停用/啟用可直接設定attribute setShiftDrawingOffsetForStartOverhang
  • 其他UI/UX細節直接參考這邊比較完整:點此
Camera and media新增限制
  • 若要請求音頻焦點 (audio focus)現在必需是top app 或是audio-related foreground service否則返回 AUDIOFOCUS_REQUEST_FAILED
  • 目前會被判定是audio-related foreground service有:
    • mediaPlayback
    • camera
    • microphone
    • phoneCall
      ✅ 學習音頻焦點 (audio focus) 直接點此看
Updated non-SDK restrictions
  • 日常版本更新都有的:直接點此看
    非SDK:涵蓋範圍內的 Java 的方法。此類介面是 SDK 的內部實作細節,可能隨時會被修改,且不對開發者另行通知。

You might also enjoy