Zarządzanie wieloma użytkownikami

Z tego przewodnika dla programistów dowiesz się, jak kontroler zasad dotyczących urządzeń może zarządzać wieloma użytkownikami Androida na specjalnych urządzeniach.

Omówienie

Twój DPC może pomóc wielu osobom korzystać z jednego specjalnego urządzenia. Twój DPC działające na w pełni zarządzanym urządzeniu może tworzyć 2 typy użytkowników i nimi zarządzać:

  • Użytkownicy dodatkowi to użytkownicy Androida, którzy mają zapisane osobne aplikacje i dane między sesjami. Do zarządzania użytkownikiem służy komponent administratora. Ci użytkownicy są przydatne w przypadkach, gdy urządzenie zostanie odebrane na początku zmiany, na przykład dostawcom czy ochroniarzom.
  • Użytkownicy efemeryczni to użytkownicy pomocniczy, którzy są usuwani przez system, gdy użytkownik zatrzymuje się, wyłącza lub urządzenie uruchamia się ponownie. Ci użytkownicy przydają się w przypadkach, gdzie po zakończeniu sesji można usunąć dane, np. dostęp publiczny. kiosków internetowych.
.

Do zarządzania oddzielnym i dodatkowym urządzeniem możesz używać obecnej wersji DPC. użytkowników. Komponent administracyjny w DPC ustawia się jako administrator nowej dodatkowej usługi użytkowników podczas ich tworzenia.

Użytkownik główny i 2 użytkowników pomocniczych.
Rysunek 1. Użytkownicy główni i pomocni zarządzani przez administratorów z ten sam DPC
.

Administratorzy użytkownika dodatkowego muszą należeć do tego samego pakietu co administrator w pełni zarządzane urządzenie. Aby uprościć programowanie, zalecamy udostępnienie informacji o administratorze między urządzeniem a użytkownikami pomocniczymi.

Zarządzanie wieloma użytkownikami na specjalnych urządzeniach zwykle wymaga Androida 9.0, ale niektóre metody omówione w tym przewodniku dla programistów są dostępne starszych wersji Androida.

Użytkownicy dodatkowi

Użytkownicy dodatkowi mogą łączyć się z Wi-Fi i konfigurować nowe sieci. Jednak są one Nie mogą edytować ani usuwać sieci, nawet tych, które utworzyły.

Tworzenie użytkowników

DPC może utworzyć w tle dodatkowych użytkowników, a następnie ich przełączyć na pierwszy plan. Proces ten jest niemal taki sam zarówno w przypadku efemeryczną. Te kroki należy wdrożyć u administratorów w pełni urządzenie zarządzane i użytkownik dodatkowy:

  1. Zadzwoń pod numer DevicePolicyManager.createAndManageUser(). Aby utworzyć użytkownika tymczasowego, dołącz MAKE_USER_EPHEMERAL w argumencie flag.
  2. Zadzwoń do nas DevicePolicyManager.startUserInBackground() do uruchamia użytkownika w tle. Użytkownik zaczyna działać, ale chcesz aby dokończyć konfigurację, zanim przeniesiesz użytkownika na pierwszy plan i wyświetlisz go do osoby korzystającej z urządzenia.
  3. Na koncie administratora użytkownika dodatkowego wywołaj DevicePolicyManager.setAffiliationIds() do powiąż nowego użytkownika z użytkownikiem głównym. Zobacz Koordynacja DPC poniżej.
  4. Wróć do konta administratora w pełni zarządzanego urządzenia i zadzwoń DevicePolicyManager.switchUser(), aby przełączyć użytkownika na: na pierwszym planie.

Z przykładu poniżej dowiesz się, jak dodać krok 1 do DPC:

Kotlin

val dpm = getContext().getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager

// If possible, reuse an existing affiliation ID across the
// primary user and (later) the ephemeral user.
val identifiers = dpm.getAffiliationIds(adminName)
if (identifiers.isEmpty()) {
    identifiers.add(UUID.randomUUID().toString())
    dpm.setAffiliationIds(adminName, identifiers)
}

// Pass an affiliation ID to the ephemeral user in the admin extras.
val adminExtras = PersistableBundle()
adminExtras.putString(AFFILIATION_ID_KEY, identifiers.first())
// Include any other config for the new user here ...

