Tworzenie aplikacji rozpoznawanych przez wielu użytkowników

Jeśli urządzenie obsługuje wielu użytkowników, aplikacje na urządzeniu muszą być uświadamianie tego charakterystycznego użytkownika.

Niektóre aplikacje muszą mieć komponenty, które działają jako singleton i mogą akceptować od dowolnego użytkownika. Obecnie z tej funkcji mogą korzystać tylko aplikacje systemowe.

Ten obiekt:

  • Oszczędza zasoby
  • Kontroluje co najmniej jeden udostępniony zasób różnym użytkownikom
  • Zmniejsza obciążenie sieci dzięki użyciu pojedynczego połączenia z serwerem

Poniższy diagram przedstawia przepływ uprawnień przez wielu użytkowników.

Przepływ uprawnień wielu użytkowników

Rysunek 1. Uprawnienia wielu użytkowników

Włączanie komponentu singleton

Aby oznaczyć aplikację jako singleton, dodaj do swojej usługi atrybut android:singleUser="true", odbiornika lub dostawcy w pliku manifestu Androida.

System utworzy instancję tego komponentu w procesie uruchomionym jako użytkownik 0. Wszelkie prośby o połączenie z danym dostawcą lub usługą albo nadanie tego nadawcy przez wszyscy użytkownicy zostaną przekierowani do procesu na koncie użytkownika 0. Jeśli jest to jedyny komponent aplikacji, uruchomi się tylko jedno wystąpienie aplikacji.

Aktywności z Twojego pakietu będą nadal uruchamiane w osobnym procesie każdego użytkownika, przy czym identyfikator UID należy do zakresu UID tego użytkownika (np. 1010034).

Interakcja z użytkownikami

Ustaw uprawnienia

Te uprawnienia są wymagane

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

Interfejsy API związane z zatrudnianiem

Użyj poniższych interfejsów API, aby poinformować aplikacje o wielu użytkownikach.

  1. Wyodrębnij nick użytkownika z przychodzących połączeń Binder:
    • int userHandle = UserHandle.getCallingUserId()
  2. Używaj nowych, chronionych interfejsów API do uruchamiania usług, działań lub transmisji na określonych danych użytkownik:
    • Context.startActivityAsUser(Intent, UserHandle)
    • Context.bindServiceAsUser(Intent, …, UserHandle)
    • Context.sendBroadcastAsUser(Intent, … , UserHandle)
    • Context.startServiceAsUser(Intent, …, UserHandle)
    . UserHandle może być użytkownikiem bezpośrednim lub jednym z uchwytów specjalnych: UserHandle.CURRENT lub UserHandle.ALL. CURRENT oznacza konto użytkownika, który znajduje się obecnie na pierwszym planie. Używaj ALL, gdy chcesz wyślij komunikat do wszystkich użytkowników.
  3. Komunikacja z komponentami we własnej aplikacji: (INTERACT_ACROSS_USERS) Za pomocą komponentów w innych aplikacjach: (INTERACT_ACROSS_USERS_FULL)
  4. Może być konieczne utworzenie komponentów serwera proxy, które będą działać w procesie użytkownika i które i otwórz komponent singleUser na koncie użytkownika 0.
  5. Wyślij zapytanie do użytkowników i ich nicków za pomocą nowej usługi systemowej UserManager:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle) – numer niepochodzący z recyklingu, który odpowiada nickowi użytkownika.
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() – zwraca kolekcję profili własnych i profili zarządzanych (jeśli istnieją).
  6. Zarejestruj się, aby nasłuchiwać konkretnych lub wszystkich użytkowników oraz wywołań zwrotnych z włączonymi nowymi interfejsami API ContentObserver, PackageMonitor i BroadcastReceiver, które zapewniają dodatkowe informacje o użytkowniku, który spowodował wywołanie zwrotne.

Usługi w wielu użytkownikach lub profilach

Nie wszystkie usługi muszą uruchamiać instancję u innego użytkownika lub w profilu służbowym. Jeśli Twoja usługa systemowa musi działać tylko jako użytkownik 0, wyłącz komponenty usługi, gdy działa w imieniu innych użytkowników, i pomagają zachować zasoby. Poniższy przykład pokazuje, jak można to zrobić we wpisie usługi pkt.:

// 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);
}

W przykładzie można też użyć parametru PackageManager.setApplicationEnabledSetting(), aby wyłączyć całą aplikację.