Książka kucharska na temat urządzeń dedykowanych

Ta książka kucharska pomaga programistom i integratorom systemów w ulepszaniu urządzenia. Zajrzyj do naszych instrukcji i znajdź rozwiązania na specjalne urządzenia zachowań. Ta książka kucharska najlepiej sprawdza się w przypadku deweloperów, którzy mają już swojego aplikacji na urządzeniu – jeśli dopiero zaczynasz, przeczytaj artykuł Urządzenia dedykowane .

Niestandardowe aplikacje ekranu głównego

Te przepisy są przydatne, gdy tworzysz aplikację, która zastąpi Androida Home ekran i Menu z aplikacjami.

Aplikacja ekranu głównego

Możesz ustawić aplikację jako aplikację ekranu głównego na urządzeniu, aby została uruchomiona automatycznie podczas uruchamiania urządzenia. Możesz też włączyć stronę główną przycisk, który przenosi aplikację z listy dozwolonych na pierwszy plan w ramach blokady w trybie zadania.

Wszystkie aplikacje na stronie głównej obsługują kategorię intencji CATEGORY_HOME – to sposób, w jaki system rozpoznaje aplikację ekranu głównego. Aby ustawić domyślną aplikację ekranu głównego, ustaw jedną z nich aktywności aplikacji jako preferowany moduł obsługi intencji Home, przez wywołanie DevicePolicyManager.addPersistentPreferredActivity() jak w tym przykładzie:

Kotlin

// Create an intent filter to specify the Home category.
val filter = IntentFilter(Intent.ACTION_MAIN)
filter.addCategory(Intent.CATEGORY_HOME)
filter.addCategory(Intent.CATEGORY_DEFAULT)

// Set the activity as the preferred option for the device.
val activity = ComponentName(context, KioskModeActivity::class.java)
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
dpm.addPersistentPreferredActivity(adminName, filter, activity)

Java

// Create an intent filter to specify the Home category.
IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);

// Set the activity as the preferred option for the device.
ComponentName activity = new ComponentName(context, KioskModeActivity.class);
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.addPersistentPreferredActivity(adminName, filter, activity);

Nadal musisz zadeklarować filtr intencji. w pliku manifestu aplikacji, jak w tym fragmencie kodu XML:

<activity
        android:name=".KioskModeActivity"
        android:label="@string/kiosk_mode"
        android:launchMode="singleInstance"
        android:excludeFromRecents="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

Zwykle nie chcesz, by Menu z aplikacjami pojawiały się na ekranie Przegląd. Nie musisz jednak dodawać usługi excludeFromRecents do deklarację aktywności, ponieważ Menu z aplikacjami na Androida ukrywa aplikacje uruchomione wcześniej aktywność, gdy system działa w trybie zadań blokady.

Pokaż osobne zadania

FLAG_ACTIVITY_NEW_TASK może być przydatnym oznaczeniem dla: aplikacje podobne do programu uruchamiającego, ponieważ każde nowe zadanie pojawia się w sekcji Ekran przeglądu. Więcej informacji o zadaniach dostępnych na ekranie Przegląd znajdziesz w sekcji Ostatnie Ekran.

Kioski publiczne

Te przepisy świetnie sprawdzają się w przypadku urządzeń bez nadzoru w miejscach publicznych, ale mogą też pozwalają wielu użytkownikom urządzeń skupić się na ich zadaniach.

Zablokuj urządzenie

Aby mieć pewność, że urządzenia są używane zgodnie z przeznaczeniem, możesz dodać ograniczeń dotyczących użytkowników wymienionych w tabeli 1.

