建構多使用者感知的應用程式

如果裝置支援多位使用者,其應用程式必須符合下列條件: 就能瞭解這些不同的使用者

某些應用程式需要將某些元件以單例模式執行,且可接受 要求存取權目前只有系統應用程式可以使用這項功能。

這類設施:

  • 節省資源
  • 在使用者之間封存一或多項共用資源
  • 使用單一伺服器連線,進而減少網路負擔

請見下圖說明多位使用者的權限流程。

多位使用者權限流程

圖 1. 多位使用者權限

啟用單例模式元件

如要將應用程式視為單例模式,請在服務中加入 android:singleUser="true"。 Android 資訊清單中的接收器或供應器

系統會在使用者 0 的執行程序中將該元件例項化 。連線至該供應商或服務,或向該接收器播送的任何要求,都來自 任何使用者都會轉送至使用者 0 的程序。如果這是應用程式中唯一的元件 應用程式的一個執行個體,只會執行一個。

系統仍會以獨立程序啟動套件中的活動 並選出 UID 位於該使用者的 UID 範圍 (例如 1010034)。

與使用者互動

設定權限

必須具備這些權限

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

使用 API

使用下列 API,讓應用程式知道多位使用者。

  1. 從傳入的 Binder 呼叫擷取使用者控制代碼:
    • int userHandle = UserHandle.getCallingUserId()
  2. 使用受保護的新 API,在特定的 使用者:
    • Context.startActivityAsUser(Intent, UserHandle)
    • Context.bindServiceAsUser(Intent, …, UserHandle)
    • Context.sendBroadcastAsUser(Intent, … , UserHandle)
    • Context.startServiceAsUser(Intent, …, UserHandle)
    ,瞭解如何調查及移除這項存取權。 UserHandle 可以是明確的使用者,也可以是下列其中一個特殊帳號: UserHandle.CURRENTUserHandle.ALLCURRENT 表示 目前位於前景的使用者。使用ALL即可 向所有使用者播送廣播訊息。
  3. 與應用程式中的元件通訊: (INTERACT_ACROSS_USERS) 或包含其他應用程式中的元件: (INTERACT_ACROSS_USERS_FULL)
  4. 您可能需要建立會在使用者的程序中運作的 Proxy 元件 然後在使用者 0 中存取 singleUser 元件。
  5. 使用新的 UserManager 系統服務查詢使用者及其控制代碼:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle) - 與使用者帳號代碼相對應的非回收編號。
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() - 傳回自己和受管理的設定檔的集合 (如果有的話)。
  6. 註冊即可監聽特定或所有使用者,以及使用新 API 的回呼 ContentObserver、PackageMonitor、BroadcastReceiver,提供額外 產生回呼的相關資訊。

多位使用者或設定檔中的服務

並非所有服務都需要在其他使用者或工作資料夾中執行執行個體。如果您的系統服務 只在使用者 0 下執行時,在其他使用者執行時停用服務的元件, 有助於保留資源以下範例顯示如何在服務項目中執行此操作 分數:

// Add on all entry points such as boot_completed or other manifest-listed receivers and providers
if (!UserManager.isSystemUser()) {
    // Disable the service
    ComponentName targetServiceName = new ComponentName(this, TargetService.class);
    context.getPackageManager().setComponentEnabledSetting(
        targetServiceName, COMPONENT_ENABLED_STATE_DISABLED, 0);
}

這個範例也可以使用 PackageManager.setApplicationEnabledSetting() 停用 整個應用程式