Cookbook perangkat khusus

Cookbook ini membantu developer dan integrator sistem meningkatkan solusi perangkat seluler. Ikuti urutan langkah kami untuk menemukan solusi bagi perangkat khusus perilaku model. Buku resep ini paling cocok untuk developer yang sudah memiliki aplikasi perangkat—jika Anda baru saja memulai, baca Perangkat khusus ringkasan.

Aplikasi Home kustom

Urutan langkah ini berguna jika Anda mengembangkan aplikasi untuk menggantikan Android Home dan Peluncur.

Menjadi aplikasi layar utama

Anda dapat menyetel aplikasi sebagai aplikasi layar utama perangkat agar dapat diluncurkan secara otomatis ketika perangkat dinyalakan. Anda juga dapat mengaktifkan tombol yang membawa aplikasi yang diizinkan ke latar depan saat terkunci mode tugas.

Semua aplikasi layar utama menangani kategori intent CATEGORY_HOME—ini adalah bagaimana sistem mengenali aplikasi {i>home<i}. Untuk menjadi aplikasi layar utama default, setel aplikasi aktivitas aplikasi Anda sebagai pengendali intent Home yang dipilih, dengan memanggil DevicePolicyManager.addPersistentPreferredActivity() seperti yang ditunjukkan dalam contoh berikut:

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

Anda tetap harus mendeklarasikan filter intent di file manifes aplikasi Anda seperti yang ditampilkan dalam cuplikan XML berikut:

<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>

Biasanya Anda tidak ingin aplikasi peluncur muncul di layar Ringkasan. Namun, Anda tidak perlu menambahkan excludeFromRecents ke deklarasi aktivitas karena Peluncur Android menyembunyikan aktivitas saat sistem berjalan dalam mode mengunci tugas.

Tampilkan tugas terpisah

FLAG_ACTIVITY_NEW_TASK dapat menjadi flag yang berguna untuk aplikasi berjenis peluncur karena setiap tugas baru akan muncul sebagai item terpisah dalam Layar Ringkasan. Untuk mempelajari lebih lanjut tugas di layar Ringkasan, baca Terbaru Layar.

Kios publik

Resep-resep ini bagus untuk perangkat yang tidak diawasi di tempat umum tetapi juga bisa membantu banyak pengguna perangkat khusus untuk fokus pada tugas mereka.

Kunci perangkat

Untuk membantu memastikan bahwa perangkat digunakan sesuai tujuan, Anda dapat menambahkan batasan pengguna yang tercantum dalam tabel 1.

Tabel 1. Batasan pengguna untuk perangkat kios
Batasan pengguna Deskripsi
DISALLOW_FACTORY_RESET Mencegah pengguna perangkat mereset perangkat ke setelan default pabrik. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menyetelnya resource.
DISALLOW_SAFE_BOOT Mencegah pengguna perangkat memulai perangkat mode aman di mana sistem tidak akan meluncurkan aplikasi Anda secara otomatis. Admin sepenuhnya perangkat terkelola dan pengguna utama dapat menetapkan batasan ini.
DISALLOW_MOUNT_PHYSICAL_MEDIA Mencegah pengguna perangkat memasang volume penyimpanan yang mungkin mereka pasang ke perangkat. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menetapkan batasan ini.
DISALLOW_ADJUST_VOLUME Membisukan audio perangkat dan mencegah pengguna perangkat mengubah suara setelan volume dan getaran. Pastikan kios Anda tidak memerlukan audio untuk fitur aksesibilitas atau pemutaran media. Admin akun yang terkelola sepenuhnya pengguna utama, pengguna sekunder, dan profil kerja dapat menyetelnya. resource.
DISALLOW_ADD_USER Mencegah pengguna perangkat menambahkan pengguna baru, seperti pengguna sekunder atau pengguna yang dibatasi. Sistem secara otomatis menambahkan batasan pengguna ini ke perangkat terkelola sepenuhnya tetapi mungkin telah dihapus. Admin sepenuhnya perangkat terkelola dan pengguna utama dapat menetapkan batasan ini.

Cuplikan berikut menunjukkan cara menetapkan batasan:

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

Anda mungkin perlu menghapus batasan ini ketika aplikasi Anda berada dalam mode admin sehingga bahwa admin IT masih dapat menggunakan fitur ini untuk pemeliharaan perangkat. Untuk menghapus pembatasan tersebut, panggil DevicePolicyManager.clearUserRestriction()

Menyembunyikan dialog error

Di beberapa lingkungan, seperti demonstrasi retail atau informasi publik Anda mungkin tidak ingin menampilkan dialog {i>error<i} kepada pengguna. Di Android 9.0 (API 28) atau lebih tinggi, Anda dapat menyembunyikan dialog error sistem untuk error aplikasi yang tidak responsif dengan menambahkan Pengguna DISALLOW_SYSTEM_ERROR_DIALOGS resource. Sistem memulai ulang aplikasi yang tidak responsif seolah-olah perangkat pengguna ditutup aplikasi dari dialog. Contoh berikut menunjukkan cara Anda dapat melakukan ini:

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