Tabela 1. Ograniczenia dotyczące użytkowników urządzeń kiosku
Ograniczenie dotyczące użytkownika Opis
DISALLOW_FACTORY_RESET Uniemożliwia użytkownikowi przywrócenie ustawień fabrycznych. Tę funkcję mogą ustawić administratorzy urządzeń w pełni zarządzanych i główny użytkownik .
DISALLOW_SAFE_BOOT Uniemożliwia użytkownikowi uruchomienia urządzenia w tryb awaryjny w którym system nie uruchomi aplikacji automatycznie. Administratorzy organizacji w pełni urządzenia zarządzane oraz główny użytkownik mogą ustawić to ograniczenie.
DISALLOW_MOUNT_PHYSICAL_MEDIA Uniemożliwia użytkownikowi podłączenia wszelkich woluminów pamięci masowej i podłączać je do urządzenia. Administratorzy w pełni zarządzanych urządzeń i główny użytkownik mogą ustawić to ograniczenie.
DISALLOW_ADJUST_VOLUME Wycisza urządzenie i uniemożliwia użytkownikowi zmianę dźwięku ustawienia głośności i wibracji. Sprawdź, czy kiosk nie wymaga dźwięku do odtwarzania multimediów lub ułatwień dostępu. Administratorzy kont w pełni zarządzanych ustawienie to można ustawić na urządzeniach, na których jest użytkownik główny, użytkownicy pomocniczy i profile służbowe .
DISALLOW_ADD_USER Uniemożliwia użytkownikowi urządzenia dodawanie nowych użytkowników, na przykład użytkowników pomocniczych użytkowników z ograniczonym dostępem. System automatycznie dodaje to ograniczenie użytkownika do: w pełni zarządzanych urządzeniach, ale lista mogła zostać wyczyszczona. Administratorzy organizacji w pełni urządzenia zarządzane oraz główny użytkownik mogą ustawić to ograniczenie.

Z tego fragmentu dowiesz się, jak ustawić ograniczenia:

Kotlin

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
arrayOf(
        UserManager.DISALLOW_FACTORY_RESET,
        UserManager.DISALLOW_SAFE_BOOT,
        UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
        UserManager.DISALLOW_ADJUST_VOLUME,
        UserManager.DISALLOW_ADD_USER).forEach { dpm.addUserRestriction(adminName, it) }

Java

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
String[] restrictions = {
    UserManager.DISALLOW_FACTORY_RESET,
    UserManager.DISALLOW_SAFE_BOOT,
    UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
    UserManager.DISALLOW_ADJUST_VOLUME,
    UserManager.DISALLOW_ADD_USER};

for (String restriction: restrictions) dpm.addUserRestriction(adminName, restriction);

Możesz usunąć te ograniczenia, gdy aplikacja działa w trybie administracyjnym. administrator IT może nadal używać tych funkcji do konserwacji urządzenia. Aby usunąć Ograniczenie, wywołaj DevicePolicyManager.clearUserRestriction()

Blokuj okna błędów

w niektórych środowiskach, takich jak demonstracje w handlu detalicznym lub informacje publiczne. możesz nie chcieć wyświetlać użytkownikom okien błędów. W Androidzie 9.0 (interfejs API) poziomu 28) lub wyższym, możesz wyłączyć okna dialogowe z błędami systemu w przypadku awarii lub niedziałające aplikacje, dodając Użytkownik DISALLOW_SYSTEM_ERROR_DIALOGS . System uruchamia aplikacje ponownie, które nie odpowiadają, tak jak po zamknięciu urządzenia przez użytkownika. z aplikacji. Z przykładu poniżej dowiesz się, jak to zrobić:

Kotlin

override fun onEnabled(context: Context, intent: Intent) {
    val dpm = getManager(context)
    val adminName = getWho(context)

    dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS)
}

Java

public void onEnabled(Context context, Intent intent) {
  DevicePolicyManager dpm = getManager(context);
  ComponentName adminName = getWho(context);

  dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS);
}

Jeśli to ograniczenie zostanie ustawione przez administratora użytkownika głównego lub dodatkowego, ukrywa okna błędów tylko dla tego użytkownika. Jeśli administrator w pełni zarządzanej urządzenie ustawia to ograniczenie, system ukrywa okna dialogowe u wszystkich użytkowników.

Nie wyłączaj ekranu

Jeśli tworzysz kiosk, możesz zatrzymać urządzenie, które usypianie podczas aktywności aplikacji. Dodaj flagę układu FLAG_KEEP_SCREEN_ON w kodzie aplikacji jak w tym przykładzie:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Keep the screen on and bright while this kiosk activity is running.
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // Keep the screen on and bright while this kiosk activity is running.
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

Sprawdź, czy urządzenie jest podłączone do gniazdka elektrycznego, USB lub bezprzewodowego. ładowarki. Zarejestruj się, aby otrzymywać komunikaty o zmianie baterii i używaj BatteryManager aby poznać stan ładowania. Możesz nawet wysyłać alerty zdalne do działu IT administratora, jeśli urządzenie zostanie odłączone. Szczegółowe instrukcje znajdziesz w artykule Monitorowanie poziomu baterii i ładowania Stan.

