應用程式休眠

如果應用程式指定的是 Android 11 (API 級別 30) 以上版本,而使用者已經數個月未和應用程式互動,系統便會把應用程式設為「休眠」狀態。系統會針對儲存空間進行最佳化 (而非以效能為優先考量),並且會保護使用者資料。這個系統行為的結果類似於使用者從系統設定手動強制停止應用程式。

休眠的影響

如表 1. 所示,休眠的影響需視應用程式指定的 SDK 版本和應用程式執行裝置而定。

表 1. 休眠對應用程式的影響
指定 SDK 版本 裝置特性 休眠影響
Android 12 以上版本 執行 Android 12 以上版本

系統會重設應用程式的執行階段權限。這項操作的效果等同於使用者在系統設定中檢視權限,並將應用程式的存取層級變更為「拒絕」

應用程式無法在背景執行工作或發送快訊。

應用程式無法接收推播通知,即使是透過 Firebase 雲端通訊傳送的高優先順序訊息也不例外。

系統會移除所有應用程式快取裡的檔案。

Android 11 執行 Android 11 系統會重設應用程式的執行階段權限。
Android 11 執行 Android 6.0 (API 級別 23) 至 Android 10 (API 級別 29),包含 Android 10,且由 Google Play 服務提供技術

系統會重設應用程式的執行階段權限。

這項行為自 2021 年 12 月開始生效。詳情請見此篇有關如何讓其他數十億台裝置都能自動重設權限的網誌文章

應用程式結束休眠後的系統行為

使用者下次和應用程式互動時,應用程式會結束休眠,並能再次建立工作、發送快訊和通知。

但系統不會對應用程式採取以下動作:

  1. 重新授予應用程式執行階段權限。

    使用者必須重新為應用程式授予這些權限。

  2. 重新安排應用程式休眠前曾排定的工作、快訊和通知。

    如果想用更輕鬆的方式支援這個工作流程,請用 WorkManager。您也可以在 ACTION_BOOT_COMPLETED 廣播接收器裡重新排程邏輯,系統會在應用程式結束休眠,並在裝置啟動時叫用這個廣播接收器。

應用程式使用情況

以下各章節將會說明應用程式使用情況的範例,以及幾種系統不認為屬於應用程式使用情況的操作範例。

應用程式使用情況範例

如果應用程式內的活動已恢復,系統會把這個事件視為使用者互動。因此,系統會延長應用程式進入休眠前所需的時間。

如果是 Android 11 以上版本,系統也會把以下行為視為使用者互動:

  • 使用者和小工具互動。
  • 使用者和通知互動,關閉通知不算在內。

請注意,休眠所說的應用程式使用情況不一定需要明確的使用者互動。只要有叫用套件的元件,就會視為應用程式使用情況。部分範例如下所示:

  • 應用程式所使用的服務或內容供應器受到相同裝置或 OS 上其他應用程式的限制,例如輸入法編輯器 (IME) 或密碼管理工具。
  • 位於從外部套件接收明確廣播的套件內的廣播接收器。

非範例

如果應用程式只呈現以下清單所述的行為,就會在幾個月後進入休眠:

系統休眠豁免權

在部分用途中,Android 會授予系統層級的應用程式休眠豁免權。如果應用程式屬於以下分類,就無需遵守應用程式使用情況標準,且不會進入休眠。

不會在啟動器顯示的應用程式
任何未在啟動器內具備有效捷徑設定方塊的應用程式。
工作資料夾應用程式
任何由使用者安裝在工作資料夾內的應用程式。請注意,如果這個應用程式也存在於個人資料夾,則只有工作資料夾的應用程式具有豁免權。
裝置政策控制器
控制本機裝置政策和裝置端系統應用程式的應用程式
電信業者特殊權限應用程式
任何有手機電信業者預先載入裝置,而且認定為執行契約服務義務所必要的應用程式,例如語音留言或客戶服務應用程式。
第三方安裝程式
可在必要時自動更新已安裝應用程式的第三方應用程式商店。

使用者休眠豁免權

如果您預期應用程式的核心用途會受到休眠影響,可以要求使用者提供應用程式休眠的豁免權。如果使用者預期應用程式主要會在背景執行,且甚至不需要使用者和應用程式互動,那麼這項豁免權就非常有用,這類應用程式功能的範例如下:

  • 定期回報家庭成員的所在位置,藉此保護家人安全。
  • 同步處理裝置和應用程式伺服器之間的資料。
  • 和電視等智慧型裝置通訊。
  • 和隨附裝置配對,例如手錶。

若要申請豁免權,請按照以下章節說明的步驟操作。

檢查使用者是否已經停用應用程式的休眠功能

如果想檢查使用者是否已經停用應用程式休眠功能,請用 getUnusedAppRestrictionsStatus() API。

如果想進一步瞭解如何在應用程式內使用此 API,請參閱本頁面的 API 程式碼範例

要求使用者停用應用程式的休眠功能

如果使用者尚未停用應用程式休眠功能,您可以向對方傳送要求。如要這樣做,請完成下列步驟:

  1. 顯示 UI,向使用者說明為什麼需要停用應用程式的休眠功能。
  2. 叫用 createManageUnusedAppRestrictionsIntent() API,如 API 程式碼範例所示。這個 API 會建立意圖,並會在設定中載入應用程式資訊畫面。然後使用者即可關閉應用程式的休眠功能。

    當傳送這項意圖時,請務必呼叫 startActivityForResult(),而不是 startActivity()

    如表 2. 所示,選項的位置和名稱需要看應用程式安裝裝置的特性而定:

    表 2. 停用應用程式休眠功能的選項
    裝置特性 顯示選項的頁面 要關閉的選項名稱
    執行 Android 13 以上版本 應用程式資訊 暫停未使用的應用程式活動
    執行 Android 12 應用程式資訊 移除權限並釋出空間
    執行 Android 11 「應用程式資訊」>「權限」 如果應用程式未使用,讓系統移除相關權限
    執行 Android 6.0 至 Android 10,包含 Android 10,且由 Google Play 服務提供技術 「Play 應用程式」>「選單」>「Play 安全防護」>「未使用應用程式權限」 如果應用程式未使用,讓系統移除相關權限

API 程式碼範例

這個程式碼範例將說明如何檢查應用程式是否以啟用休眠功能,以及要求使用者停用應用程式休眠功能的合宜方式。

Kotlin

val future: ListenableFuture<Int> =
    PackageManagerCompat.getUnusedAppRestrictionsStatus(context)
future.addListener({ onResult(future.get()) }, ContextCompat.getMainExecutor(context))

fun onResult(appRestrictionsStatus: Int) {
  when (appRestrictionsStatus) {
    // Couldn't fetch status. Check logs for details.
    ERROR -> { }

    // Restrictions don't apply to your app on this device.
    FEATURE_NOT_AVAILABLE -> { }

    // The user has disabled restrictions for your app.
    DISABLED -> { }

    // If the user doesn't start your app for a few months, the system will
    // place restrictions on it. See the API_* constants for details.
    API_30_BACKPORT, API_30, API_31 -> handleRestrictions(appRestrictionsStatus)
  }
}

fun handleRestrictions(appRestrictionsStatus: Int) {
  // If your app works primarily in the background, you can ask the user
  // to disable these restrictions. Check if you have already asked the
  // user to disable these restrictions. If not, you can show a message to
  // the user explaining why permission auto-reset or app hibernation should be
  // disabled. Then, redirect the user to the page in system settings where they
  // can disable the feature.
  val intent = IntentCompat.createManageUnusedAppRestrictionsIntent(context, packageName)

  // You must use startActivityForResult(), not startActivity(), even if
  // you don't use the result code returned in onActivityResult().
  startActivityForResult(intent, REQUEST_CODE)
}

舊版平台 API

作業系統內也有提供能和休眠功能互動的 API。不過,這個 API 僅適用於搭載 Android 11 以上版本的裝置,且無法處理向後移植到舊版 Android 的休眠功能。因此我們不建議使用這個 API。

如果為了相容性因素,您需要暫時繼續使用這個 API,請參考以下清單瞭解如何使用:

手動叫用休眠行為

如果想測試應用程式進入休眠狀態之後的行為,請按照以下步驟操作:

  1. (僅限 Android 12 以上版本) 在裝置上啟用休眠行為:

    adb shell device_config put app_hibernation app_hibernation_enabled true
    
  2. 設定系統進入休眠之前的預設等待時間。如此一來,就能在測試後還原預設等待時間:

    threshold=$(adb shell device_config get permissions \
      auto_revoke_unused_threshold_millis2)
    
  3. 減少系統等待時間。在以下範例中,系統已經修改完畢,應用程式會在停止和應用程式互動後短短一秒就進入休眠:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 1000
    
  4. 執行以下指令,等待測試裝置上的所有啟動時間播送作業完成:

    adb shell am wait-for-broadcast-idle
    

    廣播結束後,這個指令會回傳以下訊息:All broadcast queues are idle!

  5. 手動叫用應用程式休眠程序:

    adb shell cmd jobscheduler run -u 0 -f \
      com.google.android.permissioncontroller 2
    
  6. (僅限 Android 12 以上版本) 利用以下任一方法,確認應用程式已進入休眠狀態:

    • 觀察測試裝置是否顯示有通知說明未使用的應用程式已進入休眠。
    • 執行下列指令:

      adb shell cmd app_hibernation get-state PACKAGE-NAME
      
  7. 還原系統讓應用程式進入休眠之前的預設等待時間:

    adb shell device_config put permissions \
      auto_revoke_unused_threshold_millis2 $threshold