// Create the ephemeral user, using this component as the admin.
try {
    val ephemeralUser = dpm.createAndManageUser(
            adminName,
            "tmp_user",
            adminName,
            adminExtras,
            DevicePolicyManager.MAKE_USER_EPHEMERAL or
                    DevicePolicyManager.SKIP_SETUP_WIZARD)

} catch (e: UserManager.UserOperationException) {
    if (e.userOperationResult ==
            UserManager.USER_OPERATION_ERROR_MAX_USERS) {
        // Find a way to free up users...
    }
}

Java

DevicePolicyManager dpm = (DevicePolicyManager)
    getContext().getSystemService(Context.DEVICE_POLICY_SERVICE);

// If possible, reuse an existing affiliation ID across the
// primary user and (later) the ephemeral user.
Set<String> identifiers = dpm.getAffiliationIds(adminName);
if (identifiers.isEmpty()) {
  identifiers.add(UUID.randomUUID().toString());
  dpm.setAffiliationIds(adminName, identifiers);
}

// Pass an affiliation ID to the ephemeral user in the admin extras.
PersistableBundle adminExtras = new PersistableBundle();
adminExtras.putString(AFFILIATION_ID_KEY, identifiers.iterator().next());
// Include any other config for the new user here ...

// Create the ephemeral user, using this component as the admin.
try {
  UserHandle ephemeralUser = dpm.createAndManageUser(
      adminName,
      "tmp_user",
      adminName,
      adminExtras,
      DevicePolicyManager.MAKE_USER_EPHEMERAL |
          DevicePolicyManager.SKIP_SETUP_WIZARD);

} catch (UserManager.UserOperationException e) {
  if (e.getUserOperationResult() ==
      UserManager.USER_OPERATION_ERROR_MAX_USERS) {
    // Find a way to free up users...
  }
}

Podczas tworzenia lub uruchamiania nowego konta użytkownika możesz sprawdzić przyczynę niepowodzenia przechwytując wyjątek UserOperationException i wywołując getUserOperationResult() Przekroczony limit użytkownika to typowe przyczyny niepowodzenia:

.

Utworzenie użytkownika może trochę potrwać. Jeśli często tworzysz konta użytkowników, możesz poprawić wrażenia użytkowników, przygotowując gotowych do użycia je w tle; Konieczne może być zachowanie równowagi między zaletami gotowego użytkownika a maksymalnym dozwolonej liczby użytkowników na urządzeniu.

Identyfikacja

Po utworzeniu nowego użytkownika należy odwołać się do niego za pomocą stałego numeru seryjnego numer. Nie zachowuj tych elementów (UserHandle), ponieważ system wykorzystuje je ponownie tworzyć i usuwać konta użytkowników. Zadzwoń, aby uzyskać numer seryjny UserManager.getSerialNumberForUser():

Kotlin

// After calling createAndManageUser() use a device-unique serial number
// (that isn’t recycled) to identify the new user.
secondaryUser?.let {
    val userManager = getContext().getSystemService(UserManager::class.java)
    val ephemeralUserId = userManager!!.getSerialNumberForUser(it)
    // Save the serial number to storage  ...
}

Java

// After calling createAndManageUser() use a device-unique serial number
// (that isn’t recycled) to identify the new user.
if (secondaryUser != null) {
  UserManager userManager = getContext().getSystemService(UserManager.class);
  long ephemeralUserId = userManager.getSerialNumberForUser(secondaryUser);
  // Save the serial number to storage  ...
}

Konfiguracja użytkownika

W zależności od potrzeb użytkowników możesz dostosować konfigurację dodatkowych użytkowników. Podczas wywoływania funkcji createAndManageUser() możesz uwzględnić te flagi:

SKIP_SETUP_WIZARD
Pomija korzystanie z kreatora konfiguracji dla nowego użytkownika, który sprawdza dostępność aktualizacji i je instaluje. prosi użytkownika o dodanie konta Google wraz z usługami Google, a następnie ustawia blokady ekranu. Może to zająć trochę czasu i może nie mieć zastosowania w niektórych przypadkach dla użytkowników, takich jak publiczne kioski internetowe.
LEAVE_ALL_SYSTEM_APPS_ENABLED
Wszystkie aplikacje systemowe będą włączone na koncie nowego użytkownika. Jeśli nie ustawisz tej flagi, Zawiera on jedynie minimalny zestaw aplikacji potrzebnych telefonowi zwykle jest to przeglądarka plików, aplikacja do wybierania numerów, kontakty i wiadomości SMS.

