Cookbook ini membantu developer dan integrator sistem meningkatkan kualitas solusi perangkat khusus mereka. Ikuti resep petunjuk kami untuk menemukan solusi bagi perilaku perangkat khusus. Cookbook ini sangat cocok untuk developer yang sudah memiliki aplikasi perangkat khusus. Jika Anda baru memulai, baca Ringkasan perangkat khusus.
Aplikasi Home kustom
Resep ini berguna jika Anda mengembangkan aplikasi untuk menggantikan Layar utama Android dan Peluncur.
Jadilah aplikasi layar utama
Anda dapat menetapkan aplikasi Anda sebagai aplikasi layar utama perangkat agar diluncurkan secara otomatis saat perangkat dimulai. Anda juga dapat mengaktifkan tombol Beranda yang membawa aplikasi yang diizinkan ke latar depan dalam mode tugas kunci.
Semua aplikasi layar utama menangani kategori intent CATEGORY_HOME
—inilah
cara sistem mengenali aplikasi layar utama. Untuk menjadi aplikasi layar utama default, tetapkan salah satu
aktivitas aplikasi Anda sebagai pengendali intent Home pilihan, dengan memanggil
DevicePolicyManager.addPersistentPreferredActivity()
seperti yang ditunjukkan pada 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 seperti ditunjukkan 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 yang pertama kali
diluncurkan saat sistem berjalan dalam mode mengunci tugas.
Tampilkan tugas terpisah
FLAG_ACTIVITY_NEW_TASK
dapat menjadi flag yang berguna untuk
aplikasi jenis peluncur karena setiap tugas baru muncul sebagai item terpisah di
layar Ringkasan. Untuk mempelajari tugas lebih lanjut di layar Ringkasan, baca Layar
Terbaru.
Kios publik
Resep ini bagus untuk perangkat tanpa pengawasan di ruang publik, tetapi juga dapat membantu banyak pengguna perangkat khusus berfokus pada tugas mereka.
Kunci perangkat
Guna membantu memastikan bahwa perangkat digunakan untuk tujuan yang dimaksudkan, Anda dapat menambahkan batasan pengguna yang tercantum pada tabel 1.
Pembatasan pengguna | Deskripsi |
---|---|
DISALLOW_FACTORY_RESET |
Mencegah pengguna perangkat mereset perangkat ke setelan default pabrik. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menetapkan batasan ini. |
DISALLOW_SAFE_BOOT |
Mencegah pengguna perangkat memulai perangkat dalam mode aman yang tidak memungkinkan sistem meluncurkan aplikasi secara otomatis. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menetapkan batasan ini. |
DISALLOW_MOUNT_PHYSICAL_MEDIA |
Mencegah pengguna perangkat memasang volume penyimpanan apa pun yang mungkin dipasang ke perangkat. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menetapkan batasan ini. |
DISALLOW_ADJUST_VOLUME |
Membisukan perangkat dan mencegah pengguna perangkat mengubah setelan volume suara dan getaran. Pastikan kios Anda tidak memerlukan audio untuk fitur aksesibilitas atau pemutaran media. Admin perangkat terkelola sepenuhnya, pengguna utama, pengguna sekunder, dan profil kerja dapat menetapkan batasan ini. |
DISALLOW_ADD_USER |
Mencegah pengguna perangkat menambahkan pengguna baru, seperti pengguna sekunder atau pengguna yang dibatasi. Sistem akan otomatis menambahkan batasan pengguna ini ke perangkat terkelola sepenuhnya, tetapi batasan tersebut mungkin telah dihapus. Admin perangkat terkelola sepenuhnya dan pengguna utama dapat menetapkan batasan ini. |
Cuplikan berikut menunjukkan cara menetapkan pembatasan:
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 saat aplikasi berada dalam mode admin sehingga
admin IT masih dapat menggunakan fitur ini untuk pemeliharaan perangkat. Untuk menghapus pembatasan, panggil DevicePolicyManager.clearUserRestriction()
.
Sembunyikan dialog error
Di beberapa lingkungan, seperti demonstrasi retail atau tampilan informasi
publik, Anda mungkin tidak ingin menampilkan dialog error kepada pengguna. Di Android 9.0 (API
level 28) atau yang lebih baru, Anda dapat menyembunyikan dialog error sistem untuk aplikasi yang error atau
tidak responsif dengan menambahkan
pembatasan pengguna
DISALLOW_SYSTEM_ERROR_DIALOGS
. Sistem akan memulai ulang aplikasi yang tidak responsif seolah-olah pengguna perangkat menutup
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 perangkat terkelola sepenuhnya menetapkan batasan ini, sistem akan menyembunyikan dialog untuk semua pengguna.
Menjaga layar agar tetap aktif
Jika membuat kios, Anda dapat menghentikan perangkat agar
tidur saat perangkat sedang menjalankan aktivitas aplikasi. Tambahkan
tanda tata letak FLAG_KEEP_SCREEN_ON
ke jendela
aplikasi 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); }
Sebaiknya periksa apakah perangkat dicolokkan ke pengisi daya AC, USB, atau
nirkabel. Daftarkan siaran perubahan baterai dan gunakan nilai BatteryManager
untuk menemukan status pengisian daya. Anda bahkan dapat mengirim peringatan jarak jauh
ke admin IT jika perangkat tidak terhubung ke sumber listrik. Untuk petunjuk langkah demi langkah, baca
Memantau Level Baterai dan Status
Pengisian Daya.
Anda juga dapat menetapkan setelan global STAY_ON_WHILE_PLUGGED_IN
agar perangkat tetap aktif saat terhubung ke sumber listrik.
Admin perangkat terkelola sepenuhnya, di Android 6.0 (API level 23) atau yang lebih baru, dapat
memanggil 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 resep untuk menginstal aplikasi secara efisien ke perangkat khusus.
Menyimpan paket aplikasi dalam cache
Jika pengguna perangkat bersama semuanya memiliki kumpulan aplikasi umum, sebaiknya hindari mendownload aplikasi jika memungkinkan. Untuk menyederhanakan penyediaan pengguna di perangkat bersama dengan sekumpulan pengguna tetap, seperti perangkat untuk pekerja shift, di Android 9.0 (API level 28) atau yang lebih baru, Anda dapat menyimpan cache paket aplikasi (APK) yang diperlukan untuk sesi multi-pengguna.
Penginstalan APK yang di-cache (yang sudah terinstal di perangkat) terjadi dalam dua tahap:
- Komponen admin dari perangkat yang terkelola sepenuhnya (atau delegasi—lihat berikut) menetapkan daftar APK yang akan dipertahankan di perangkat.
- Komponen admin dari pengguna sekunder yang berafiliasi (atau delegasinya) dapat menginstal APK yang di-cache atas nama pengguna. Admin perangkat terkelola sepenuhnya, pengguna utama, atau profil kerja yang berafiliasi (atau delegasinya) juga dapat menginstal aplikasi yang di-cache jika diperlukan.
Untuk menetapkan daftar APK yang akan dipertahankan di perangkat, admin akan memanggil
DevicePolicyManager.setKeepUninstalledPackages()
.
Metode ini tidak memeriksa apakah APK telah diinstal di perangkat—berguna jika Anda
ingin menginstal aplikasi tepat 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 pengguna
sekunder dihapus, sistem akan menghapus APK yang di-cache yang tidak diperlukan lagi.
Untuk menginstal APK yang di-cache, panggil
DevicePolicyManager.installExistingPackage()
.
Metode ini hanya dapat menginstal aplikasi yang telah di-cache oleh sistem—solusi perangkat
khusus Anda (atau pengguna perangkat) harus terlebih dahulu menginstal aplikasi di
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);
Mendelegasikan aplikasi
Anda dapat mendelegasikan aplikasi lain untuk mengelola cache aplikasi. Anda dapat melakukannya untuk
memisahkan fitur solusi atau menawarkan kemampuan kepada admin IT untuk menggunakan
aplikasi mereka sendiri. Aplikasi delegasi mendapatkan izin yang sama dengan komponen
admin. Misalnya, delegasi aplikasi dari admin pengguna sekunder dapat memanggil
installExistingPackage()
, tetapi tidak dapat memanggil setKeepUninstalledPackages()
.
Untuk membuat delegasi, panggil DevicePolicyManager.setDelegatedScopes()
dan sertakan DELEGATION_KEEP_UNINSTALLED_PACKAGES
dalam argumen cakupan. Contoh berikut menunjukkan cara agar aplikasi lain
dapat menjadi 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 siaran
ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED
dan menjadi delegasi. Aplikasi dapat memanggil metode dalam panduan ini
seolah-olah aplikasi tersebut adalah pemilik perangkat atau pemilik profil. Saat memanggil
metode DevicePolicyManager
, delegasi akan meneruskan null
untuk argumen
komponen admin.
Menginstal paket aplikasi
Terkadang, ada gunanya menginstal aplikasi kustom yang di-cache secara lokal ke perangkat
khusus. Misalnya, perangkat khusus sering di-deploy ke lingkungan atau area dengan bandwidth terbatas tanpa konektivitas internet. Solusi
perangkat khusus Anda harus memperhatikan bandwidth pelanggan. Aplikasi
Anda dapat memulai penginstalan paket aplikasi (APK) lain menggunakan
class PackageInstaller
.
Meskipun aplikasi apa pun dapat menginstal APK, admin di perangkat yang terkelola sepenuhnya dapat menginstal (atau meng-uninstal) paket tanpa interaksi pengguna. Admin dapat mengelola perangkat, pengguna sekunder yang berafiliasi, atau profil kerja yang berafiliasi. Setelah menyelesaikan penginstalan, sistem akan memposting notifikasi yang dilihat oleh semua pengguna perangkat. Notifikasi ini memberi tahu pengguna perangkat bahwa aplikasi telah diinstal (atau diupdate) oleh admin mereka.
Versi Android | Komponen admin untuk penginstalan dan uninstal |
---|---|
Android 9.0 (API level 28) atau yang lebih tinggi | Pengguna sekunder dan profil kerja yang berafiliasi—baik di perangkat yang terkelola sepenuhnya |
Android 6.0 (API level 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 tersebut dan mungkin seberapa jauh jarak perangkat 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 satu
atau beberapa APK untuk diinstal. Pada contoh berikut, kita menerima masukan status dalam aktivitas (mode singleTop), tetapi Anda dapat menggunakan
layanan atau penerima siaran:
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 ini mengirimkan masukan status tentang penginstalan menggunakan intent. Periksa
setiap kolom EXTRA_STATUS
intent untuk mendapatkan
status. Ingat, admin tidak menerima
update status STATUS_PENDING_USER_ACTION
karena pengguna perangkat tidak perlu menyetujui penginstalan.
Untuk meng-uninstal aplikasi, Anda dapat memanggil PackageInstaller.uninstall
.
Admin perangkat terkelola sepenuhnya, pengguna, dan profil kerja dapat meng-uninstal paket
tanpa interaksi pengguna yang menjalankan versi Android yang didukung (lihat
tabel 2).
Membekukan update sistem
Perangkat Android menerima update over the air (OTA) untuk software sistem dan aplikasi. Untuk membekukan versi OS selama periode penting, seperti hari libur atau waktu sibuk lainnya, perangkat khusus dapat menangguhkan update sistem OTA hingga 90 hari. Untuk mempelajari lebih lanjut, baca Mengelola update sistem.
Remote config
Konfigurasi terkelola Android memungkinkan admin IT mengonfigurasi aplikasi dari jarak jauh. Anda dapat menampilkan setelan seperti daftar yang diizinkan, host jaringan, atau URL konten agar aplikasi lebih berguna bagi admin IT.
Jika aplikasi Anda mengekspos konfigurasinya, jangan lupa untuk menyertakan setelan dalam dokumentasi Anda. Untuk mempelajari lebih lanjut cara mengekspos konfigurasi aplikasi dan merespons perubahan setelan, baca Menyiapkan konfigurasi terkelola.
Penyiapan pengembangan
Saat Anda mengembangkan solusi untuk perangkat khusus, terkadang ada baiknya untuk menetapkan aplikasi Anda sebagai admin perangkat yang terkelola sepenuhnya tanpa mereset ke setelan pabrik. Untuk menyetel admin perangkat terkelola sepenuhnya, ikuti langkah-langkah berikut:
- Bangun dan instal aplikasi pengontrol kebijakan perangkat (DPC) di perangkat.
- Pastikan tidak ada akun di perangkat.
Jalankan perintah berikut di shell Android Debug Bridge (adb). Anda harus 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 men-deploy solusi, Anda harus melihat metode pendaftaran lain. Sebaiknya pendaftaran kode QR untuk perangkat khusus.
Referensi lainnya
Untuk mempelajari perangkat khusus lebih lanjut, baca dokumen berikut: