Profile służbowe

Platforma Androida umożliwia urządzeniom posiadanie profili służbowych (czasami zwanych profilami zarządzanymi). Profilem do pracy zarządza administrator IT, a dostępne dla niego funkcje są ustawiane niezależnie od funkcji głównego profilu użytkownika. Dzięki temu organizacje mogą kontrolować środowisko, w którym działają na urządzeniach użytkowników aplikacje i dane specyficzne dla firmy. Użytkownicy mogą jednocześnie korzystać z osobistych aplikacji i profili.

Z tej lekcji dowiesz się, jak zmodyfikować swoją aplikację, aby działała niezawodnie na urządzeniu z profilem służbowym. Nie musisz robić nic poza zwykłymi sprawdzonymi metodami tworzenia aplikacji. Niektóre ze sprawdzonych metod są jednak szczególnie ważne na urządzeniach z profilami służbowymi. Ten dokument wskazuje problemy, na które należy uważać.

Przegląd

Użytkownicy często chcą korzystać z urządzeń osobistych w środowisku firmowym. Taka sytuacja może stawiać organizacje w dylematach. Jeśli użytkownik może korzystać z własnego urządzenia, organizacja musi się martwić, że poufne informacje (takie jak e-maile i kontakty pracowników) znajdują się na urządzeniu, którego organizacja nie ma pod kontrolą.

W tej sytuacji Android 5.0 (poziom interfejsu API 21) umożliwia organizacjom konfigurowanie profili służbowych. Jeśli urządzenie ma profil służbowy, nad jego ustawieniami zarządza administrator IT. Administrator IT może wybrać, które aplikacje są dozwolone w przypadku danego profilu, i kontrolować, które funkcje urządzenia mają być dostępne na tym profilu.

Jeśli urządzenie ma profil służbowy, ma to wpływ na aplikacje uruchomione na urządzeniu, niezależnie od profilu, w którym działa:

  • Domyślnie większość intencji nie krzyżuje się między profilami. Jeśli aplikacja uruchomiona na profilu wywoła intencję, w tym profilu nie będzie żadnego modułu obsługi, a intencja nie będzie mogła przejść do innego profilu ze względu na ograniczenia profilu, żądanie nie zostanie zrealizowane, a aplikacja może się niespodziewanie wyłączyć.
  • Administrator IT profilu może ograniczyć zakres aplikacji systemowych dostępnych w profilu służbowym. Ograniczenie to może też spowodować brak modułu obsługi w przypadku niektórych typowych intencji w profilu służbowym.
  • Profil prywatny i służbowy mają oddzielne miejsce na dane, więc identyfikator URI pliku prawidłowy w jednym profilu nie jest prawidłowy w drugim. Każda intencja wywołana w jednym profilu może być obsługiwana w innym (w zależności od ustawień profilu), więc dołączanie identyfikatorów URI plików do intencji nie jest bezpieczne.

Zapobiegaj nieudanych intencjom

Na urządzeniu z profilem służbowym obowiązują ograniczenia dotyczące tego, czy zamiary mogą się krzyżować między profilami. W większości przypadków, gdy intencja jest uruchamiana, jest obsługiwana na tym samym profilu. Jeśli w tym profilu nie ma modułu obsługi intencji, intencja nie jest obsługiwana, a uruchomiona aplikacja może się nieoczekiwanie zamknąć – nawet jeśli w innym profilu istnieje moduł obsługi intencji.

Administrator profilu może wybrać, które intencje mogą się przenosić między profilami. Taką decyzję podejmuje administrator IT, dlatego nie ma możliwości wcześniejszego sprawdzenia, które intencje mogą przekroczyć tę granicę. Tę zasadę określa administrator IT, a w każdej chwili może ją zmienić.

Zanim aplikacja rozpocznie aktywność, sprawdź, czy masz odpowiednie rozwiązanie. Aby sprawdzić, czy rozwiązanie jest zaakceptowane, wywołaj Intent.resolveActivity(). Jeśli nie można rozwiązać intencji, metoda zwraca null. Jeśli metoda zwraca wartość nienull, istnieje co najmniej 1 sposób na rozstrzygnięcie intencji i można bezpiecznie uruchamiać intencję. W tym przypadku można rozstrzygnąć intencję, ponieważ w bieżącym profilu występuje moduł obsługi lub intencja może przechodzić do modułu obsługi na drugim profilu. Więcej informacji o rozpoznawaniu intencji znajdziesz w artykule Typowe intencje.

Jeśli na przykład aplikacja musi ustawiać liczniki czasu, musi sprawdzić, czy istnieje prawidłowy moduł obsługi dla intencji ACTION_SET_TIMER. Jeśli aplikacja nie może rozwiązać intencji, powinna podjąć odpowiednie działanie (np. wyświetlić komunikat o błędzie).

Kotlin

fun startTimer(message: String, seconds: Int) {

    // Build the "set timer" intent
    val timerIntent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(packageManager) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent)

    }
}

Java

public void startTimer(String message, int seconds) {

    // Build the "set timer" intent
    Intent timerIntent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);

    // Check if there's a handler for the intent
    if (timerIntent.resolveActivity(getPackageManager()) == null) {

        // Can't resolve the intent! Fail this operation cleanly
        // (perhaps by showing an error message)

    } else {
        // Intent resolves, it's safe to fire it off
        startActivity(timerIntent);

    }
}

Udostępniaj pliki w różnych profilach

Czasami aplikacja musi umożliwić innym aplikacjom dostęp do własnych plików. Na przykład aplikacja galerii obrazów może udostępniać swoje obrazy edytorom obrazów. Plik można zazwyczaj udostępniać na 2 sposoby: za pomocą identyfikatora URI pliku lub identyfikatora URI treści.

Identyfikator URI pliku zaczyna się od prefiksu file:, po którym następuje bezwzględna ścieżka pliku w pamięci urządzenia. Profil służbowy i osobisty korzystają jednak z osobnych obszarów przechowywania, więc identyfikator URI pliku prawidłowy w jednym profilu nie jest prawidłowy w drugim. Oznacza to, że jeśli do intencji, a intencja jest obsługiwana w innym profilu, dołączysz identyfikator URI pliku, moduł obsługi nie będzie mógł uzyskać dostępu do pliku.

Zamiast tego udostępniaj pliki za pomocą identyfikatorów URI treści. Identyfikatory URI treści identyfikują plik w bezpieczniejszy sposób, który można udostępniać. Identyfikator URI treści zawiera ścieżkę pliku, a także nazwę urzędu, który udostępnia ten plik, oraz numer identyfikacyjny identyfikujący plik. Możesz wygenerować identyfikator treści dla dowolnego pliku za pomocą właściwości FileProvider. Możesz go udostępnić innym aplikacjom (nawet w ramach drugiego profilu). Odbiorca może użyć identyfikatora treści, aby uzyskać dostęp do pliku.

Aby na przykład uzyskać identyfikator URI treści dla określonego pliku:

Kotlin

// Open File object from its file URI
val fileToShare = File(fileUriToShare)

val contentUriToShare: Uri = FileProvider.getUriForFile(
        context,
        "com.example.myapp.fileprovider",
        fileToShare
)

Java

// Open File object from its file URI
File fileToShare = new File(fileUriToShare);

Uri contentUriToShare = FileProvider.getUriForFile(getContext(),
        "com.example.myapp.fileprovider", fileToShare);

Wywołując metodę getUriForFile(), musisz podać uprawnienia dostawcy pliku (w tym przykładzie "com.example.myapp.fileprovider"), które jest określone w elemencie <provider> pliku manifestu aplikacji. Więcej informacji o udostępnianiu plików za pomocą identyfikatorów URI treści znajdziesz w sekcji Udostępnianie plików.

Słuchaj powiadomień

Aplikacja zazwyczaj udostępnia podklasę NotificationListenerService do odbierania przez system wywołań zwrotnych dotyczących zmian w powiadomieniach. Urządzenia z profilami służbowymi mogą wpływać na działanie NotificationListenerService z Twoją aplikacją.

W profilu służbowym

Nie możesz użyć uprawnienia NotificationListenerService z aplikacji uruchomionej w profilu służbowym. Gdy Twoja aplikacja działa w profilu służbowym, system ignoruje jej NotificationListenerService. Aplikacje uruchomione w profilu osobistym mogą jednak nasłuchiwać powiadomień.

W profilu osobistym

Jeśli Twoja aplikacja działa w profilu osobistym, możesz nie otrzymywać powiadomień z aplikacji uruchomionych w tym profilu. Domyślnie wszystkie aplikacje profilu osobistego otrzymują wywołania zwrotne, ale administrator IT może dodać do listy dozwolonych co najmniej 1 aplikację profilu osobistego, która zezwala na nasłuchiwanie zmian powiadomień. Następnie system blokuje aplikacje, które nie znajdują się na liście dozwolonych. Na urządzeniu z Androidem 8.0 (poziom interfejsu API 26) lub nowszym kontroler zasad dotyczących urządzeń (DPC) zarządzający profilem służbowym może blokować aplikacji dostęp do powiadomień z profilu służbowego za pomocą DevicePolicyManagermetodysetPermittedCrossProfileNotificationListeners(). Aplikacja nadal będzie otrzymywać wywołania zwrotne dotyczące powiadomień opublikowanych w profilu osobistym.