Przestrzegaj cyklu życia użytkownika

DPC (jeśli jest administratorem w pełni zarządzanego urządzenia) może przydać się do: możesz otrzymywać powiadomienia o zmianach użytkowników pomocniczych. Aby uruchamiać zadania dodatkowe po wprowadzeniu zmian, zastąp zastąpienie te metody wywołania zwrotnego w podklasie DeviceAdminReceiver DPC:

onUserStarted()
Wywoływane po uruchomieniu systemu przez użytkownika. Ten użytkownik może nadal konfigurować urządzenie lub działać w tle. Użytkownika możesz uzyskać w startedUser .
onUserSwitched()
Wywoływane po przełączeniu systemu na innego użytkownika. Nowego użytkownika możesz która działa na pierwszym planie z argumentu switchedUser.
onUserStopped()
Wywoływane po zatrzymaniu użytkownika przez system, ponieważ użytkownik się wylogował, a następnie przełączył się na nowego użytkownika (jeśli użytkownik jest tymczasowy) lub system DPC go zatrzymał. Możesz uzyskać użytkownika z argumentu stoppedUser.
onUserAdded()
Wywoływana, gdy system dodaje nowego użytkownika. Zazwyczaj użytkownicy dodatkowi nie skonfigurować pełną konfigurację, kiedy DPC otrzyma wywołanie zwrotne. Aby uzyskać informacje o użytkowniku, newUser argument.
onUserRemoved()
Wywoływana po usunięciu użytkownika przez system. Ponieważ konto użytkownika zostało już usunięte, nie możesz uzyskać dostępu do użytkownika reprezentowanego przez argument removedUser.

Aby wiedzieć, kiedy system przenosi użytkownika na pierwszy plan lub wysyła go na w tle, aplikacje mogą rejestrować odbiornik ACTION_USER_FOREGROUND i ACTION_USER_BACKGROUND transmisji.

Odkryj użytkowników

Aby pobrać wszystkich użytkowników pomocniczych, administrator w pełni zarządzanego urządzenia może zadzwonić do: DevicePolicyManager.getSecondaryUsers() Wyniki uwzględniania wszystkich użytkowników dodatkowych lub tymczasowych, utworzonych przez administratora. Dodatkowo wyniki wyszukiwania użytkowników dodatkowych (lub gościa), którzy mogą korzystać z urządzenia utworzone przez użytkowników. Wyniki nie obejmują profili służbowych, ponieważ nie są i innymi użytkownikami. Z przykładu poniżej dowiesz się, jak możesz używać tej metody:

Kotlin

// The device is stored for the night. Stop all running secondary users.
dpm.getSecondaryUsers(adminName).forEach {
    dpm.stopUser(adminName, it)
}

Java

// The device is stored for the night. Stop all running secondary users.
for (UserHandle user : dpm.getSecondaryUsers(adminName)) {
  dpm.stopUser(adminName, user);
}

Oto inne metody, które można wywołać, aby sprawdzić stan użytkowników dodatkowych:

DevicePolicyManager.isEphemeralUser()
Wywołaj tę metodę administratora użytkownika dodatkowego, aby sprawdzić, czy jest to użytkownik tymczasowy.
DevicePolicyManager.isAffiliatedUser()
Wywołaj tę metodę administratora konta użytkownika dodatkowego, aby sprawdzić, czy ten użytkownik powiązane z głównym użytkownikiem. Więcej informacji o powiązaniu znajdziesz na stronie DPC poniżej.

Zarządzanie użytkownikami

Jeśli chcesz w pełni zarządzać cyklem życia użytkownika, możesz wywołać interfejsy API: szczegółowa kontrola nad tym, kiedy i w jaki sposób urządzenie zmienia użytkowników. Na przykład: możesz usunąć konto użytkownika, jeśli urządzenie nie było używane od jakiegoś czasu lub możesz wysyłania niewysłanych zamówień na serwer przed zakończeniem pracy użytkownika.

Wyloguj