Możesz też określić STAY_ON_WHILE_PLUGGED_IN globalne ustawienie, aby urządzenie pozostawało uśpione, gdy jest podłączone do źródła zasilania. Administratorzy w pełni zarządzanych urządzeń z Androidem 6.0 (poziom interfejsu API 23) lub nowszym mogą połącz z DevicePolicyManager.setGlobalSetting() zgodnie z ilustracją w tym przykładzie:

Kotlin

val pluggedInto = BatteryManager.BATTERY_PLUGGED_AC or
        BatteryManager.BATTERY_PLUGGED_USB or
        BatteryManager.BATTERY_PLUGGED_WIRELESS
dpm.setGlobalSetting(adminName,
        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, pluggedInto.toString())

Java

int pluggedInto = BatteryManager.BATTERY_PLUGGED_AC |
    BatteryManager.BATTERY_PLUGGED_USB |
    BatteryManager.BATTERY_PLUGGED_WIRELESS;
dpm.setGlobalSetting( adminName,
    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, String.valueOf(pluggedInto));

Pakiety aplikacji

Ta sekcja zawiera przepisy na sprawne instalowanie aplikacji na specjalnych urządzeniach.

Buforowanie pakietów aplikacji

Jeśli użytkownicy współdzielonego urządzenia korzystają z jednego zestawu aplikacji, lepiej unikać pobierania aplikacji, gdy tylko jest to możliwe. Aby ułatwić korzystanie z usług obsługa administracyjna użytkowników na współdzielonych urządzeniach ze stałą grupą użytkowników, takich jak w Androidzie 9.0 (poziom interfejsu API 28) lub nowszym można buforować aplikacje pakiety APK wymagane do obsługi sesji wielu użytkowników.

Zainstalowanie pliku APK z pamięci podręcznej (już zainstalowanego na urządzeniu) odbywa się: 2 etapów:

  1. składnika administratora w pełni zarządzanego urządzenia (lub osobę z przekazanym dostępem – zobacz poniżej) ustawia listę plików APK, które mają być przechowywane na urządzeniu.
  2. Komponenty administracyjne powiązanych użytkowników dodatkowych (lub ich przedstawicieli) mogą zainstalować pakiet APK z pamięci podręcznej w imieniu użytkownika. Administratorzy w pełni zarządzanych urządzenia, głównego użytkownika lub powiązanego profilu służbowego (albo przedstawicieli) mogą w razie potrzeby zainstalować aplikację z pamięci podręcznej.

Aby ustawić listę plików APK do zachowania na urządzeniu, administrator wywołuje metodę DevicePolicyManager.setKeepUninstalledPackages() Ta metoda nie sprawdza, czy na urządzeniu jest zainstalowany plik APK. Jest to przydatne, jeśli chcesz zainstalować aplikację, gdy będzie potrzebna. Aby uzyskać listę ustawionych wcześniej pakietów, można zadzwonić DevicePolicyManager.getKeepUninstalledPackages() Po wywołaniu numeru setKeepUninstalledPackages() ze zmianami lub gdy pomocnicza użytkownika, system usunie wszystkie pliki APK z pamięci podręcznej, które nie są już potrzebne.

Aby zainstalować plik APK z pamięci podręcznej, wywołaj DevicePolicyManager.installExistingPackage() Ta metoda pozwala zainstalować tylko aplikację, która została już zapisana w pamięci podręcznej systemu – dedykowane urządzenie (lub użytkownik urządzenia) musi najpierw zainstalować aplikację na urządzeniu, zanim będzie można wywołać tę metodę.

Z przykładu poniżej dowiesz się, jak możesz użyć takich wywołań interfejsu API w panelu administracyjnym w pełni zarządzane urządzenie i użytkownik dodatkowy:

Kotlin

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
val cachedAppPackageName = "com.example.android.myapp"
dpm.setKeepUninstalledPackages(adminName, listOf(cachedAppPackageName))

// ...

// The admin of a secondary user installs the app.
val success = dpm.installExistingPackage(adminName, cachedAppPackageName)