Jika admin pengguna utama atau sekunder menetapkan batasan ini, sistem akan menyembunyikan dialog error hanya untuk pengguna tersebut. Jika admin akun terkelola sepenuhnya jika perangkat menyetel pembatasan ini, sistem akan menyembunyikan dialog untuk semua pengguna.

Menjaga layar agar tetap aktif

Jika Anda membuat kios, Anda dapat menghentikan perangkat yang akan tidur saat aplikasi menjalankan aktivitas aplikasi Anda. Tambah flag tata letak FLAG_KEEP_SCREEN_ON ke seperti yang ditunjukkan dalam contoh berikut:

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

Anda mungkin ingin memeriksa apakah perangkat dicolokkan ke sumber listrik AC, USB, atau nirkabel ke pengisi daya. Mendaftar untuk siaran perubahan baterai dan menggunakan BatteryManager nilai untuk menemukan status pengisian daya. Anda bahkan dapat mengirim peringatan jarak jauh kepada staf IT admin jika perangkat dicabut. Untuk petunjuk langkah demi langkah, baca Memantau Level Daya dan Pengisian Daya Baterai Status.

Anda juga dapat menyetel STAY_ON_WHILE_PLUGGED_IN secara global agar perangkat tetap aktif saat terhubung ke sumber listrik. Admin perangkat terkelola sepenuhnya, di Android 6.0 (API level 23) atau yang lebih tinggi, dapat panggil DevicePolicyManager.setGlobalSetting() seperti yang ditunjukkan dalam contoh berikut:

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

Paket aplikasi

Bagian ini berisi urutan langkah untuk menginstal aplikasi secara efisien ke perangkat khusus.

Meng-cache paket aplikasi

Jika semua pengguna perangkat bersama berbagi satu kumpulan aplikasi yang sama, hal itu akan masuk akal untuk menghindari mengunduh aplikasi jika memungkinkan. Untuk menyederhanakan pengguna penyediaan resource di perangkat bersama dengan sekumpulan pengguna yang tetap, seperti perangkat untuk pekerja shift, di Android 9.0 (API level 28) atau yang lebih baru, Anda dapat meng-cache aplikasi paket (APK) yang diperlukan untuk sesi multi-pengguna.

Menginstal APK yang di-cache (yang sudah terinstal di perangkat) terjadi di dua tahap:

  1. Komponen admin dari perangkat terkelola sepenuhnya (atau delegasi—lihat berikut) menetapkan daftar APK yang akan disimpan di perangkat.
  2. Komponen admin dari pengguna sekunder yang berafiliasi (atau delegasi mereka) dapat instal APK yang di-cache atas nama pengguna. Admin akun terkelola sepenuhnya perangkat Anda, pengguna utama, atau profil kerja yang berafiliasi (atau akun delegasi) juga bisa menginstal aplikasi yang di-cache jika diperlukan.

Untuk menyetel daftar APK yang akan disimpan di perangkat, admin memanggil DevicePolicyManager.setKeepUninstalledPackages() Metode ini tidak memeriksa apakah APK telah diinstal pada perangkat—berguna jika Anda ingin menginstal aplikasi sebelum Anda membutuhkannya untuk pengguna. Untuk mendapatkan daftar paket yang telah ditetapkan sebelumnya, Anda dapat memanggil DevicePolicyManager.getKeepUninstalledPackages() Setelah Anda memanggil setKeepUninstalledPackages() dengan perubahan, atau saat panggilan sekunder pengguna dihapus, sistem akan menghapus APK yang di-cache yang tidak lagi diperlukan.

Untuk menginstal APK yang di-cache, panggil DevicePolicyManager.installExistingPackage() Metode ini hanya dapat menginstal aplikasi yang telah di-cache sistem— solusi perangkat khusus (atau pengguna perangkat) harus terlebih dahulu menginstal aplikasi pada perangkat sebelum Anda dapat memanggil metode ini.

Contoh berikut menunjukkan cara menggunakan panggilan API ini di admin perangkat terkelola sepenuhnya dan pengguna sekunder:

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

Delegasikan aplikasi

Anda dapat mendelegasikan aplikasi lain untuk mengelola penyimpanan aplikasi dalam cache. Anda mungkin perlu melakukan ini untuk memisahkan fitur dari solusi Anda atau menawarkan kemampuan bagi admin IT untuk menggunakan aplikasi mereka sendiri. Aplikasi yang didelegasikan mendapatkan izin yang sama dengan admin komponen. Misalnya, delegasi aplikasi dari admin pengguna sekunder dapat memanggil installExistingPackage(), tetapi tidak dapat memanggil setKeepUninstalledPackages().

Untuk melakukan panggilan delegasi DevicePolicyManager.setDelegatedScopes() dan sertakan DELEGATION_KEEP_UNINSTALLED_PACKAGES dalam argumen cakupan. Contoh berikut menunjukkan cara membuat aplikasi lain penerima delegasi:

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 ...
}

Jika semuanya berjalan lancar, aplikasi delegasi akan menerima ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED melakukan siaran dan menjadi delegasinya. Aplikasi dapat memanggil metode dalam panduan ini seolah-olah itu adalah pemilik perangkat atau pemilik profil. Saat menelepon Metode DevicePolicyManager, delegasi akan meneruskan null untuk admin argumen komponen.

Instal paket aplikasi

Kadang-kadang ada gunanya menginstal aplikasi khusus yang di-cache secara lokal ke perangkat seluler. Misalnya, perangkat khusus sering di-deploy ke lingkungan dengan bandwidth terbatas atau area tanpa konektivitas internet apa pun. Nama solusi perangkat khusus harus memperhatikan {i>bandwidth<i} pelanggan Anda. Nama aplikasi Anda dapat memulai penginstalan paket aplikasi (APK) lain menggunakan Class PackageInstaller.

Meskipun aplikasi apa pun dapat menginstal APK, admin pada perangkat yang terkelola sepenuhnya dapat menginstal (atau menghapus instalan) paket tanpa interaksi pengguna. Admin mungkin mengelola perangkat, pengguna sekunder yang berafiliasi, atau profil kerja yang berafiliasi. Sesudah menyelesaikan penginstalan, sistem akan memposting pemberitahuan bahwa semua pengguna perangkat baca. Notifikasi tersebut memberi tahu pengguna perangkat bahwa aplikasi telah diinstal (atau diperbarui) oleh adminnya.

Tabel 2. Versi Android yang mendukung penginstalan paket tanpa interaksi pengguna
Versi Android Komponen admin untuk penginstalan dan uninstal
Android 9.0 (level API 28) atau yang lebih tinggi Pengguna sekunder dan profil kerja yang terafiliasi—baik dengan profil kerja yang terkelola sepenuhnya perangkat
Android 6.0 (level API 23) atau yang lebih tinggi Perangkat terkelola sepenuhnya

Cara Anda mendistribusikan satu atau beberapa salinan APK ke perangkat khusus akan bergantung pada seberapa jauh perangkat dan mungkin seberapa jauh perangkat berasal dari satu sama lain. Solusi Anda harus mengikuti praktik terbaik keamanan sebelum menginstal APK ke perangkat khusus.

Anda dapat menggunakan PackageInstaller.Session untuk membuat sesi yang mengantrekan sesi atau lebih APK untuk penginstalan. Pada contoh berikut, kita menerima status masukan di aktivitas kami (mode singleTop), tetapi Anda dapat menggunakan penerima siaran atau layanan:

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

Sesi mengirimkan masukan status tentang penginstalan menggunakan intent. Periksa setiap kolom EXTRA_STATUS intent untuk mendapatkan status. Perlu diingat, admin tidak menerima Pembaruan status STATUS_PENDING_USER_ACTION karena pengguna perangkat tidak perlu menyetujui pemasangan.

Untuk meng-uninstal aplikasi, Anda dapat memanggil PackageInstaller.uninstall. Admin perangkat, pengguna, dan profil kerja yang terkelola sepenuhnya dapat meng-uninstal paket tanpa interaksi pengguna, menjalankan versi Android yang didukung (lihat tabel 2).

Membekukan update sistem

Perangkat Android menerima update over the air (OTA) untuk sistem dan aplikasi {i>software<i}. Untuk membekukan versi OS selama periode penting, seperti hari libur atau di waktu sibuk lainnya, perangkat khusus dapat menangguhkan update sistem OTA hingga 90 hari. Untuk mempelajari lebih lanjut, baca Mengelola update sistem.

Konfigurasi jarak jauh

Konfigurasi terkelola Android memungkinkan admin IT untuk melakukan konfigurasi aplikasi Anda dari jarak jauh. Anda mungkin ingin mengekspos setelan seperti daftar yang diizinkan, host jaringan, atau URL konten untuk membuat aplikasi Anda lebih berguna bagi IT admin.

Jika aplikasi Anda mengekspos konfigurasinya, jangan lupa untuk menyertakan setelan di dokumentasi tambahan. Untuk mempelajari lebih lanjut cara mengekspos konfigurasi aplikasi dan bereaksi terhadap di setelan, baca Menyiapkan konfigurasi terkelola.

Penyiapan pengembangan

Selagi Anda mengembangkan solusi untuk perangkat khusus, terkadang berguna untuk menyetel aplikasi Anda sebagai admin perangkat terkelola sepenuhnya tanpa setelan pabrik {i>reset<i}. Untuk menetapkan admin perangkat terkelola sepenuhnya, ikuti langkah-langkah berikut:

  1. Bangun dan instal aplikasi pengontrol kebijakan perangkat (DPC) di perangkat.
  2. Pastikan tidak ada akun di perangkat.
  3. Jalankan perintah berikut di shell Android Debug Bridge (adb). Anda perlu mengganti com.example.dpc/.MyDeviceAdminReceiver dalam contoh dengan nama komponen admin aplikasi Anda:

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

Untuk membantu pelanggan menerapkan solusi, Anda harus melihat pendaftaran lain metode. Sebaiknya pendaftaran kode QR untuk perangkat yang terdedikasi.

Referensi lainnya

Untuk mempelajari perangkat khusus lebih lanjut, baca dokumen berikut: