2025 年 3 月 27 日より、AOSP のビルドとコントリビューションには aosp-main
ではなく android-latest-release
を使用することをおすすめします。詳細については、AOSP の変更をご覧ください。
複数のユーザーを認識するアプリを構築する
コレクションでコンテンツを整理
必要に応じて、コンテンツの保存と分類を行います。
デバイスが複数のユーザーをサポートしている場合、アプリはそれぞれのユーザーを認識する必要があります。
アプリによっては、いくつかのコンポーネントをシングルトンとして実行して、どのユーザーからのリクエストも受け付けられるようにする必要があります。現在、この機能を使用できるのはシステムアプリだけです。
この機能により、以下が実現します。
- リソースを節約する
- ユーザー間で 1 つ以上の共有リソースの使用を調整する
- 単一のサーバー接続を使用してネットワークのオーバーヘッドを削減する
複数のユーザーをサポートしている場合の権限フローについて下の図をご覧ください。
図 1. 複数のユーザーをサポートしている場合の権限
シングルトン コンポーネントを有効にする
アプリをシングルトンとして指定するには、Android マニフェストのサービス、レシーバ、またはプロバイダに android:singleUser="true"
を追加します。
システムは、ユーザー 0 だけで実行されているプロセスで、そのコンポーネントをインスタンス化します。ユーザーからそのプロバイダまたはサービスに接続するリクエスト、またはそのレシーバにブロードキャストするリクエストは、ユーザー 0 のプロセスにルーティングされます。これがアプリ内の唯一のコンポーネントである場合、アプリのインスタンスが 1 つだけ実行されます。
パッケージ内のアクティビティは引き続き、各ユーザーの個別のプロセスで起動され、UID はそのユーザーの UID の範囲内(1010034 など)になります。
ユーザーとやり取りを行う
権限を設定する
以下の権限が必要になります。
INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)
API を使用する
次の API を使用して、アプリが複数のユーザーを認識できるようにします。
- 受信した Binder 呼び出しからユーザー ハンドルを抽出します。
int userHandle = UserHandle.getCallingUserId()
- 保護されている新しい API を使用して、特定のユーザーでサービス、アクティビティ、ブロードキャストを開始します。
Context.startActivityAsUser(Intent, UserHandle)
Context.bindServiceAsUser(Intent, …, UserHandle)
Context.sendBroadcastAsUser(Intent, … , UserHandle)
Context.startServiceAsUser(Intent, …, UserHandle)
UserHandle
は、明示的なユーザーか、特殊なハンドルのいずれか(UserHandle.CURRENT
または UserHandle.ALL
)になります。CURRENT
は、現在フォアグラウンドにあるユーザーを示します。すべてのユーザーにブロードキャストを送信する場合は、ALL
を使用します。
(INTERACT_ACROSS_USERS)
で同じアプリ内のコンポーネントと通信します。他のアプリのコンポーネントと通信するには (INTERACT_ACROSS_USERS_FULL)
を使用します。
- ユーザーのプロセスで実行されるプロキシ コンポーネントの作成が必要になる場合があります。このプロキシ コンポーネントは、ユーザー 0 の
singleUser
コンポーネントにアクセスします。
- 新しい
UserManager
システム サービスで、ユーザーとそのハンドルをクエリします。
UserManager.getUsers()
UserManager.getUserInfo()
UserManager.supportsMultipleUsers()
UserManager.getUserSerialNumber(int userHandle)
- ユーザー ハンドルに対応する、リサイクルされない数値です。
UserManager.getUserHandle(int serialNumber)
UserManager.getUserProfiles()
- 自己プロファイルと管理対象プロファイルのコレクションを返します(存在する場合)。
- コールバックの送信元ユーザーについての追加情報を提供する ContentObserver、PackageMonitor、BroadcastReceiver で新しい API を使用して、特定またはすべてのユーザー、およびコールバックをリッスンするように登録します。
複数のユーザーまたはプロファイルのサービス
すべてのサービスが、他のユーザーまたは仕事用プロファイルでインスタンスを実行する必要があるわけではありません。システム サービスをユーザー 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()
を使用してアプリ全体を無効にすることもできます。
このページのコンテンツやコードサンプルは、コンテンツ ライセンスに記載のライセンスに従います。Java および OpenJDK は Oracle および関連会社の商標または登録商標です。
最終更新日 2025-07-27 UTC。
[[["わかりやすい","easyToUnderstand","thumb-up"],["問題の解決に役立った","solvedMyProblem","thumb-up"],["その他","otherUp","thumb-up"]],[["必要な情報がない","missingTheInformationINeed","thumb-down"],["複雑すぎる / 手順が多すぎる","tooComplicatedTooManySteps","thumb-down"],["最新ではない","outOfDate","thumb-down"],["翻訳に関する問題","translationIssue","thumb-down"],["サンプル / コードに問題がある","samplesCodeIssue","thumb-down"],["その他","otherDown","thumb-down"]],["最終更新日 2025-07-27 UTC。"],[],[],null,["# Build multiuser-aware apps\n\nWhen a device supports [multiple users](/docs/devices/admin/multi-user), its apps must be\nmade aware of these distinct users.\n\nCertain apps need to have some components run as singletons and can accept\nrequests from any user. Only system apps can currently use this feature.\n\nThis facility:\n\n- Conserves resources\n- Arbitrates one or more shared resources across users\n- Reduces network overhead by using a single server connection\n\nSee the diagram below for a depiction of permissions flow with multiple users.\n\n\n**Figure 1.** Multiple users permissions\n\nEnable a singleton component\n----------------------------\n\nTo identify an app as a singleton, add `android:singleUser=\"true\"` to your service,\nreceiver, or provider in the Android manifest.\n\nThe system instantiates that component in the process running as user 0\nonly. Any requests to connect to that provider or service, or to broadcast to that receiver, from\nany user is routed to the process in user 0. If this is the only component in your app,\nonly one instance of your app runs.\n\nActivities in your package are still launched in a separate process for\neach user, with the UID being in the UID range for that user (such as 1010034).\n\nInteract with users\n-------------------\n\n### Set permissions\n\nThese permissions are required: \n\n```\nINTERACT_ACROSS_USERS (signature|system)\nINTERACT_ACROSS_USERS_FULL (signature)\n```\n\n### Employ APIs\n\nUse the following APIs to make apps aware of multiple users.\n\n1. Extract the user handle from incoming Binder calls:\n - `int userHandle = UserHandle.getCallingUserId()`\n2. Use new, protected APIs to start services, activities, broadcasts on a specific user:\n - `Context.startActivityAsUser(Intent, UserHandle)`\n - `Context.bindServiceAsUser(Intent, ..., UserHandle)`\n - `Context.sendBroadcastAsUser(Intent, ... , UserHandle)`\n - `Context.startServiceAsUser(Intent, ..., UserHandle)`\n\n `UserHandle` can be an explicit user or one of the special handles: `UserHandle.CURRENT` or `UserHandle.ALL`. `CURRENT` indicates the user that is currently in the foreground. Use `ALL` when you want to send a broadcast to all users.\n3. Communicate with components in your own app: `(INTERACT_ACROSS_USERS)` Or with components in other apps: `(INTERACT_ACROSS_USERS_FULL)`\n4. You might need to create proxy components that run in the user's process that then access the `singleUser` component in user 0.\n5. Query users and their handles with the new `UserManager` system service:\n - `UserManager.getUsers()`\n - `UserManager.getUserInfo()`\n - `UserManager.supportsMultipleUsers()`\n - `UserManager.getUserSerialNumber(int userHandle)` - a nonrecycled number that corresponds to a user handle.\n - `UserManager.getUserHandle(int serialNumber)`\n - `UserManager.getUserProfiles()` - returns the collection of self and managed profiles, if any.\n6. Register to listen to specific or all users and the callbacks with new APIs on ContentObserver, PackageMonitor, BroadcastReceiver that provide additional information about which user has caused the callback.\n\n### Services in multiple users or profiles\n\nNot all services need to run an instance in another user or work profile. If your system service\nonly needs to run as user 0, disable the service's components when running under other users to\nhelp preserve resources. The following example shows how you might do this at your service's entry\npoints: \n\n```\n// Add on all entry points such as boot_completed or other manifest-listed receivers and providers\nif (!UserManager.isSystemUser()) {\n // Disable the service\n ComponentName targetServiceName = new ComponentName(this, TargetService.class);\n context.getPackageManager().setComponentEnabledSetting(\n targetServiceName, COMPONENT_ENABLED_STATE_DISABLED, 0);\n}\n```\n\nThe example could also use `PackageManager.setApplicationEnabledSetting()` to disable\nthe entire app."]]