W Androidzie 9.0 dodaliśmy przycisk wylogowania do ekranu blokady, dzięki czemu osoba korzystająca z może zakończyć sesję. Po dotknięciu przycisku system zatrzymuje użytkownik dodatkowy, usuwa konto użytkownika, jeśli jest ono efemeryczne, a użytkownik główny powraca na pierwszy plan. Android ukrywa przycisk, gdy główny użytkownik znajduje się na ponieważ główny użytkownik nie może się wylogować.

Domyślnie Android nie wyświetla przycisku zakończenia sesji, ale administrator ( w pełni zarządzanym urządzeniu) mogą je włączyć, łącząc się DevicePolicyManager.setLogoutEnabled() W razie potrzeby potwierdź obecny stan przycisku, wywołaj DevicePolicyManager.isLogoutEnabled()

Administrator użytkownika dodatkowego może automatycznie wylogować użytkownika i wrócić do niego głównemu użytkownikowi. Najpierw sprawdź, czy główni i dodatkowi użytkownicy są stowarzyszony, a następnie zadzwoń pod numer DevicePolicyManager.logoutUser(). Jeśli wylogowany użytkownik jest użytkownikiem tymczasowym, system zatrzymuje się, a następnie usuwa użytkownika.

Przełącz użytkownika

Aby przełączyć się na innego użytkownika dodatkowego, administrator w pełni zarządzanego urządzenia może zadzwoń do: DevicePolicyManager.switchUser(). Dla wygody może przekazać użytkownikowi null, aby został głównym użytkownikiem.

Zatrzymywanie użytkownika

Aby zatrzymać użytkownika dodatkowego, DPC, które jest właścicielem w pełni zarządzanego urządzenia, może zadzwonić DevicePolicyManager.stopUser() Jeśli zatrzymany użytkownik to użytkownik zostaje zatrzymany, a następnie usunięty.

O ile to możliwe, zalecamy zatrzymanie użytkowników, aby uniknąć ograniczenia działania urządzenia z maksymalną liczbą aktywnych użytkowników.

Usuwanie użytkownika

Aby trwale usunąć użytkownika dodatkowego, DPC może wywołać jedną z tych czynności: DevicePolicyManager metody:

  • Administrator w pełni zarządzanego urządzenia może zadzwonić pod numer removeUser().
  • Administrator użytkownika dodatkowego może wywołać metodę wipeData().

System usuwa użytkowników tymczasowych, gdy są zalogowani, zatrzymani lub przełączeni z daleka.

Wyłącz domyślny interfejs użytkownika

Jeśli DPC udostępnia interfejs do zarządzania użytkownikami, możesz wyłączyć wbudowane aplikacje na Androida do wykorzystania przez wielu użytkowników. Aby to zrobić, zadzwoń pod numer DevicePolicyManager.setLogoutEnabled() i dodanie funkcji Ograniczenie DISALLOW_USER_SWITCH wyświetlane w następujący przykład:

Kotlin

// Explicitly disallow logging out using Android UI (disabled by default).
dpm.setLogoutEnabled(adminName, false)

// Disallow switching users in Android's UI. This DPC can still
// call switchUser() to manage users.
dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH)

Java

// Explicitly disallow logging out using Android UI (disabled by default).
dpm.setLogoutEnabled(adminName, false);

// Disallow switching users in Android's UI. This DPC can still
// call switchUser() to manage users.
dpm.addUserRestriction(adminName, UserManager.DISALLOW_USER_SWITCH);

Osoba używająca urządzenia nie może dodawać użytkowników pomocniczych, używając wbudowanego interfejsu Androida. bo administratorzy w pełni zarządzanych urządzeń automatycznie dodają Ograniczenie dotyczące użytkownika DISALLOW_ADD_USER.

Komunikaty dotyczące sesji

Gdy osoba używająca urządzenia przełącza się na nowego użytkownika, Android pokazuje panel, zaznacz przełącznik. Android wyświetla te komunikaty:

  • Komunikat rozpoczynania sesji użytkownika wyświetlany, gdy urządzenie przełącza się na pomocniczą głównego użytkownika.
  • Komunikat dotyczący sesji użytkownika wyświetlany, gdy urządzenie wraca do głównego użytkownika przez użytkownika dodatkowego.

System nie wyświetla komunikatów podczas przełączania się między 2 użytkownikami pomocniczymi.