Testowanie zgodności aplikacji z profilami służbowymi

Przetestuj aplikację w środowisku profili służbowych, aby wykryć problemy, które mogłyby spowodować awarię aplikacji na urządzeniu z profilami służbowymi. W szczególności warto przeprowadzić testy na urządzeniu z profilem służbowym, by mieć pewność, że aplikacja prawidłowo obsługuje intencje – nie uruchamia intencji, których nie można obsłużyć, nie dołącza identyfikatorów URI, które nie działają w różnych profilach, itp.

Udostępniliśmy przykładową aplikację TestDPC, której możesz użyć do skonfigurowania profilu służbowego na urządzeniu z Androidem 5.0 (poziom interfejsu API 21) lub nowszym. Umożliwia ona łatwe testowanie aplikacji w środowisku profilu służbowego. Możesz jej też użyć do skonfigurowania profilu służbowego w ten sposób:

  • Określ, które aplikacje domyślne są dostępne w profilu zarządzanym
  • Określ, które intencje mogą się przechodzić między poszczególnymi profilami

Jeśli ręcznie zainstalujesz aplikację za pomocą kabla USB na urządzeniu z profilem służbowym, zostanie ona zainstalowana zarówno na profilu osobistym, jak i służbowym. Gdy zainstalujesz aplikację, możesz ją przetestować pod tymi warunkami:

  • Jeśli intencja była zwykle obsługiwana przez aplikację domyślną (np. aplikację aparatu), spróbuj ją wyłączyć w profilu służbowym i sprawdź, czy aplikacja obsługuje tę funkcję prawidłowo.
  • Jeśli uruchamiasz intencję, która oczekuje, że będzie obsługiwana przez inną aplikację, spróbuj włączyć i wyłączyć w niej uprawnienia do przechodzenia między profilami. Sprawdź, czy aplikacja działa prawidłowo w obu warunkach. Jeśli intencje nie mogą się pojawiać w różnych profilach, sprawdź działanie aplikacji zarówno wtedy, gdy w jej profilu istnieje odpowiedni moduł obsługi, jak i gdy nie jest. Jeśli na przykład aplikacja uruchamia intencję związaną z mapą, wypróbuj każdy z tych scenariuszy:
    • Urządzenie umożliwia przechodzenie intencji mapy z jednego profilu do drugiego, a w drugim profilu istnieje odpowiedni moduł obsługi (profil, w którym nie działa aplikacja).
    • Urządzenie nie zezwala na krzyżowanie się intencji mapy między profilami, ale profil aplikacji zawiera odpowiedni moduł obsługi.
    • Urządzenie nie zezwala na krzyżowanie się intencji mapy między profilami, a w profilu urządzenia nie ma odpowiedniego modułu obsługi intencji map.
  • Jeśli dołączasz treści do intencji, sprawdź, czy intencja działa prawidłowo zarówno wtedy, gdy jest obsługiwana w profilu aplikacji, jak i gdy przechodzi między profilami.

Testowanie w profilach służbowych: porady i wskazówki

Jest kilka sztuczek, które mogą Ci się przydać podczas testowania na urządzeniu z profilem służbowym.

  • Jak wspomnieliśmy, aplikacja zainstalowana z innego urządzenia na urządzeniu z profilem służbowym jest zainstalowana w obu profilach. Możesz usunąć aplikację z jednego profilu i pozostawić ją w drugim.
  • Większość poleceń menedżera aktywności dostępnych w powłoce Android Debug Bridge (adb) obsługuje flagę --user, która umożliwia określenie użytkownika, jako którego chcesz uruchamiać działania. Podając użytkownika, możesz określić, czy aplikacja ma być uruchamiana jako niezarządzany użytkownik główny, czy profil służbowy. Więcej informacji znajdziesz w artykule o poleceniach powłoki ADB.
  • Aby znaleźć aktywnych użytkowników na urządzeniu, użyj polecenia list users menedżera pakietów adb. Pierwsza liczba w ciągu wyjściowym to identyfikator użytkownika, którego możesz użyć z flagą --user. Więcej informacji znajdziesz w artykule o poleceniach powłoki ADB.

Aby na przykład znaleźć użytkowników korzystających z urządzenia, uruchom to polecenie:

$ adb shell pm list users
UserInfo{0:Drew:13} running
UserInfo{10:Work profile:30} running

W tym przypadku użytkownik główny („Drew”) ma identyfikator użytkownika 0, a profil służbowy – identyfikator użytkownika 10. Aby uruchomić aplikację w profilu służbowym, możesz użyć tego polecenia:

$ adb shell am start --user 10 \
-n "com.example.myapp/com.example.myapp.testactivity" \
-a android.intent.action.MAIN -c android.intent.category.LAUNCHER