기기에서 여러 사용자를 지원하는 경우 앱에서는 이 사용자들을 개별적으로 인식해야합니다.
일부 앱은 싱글톤으로 실행되는 일부 구성요소를 포함해야 하며 어떤 사용자의 요청이든 수락할 수 있습니다. 현재 시스템 앱에서만 이 기능을 사용할 수 있습니다.
이 기능의 특징은 다음과 같습니다.
- 리소스를 절약합니다.
- 사용자 간에 하나 이상의 공유 리소스를 조정합니다.
- 단일 서버 연결을 사용하여 네트워크 오버헤드를 줄입니다.
아래의 다이어그램은 여러 사용자와 관련된 권한 흐름을 보여줍니다.
싱글톤 구성요소 사용 설정
앱을 싱글톤으로 식별하려면 Android 매니페스트에서 android:singleUser=”true”
를 서비스, 받는 사람 또는 공급자에 추가합니다.
시스템은 사용자 0으로만 실행 중인 프로세스에서 이 구성요소를 인스턴스화합니다. 공급자 또는 서비스에 연결하거나 받는 사람에게 브로드캐스트하려는 모든 사용자의 모든 요청은 사용자 0의 프로세스로 라우팅됩니다. 앱의 유일한 구성요소인 경우 앱 인스턴스는 하나만 실행됩니다.
패키지의 활동은 각 사용자의 개별 프로세스에서 사용자의 UID 범위에 속하는 UID(예: 1010034)를 사용하여 시작됩니다.
사용자와 상호작용
권한 설정
다음 권한은 필수입니다.
INTERACT_ACROSS_USERS (signature|system) INTERACT_ACROSS_USERS_FULL (signature)
API 사용
다음 API를 사용하여 앱에서 여러 사용자를 인식하도록 합니다.
- 수신되는 바인더 호출에서 사용자 핸들을 추출합니다.
-
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()
을 사용하여 전체 앱을 사용 중지할 수도 있습니다.