Wiadomości mogą nie być odpowiednie we wszystkich sytuacjach, więc możesz zmienić treść tych wiadomości. Jeśli na przykład rozwiązanie używa tymczasowego użytkownika sesji, może to być odzwierciedlone w komunikatach takich jak: Zatrzymywanie przeglądarki sesja i usuwam dane osobowe...

System wyświetla wiadomość przez kilka sekund, więc każda wiadomość powinna być krótka, jasna. Aby dostosować wiadomości, administrator może zadzwonić metody DevicePolicyManager setStartUserSessionMessage() i setEndUserSessionMessage() zgodnie z następujący przykład:

Kotlin

// Short, easy-to-read messages shown at the start and end of a session.
// In your app, store these strings in a localizable resource.
internal val START_USER_SESSION_MESSAGE = "Starting guest session"
internal val END_USER_SESSION_MESSAGE = "Stopping & clearing data"

// ...
dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE)
dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE)

Java

// Short, easy-to-read messages shown at the start and end of a session.
// In your app, store these strings in a localizable resource.
private static final String START_USER_SESSION_MESSAGE = "Starting guest session";
private static final String END_USER_SESSION_MESSAGE = "Stopping & clearing data";

// ...
dpm.setStartUserSessionMessage(adminName, START_USER_SESSION_MESSAGE);
dpm.setEndUserSessionMessage(adminName, END_USER_SESSION_MESSAGE);

Przekaż null, aby usunąć swoje wiadomości i wrócić do ustawień domyślnych Androida wiadomości. Jeśli chcesz sprawdzić bieżący tekst wiadomości, zadzwoń pod getStartUserSessionMessage() lub getEndUserSessionMessage()

DPC powinien ustawić zlokalizowane komunikaty dla bieżącego języka użytkownika. Musisz również zaktualizować wiadomości, gdy zmiany języka użytkownika:

Kotlin

override fun onReceive(context: Context?, intent: Intent?) {
    // Added the <action android:name="android.intent.action.LOCALE_CHANGED" />
    // intent filter for our DeviceAdminReceiver subclass in the app manifest file.
    if (intent?.action === ACTION_LOCALE_CHANGED) {

        // Android's resources return a string suitable for the new locale.
        getManager(context).setStartUserSessionMessage(
                getWho(context),
                context?.getString(R.string.start_user_session_message))

        getManager(context).setEndUserSessionMessage(
                getWho(context),
                context?.getString(R.string.end_user_session_message))
    }
    super.onReceive(context, intent)
}

Java

public void onReceive(Context context, Intent intent) {
  // Added the <action android:name="android.intent.action.LOCALE_CHANGED" />
  // intent filter for our DeviceAdminReceiver subclass in the app manifest file.
  if (intent.getAction().equals(ACTION_LOCALE_CHANGED)) {

    // Android's resources return a string suitable for the new locale.
    getManager(context).setStartUserSessionMessage(
        getWho(context),
        context.getString(R.string.start_user_session_message));

    getManager(context).setEndUserSessionMessage(
        getWho(context),
        context.getString(R.string.end_user_session_message));
  }
  super.onReceive(context, intent);
}

Koordynacja DPC

Zarządzanie użytkownikami pomocniczymi zwykle wymaga 2 instancji DPC – jednej z na w pełni zarządzanym urządzeniu, a drugie jest właścicielem użytkownika dodatkowego. Podczas tworzenia nowego użytkownika, administrator w pełni zarządzanego urządzenia ustawi kolejną instancję jako administratora nowego użytkownika.

powiązani użytkownicy

Niektóre interfejsy API wymienione w tym przewodniku dla programistów działają tylko wtedy, gdy użytkownicy dodatkowi są stowarzyszone. Android wyłącza niektóre funkcje (na przykład logowania sieciowego) podczas dodawania nowych niepowiązanych użytkowników dodatkowych do urządzenia, należy jak najszybciej powiązać użytkowników. Zobacz przykład tutaj: Konfiguracja poniżej.

Konfiguracja