Java

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
String cachedAppPackageName = "com.example.android.myapp";
List<String> packages = new ArrayList<String>();
packages.add(cachedAppPackageName);
dpm.setKeepUninstalledPackages(adminName, packages);

// ...

// The admin of a secondary user installs the app.
boolean success = dpm.installExistingPackage(adminName, cachedAppPackageName);

Przekazywanie dostępu do aplikacji

Do zarządzania pamięcią podręczną aplikacji możesz przekazać innej aplikacji. Możesz to zrobić, aby: oddzielić funkcje rozwiązania lub zapewnić administratorom IT możliwość korzystania do własnych aplikacji. Aplikacja z przekazanym dostępem otrzymuje te same uprawnienia co administrator . Na przykład pełnomocnik administratora użytkownika dodatkowego może zadzwonić do aplikacji installExistingPackage(), ale nie można zadzwonić do: setKeepUninstalledPackages().

Przekazywanie dostępu DevicePolicyManager.setDelegatedScopes() i uwzględnij DELEGATION_KEEP_UNINSTALLED_PACKAGES w argumencie zakresów. Ten przykład pokazuje, jak utworzyć kolejną aplikację przedstawiciel:

Kotlin

var delegatePackageName = "com.example.tools.kept_app_assist"

// Check that the package is installed before delegating.
try {
    context.packageManager.getPackageInfo(delegatePackageName, 0)
    dpm.setDelegatedScopes(
            adminName,
            delegatePackageName,
            listOf(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES))
} catch (e: PackageManager.NameNotFoundException) {
    // The delegate app isn't installed. Send a report to the IT admin ...
}

Java

String delegatePackageName = "com.example.tools.kept_app_assist";

// Check that the package is installed before delegating.
try {
  context.getPackageManager().getPackageInfo(delegatePackageName, 0);
  dpm.setDelegatedScopes(
      adminName,
      delegatePackageName,
      Arrays.asList(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES));
} catch (PackageManager.NameNotFoundException e) {
  // The delegate app isn't installed. Send a report to the IT admin ...
}

Jeśli wszystko będzie w porządku, aplikacja z przekazanym dostępem otrzyma ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED i staje się jego przedstawicielem. Aplikacja może wywoływać metody opisane w tym przewodniku tak jak właściciel urządzenia lub profilu. Podczas rozmowy DevicePolicyManager, osoba, której przekazano dostęp, przekazuje null administratorowi składnika.

Instalowanie pakietów aplikacji

Czasami warto zainstalować lokalną aplikację w pamięci podręcznej urządzenia. Na przykład urządzenia dedykowane są często wdrażane środowiska o ograniczonej przepustowości lub obszary bez połączenia z internetem. Twoje urządzeń specjalnych powinna uwzględniać przepustowość łącza. Twoje może rozpocząć instalację innego pakietu aplikacji (APK) za pomocą PackageInstaller zajęć.

Każda aplikacja może instalować pliki APK, ale administratorzy na w pełni zarządzanych urządzeniach mogą instalować (lub odinstalowywać) pakietów bez udziału użytkownika. Może zarządzać administratorem urządzenie, powiązany dodatkowy użytkownik lub powiązany profil służbowy. Po Po zakończeniu instalacji system opublikuje powiadomienie, że wszyscy użytkownicy urządzenia zobaczyć. Zawiera ono informacje dla użytkowników urządzenia, że aplikacja została zainstalowana (lub zaktualizowane) przez administratora.

Tabela 2. Wersje Androida obsługujące instalację pakietów bez interakcji użytkownika
Wersja Androida Komponent administracyjny do instalowania i odinstalowywania
Android 9.0 (poziom interfejsu API 28) lub nowszy Powiązane konta użytkowników dodatkowych i profile służbowe – zarówno w ramach w pełni zarządzanych, urządzenia
Android 6.0 (poziom interfejsu API 23) lub nowszy W pełni zarządzane urządzenia

Sposób rozpowszechniania co najmniej jednej kopii pliku APK na urządzeniach specjalnych będzie i odległości między nimi. pochodzą od siebie nawzajem. Twoje rozwiązanie musi być zgodne ze sprawdzonymi metodami zapewniania bezpieczeństwa przed zainstalowaniem pakietów APK na specjalnych urządzeniach.

Możesz użyć narzędzia PackageInstaller.Session, aby utworzyć sesję, która doda ją do kolejki lub więcej plików APK do instalacji. W poniższym przykładzie otrzymujemy stan opinii w naszej aktywności (tryb singleTop), ale możesz użyć lub odbiornik:

Kotlin

// First, create a package installer session.
val packageInstaller = context.packageManager.packageInstaller
val params = PackageInstaller.SessionParams(
        PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = packageInstaller.createSession(params)
val session = packageInstaller.openSession(sessionId)

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
// The I/O streams can't be open when installation begins.
session.openWrite("apk", 0, -1).use { output ->
    getContext().resources.openRawResource(R.raw.app).use { input ->
        input.copyTo(output, 2048)
    }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
val intent = Intent(context, activity.javaClass)
intent.action = "com.android.example.APK_INSTALLATION_ACTION"
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
val statusReceiver = pendingIntent.intentSender

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver)

Java

// First, create a package installer session.
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
try (
    // These I/O streams can't be open when installation begins.
    OutputStream output = session.openWrite("apk", 0, -1);
    InputStream input = getContext().getResources().openRawResource(R.raw.app);
) {
  byte[] buffer = new byte[2048];
  int n;
  while ((n = input.read(buffer)) >= 0) {
    output.write(buffer, 0, n);
  }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
Intent intent = new Intent(context, getActivity().getClass());
intent.setAction("com.android.example.APK_INSTALLATION_ACTION");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver);

Sesja wysyła opinię o stanie instalacji za pomocą intencji. Sprawdź w polu EXTRA_STATUS każdej intencji, aby uzyskać stan. Pamiętaj, że administratorzy nie otrzymują STATUS_PENDING_USER_ACTION – aktualizacja stanu ponieważ użytkownik urządzenia nie musi zatwierdzać instalacji.

Aby odinstalować aplikacje, możesz zadzwonić pod numer PackageInstaller.uninstall. Administratorzy w pełni zarządzanych urządzeń, użytkowników i profili służbowych mogą odinstalować pakiety bez interakcji użytkownika na obsługiwanych wersjach Androida (zobacz tabeli 2).

Blokowanie aktualizacji systemu

Urządzenia z Androidem otrzymują aktualizacje systemu i aplikacji bezprzewodowo (OTA). i oprogramowaniu. Aby zablokować wersję systemu operacyjnego w okresach krytycznych, takich jak święta lub w innych godzinach, urządzenia specjalne mogą zawieszać aktualizacje systemu OTA na maksymalnie 90 dni. Więcej informacji znajdziesz w artykule Zarządzanie aktualizacjami systemu.

Zdalna konfiguracja

Konfiguracje zarządzane w Androidzie umożliwiają administratorom IT: zdalnie konfigurować aplikację. Możesz pokazać ustawienia takie jak: listy dozwolonych, hostów sieciowych i adresów URL treści, aby aplikacja była bardziej użyteczna dla działu IT dla administratorów.

Jeśli Twoja aplikacja ujawnia swoją konfigurację, pamiętaj o uwzględnieniu ustawień w sekcji dokumentacji. Aby dowiedzieć się więcej o ujawnianiu konfiguracji aplikacji i reagowaniu na zmian w ustawieniach znajdziesz w artykule Konfigurowanie konfiguracji zarządzanych.

Konfiguracja programowania

Podczas pracy nad rozwiązaniem dla urządzeń specjalnych czasami przydatne do ustawienia aplikacji jako administratora w pełni zarządzanego urządzenia bez ustawień fabrycznych. . Aby ustawić administratora w pełni zarządzanego urządzenia, wykonaj te czynności:

  1. Utwórz i zainstaluj na urządzeniu aplikację kontrolera zasad urządzeń.
  2. Sprawdź, czy na urządzeniu nie ma żadnych kont.
  3. Uruchom podane niżej polecenie w powłoce Android Debug Bridge (adb). Ty musisz zastąpić com.example.dpc/.MyDeviceAdminReceiver w przykładzie nazwa komponentu administratora aplikacji:

    adb shell dpm set-device-owner com.example.dpc/.MyDeviceAdminReceiver

Aby pomóc klientom wdrożyć rozwiązanie, zapoznaj się z innymi procesami rejestracji . Zalecamy rejestrację za pomocą kodu QR w przypadku: urządzeń specjalnych.

Dodatkowe materiały

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