Skonfiguruj nowych użytkowników dodatkowych (z DPC, do którego należy konto użytkownika dodatkowego) przed i umożliwiać ludziom korzystanie z nich. Możesz to zrobić na stronie DeviceAdminReceiver.onEnabled() – wywołanie zwrotne. Jeśli wcześniej ustaw wszelkie dodatki administracyjne podczas rozmowy na createAndManageUser(), możesz uzyskać wartości z argumentu intent. Oto przykład powiązania z DPC nowego użytkownika dodatkowego w wywołaniu zwrotnym:

Kotlin

override fun onEnabled(context: Context?, intent: Intent?) {
    super.onEnabled(context, intent)

    // Get the affiliation ID (our DPC previously put in the extras) and
    // set the ID for this new secondary user.
    intent?.getStringExtra(AFFILIATION_ID_KEY)?.let {
        val dpm = getManager(context)
        dpm.setAffiliationIds(getWho(context), setOf(it))
    }
    // Continue setup of the new secondary user ...
}

Java

public void onEnabled(Context context, Intent intent) {
  // Get the affiliation ID (our DPC previously put in the extras) and
  // set the ID for this new secondary user.
  String affiliationId = intent.getStringExtra(AFFILIATION_ID_KEY);
  if (affiliationId != null) {
    DevicePolicyManager dpm = getManager(context);
    dpm.setAffiliationIds(getWho(context),
        new HashSet<String>(Arrays.asList(affiliationId)));
  }
  // Continue setup of the new secondary user ...
}

RPC między kontrolerami DPC

Mimo że 2 instancje DPC są uruchomione w ramach osobnych użytkowników, do użytkowników urządzenia, a użytkownicy dodatkowi mogą się ze sobą komunikować. Wywołanie innej usługi DPC przekracza granice użytkowników, więc Twój DPC nie może Wywołaj bindService() w taki sam sposób, jakby na urządzeniach z Androidem. Aby utworzyć powiązanie z usługą działającą w inny użytkownik, wywołaj DevicePolicyManager.bindDeviceAdminServiceAsUser()

Użytkownik główny i 2 powiązane konta użytkowników dodatkowych wywołujące RPC.
Rysunek 2. Administratorzy powiązanych użytkowników głównych i dodatkowych metod obsługi połączeń
.

DPC może tworzyć powiązania tylko z usługami uruchomionymi dla użytkowników zwróconych przez DevicePolicyManager.getBindDeviceAdminTargetUsers() Poniższy przykład pokazuje administratora dodatkowego powiązania użytkownika z administratorem w pełni zarządzanego urządzenia:

Kotlin

// From a secondary user, the list contains just the primary user.
dpm.getBindDeviceAdminTargetUsers(adminName).forEach {

    // Set up the callbacks for the service connection.
    val intent = Intent(mContext, FullyManagedDeviceService::class.java)
    val serviceconnection = object : ServiceConnection {
        override fun onServiceConnected(componentName: ComponentName,
                                        iBinder: IBinder) {
            // Call methods on service ...
        }
        override fun onServiceDisconnected(componentName: ComponentName) {
            // Clean up or reconnect if needed ...
        }
    }

    // Bind to the service as the primary user [it].
    val bindSuccessful = dpm.bindDeviceAdminServiceAsUser(adminName,
            intent,
            serviceconnection,
            Context.BIND_AUTO_CREATE,
            it)
}

Java

// From a secondary user, the list contains just the primary user.
List<UserHandle> targetUsers = dpm.getBindDeviceAdminTargetUsers(adminName);
if (targetUsers.isEmpty()) {
  // If the users aren't affiliated, the list doesn't contain any users.
  return;
}

// Set up the callbacks for the service connection.
Intent intent = new Intent(mContext, FullyManagedDeviceService.class);
ServiceConnection serviceconnection = new ServiceConnection() {
  @Override
  public void onServiceConnected(
      ComponentName componentName, IBinder iBinder) {
    // Call methods on service ...
  }

  @Override
  public void onServiceDisconnected(ComponentName componentName) {
    // Clean up or reconnect if needed ...
  }
};

// Bind to the service as the primary user.
UserHandle primaryUser = targetUsers.get(0);
boolean bindSuccessful = dpm.bindDeviceAdminServiceAsUser(
    adminName,
    intent,
    serviceconnection,
    Context.BIND_AUTO_CREATE,
    primaryUser);

Dodatkowe materiały

Więcej informacji o urządzeniach specjalnych znajdziesz w tych dokumentach: