Membangun Aplikasi Multipengguna

Jika perangkat mendukung beberapa pengguna, aplikasi perangkat harus mengetahui para pengguna yang berbeda ini.

Aplikasi tertentu perlu memiliki beberapa komponen yang dijalankan sebagai singleton dan dapat menerima permintaan dari pengguna mana pun. Saat ini hanya aplikasi sistem yang dapat menggunakan fitur ini.

Fasilitas ini:

  • Menghemat resource
  • Arbitrase satu atau beberapa resource bersama dengan semua pengguna
  • Mengurangi beban jaringan dengan menggunakan koneksi server tunggal

Lihat diagram di bawah untuk gambaran alur izin dengan beberapa pengguna.

Alur izin multi-pengguna

Gambar 1. Izin multi-pengguna

Mengaktifkan komponen singleton

Untuk mengidentifikasi aplikasi sebagai singleton, tambahkan android:singleUser="true" ke layanan Anda. penerima, atau penyedia dalam manifes Android.

Sistem akan membuat instance komponen tersebut dalam proses yang berjalan sebagai pengguna 0 saja. Setiap permintaan untuk terhubung ke penyedia atau layanan itu, atau untuk menyiarkan ke penerima itu, dari setiap pengguna akan diarahkan ke proses di pengguna 0. Jika ini adalah satu-satunya komponen di aplikasi Anda, hanya satu instance aplikasi yang akan berjalan.

Aktivitas dalam paket Anda tetap akan diluncurkan dalam proses terpisah untuk setiap pengguna, dengan UID dalam rentang UID untuk pengguna tersebut (seperti 1010034).

Berinteraksi dengan pengguna

Setel izin

Izin ini diperlukan

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

Menggunakan API

Gunakan API berikut agar aplikasi dapat mengenali beberapa pengguna.

  1. Ekstrak nama sebutan channel pengguna dari panggilan Binder yang masuk:
    • int userHandle = UserHandle.getCallingUserId()
  2. Gunakan API baru yang dilindungi untuk memulai layanan, aktivitas, dan siaran di pengguna:
    • Context.startActivityAsUser(Intent, UserHandle)
    • Context.bindServiceAsUser(Intent, …, UserHandle)
    • Context.sendBroadcastAsUser(Intent, … , UserHandle)
    • Context.startServiceAsUser(Intent, …, UserHandle)
    UserHandle dapat berupa pengguna eksplisit atau salah satu nama sebutan channel khusus: UserHandle.CURRENT atau UserHandle.ALL. CURRENT menunjukkan pengguna yang saat ini berada di latar depan. Gunakan ALL saat Anda ingin mengirim siaran ke semua pengguna.
  3. Berkomunikasi dengan komponen dalam aplikasi Anda sendiri: (INTERACT_ACROSS_USERS) Atau dengan komponen di aplikasi lain: (INTERACT_ACROSS_USERS_FULL)
  4. Anda mungkin perlu membuat komponen {i>proxy<i} yang berjalan dalam proses pengguna yang lalu akses komponen singleUser di pengguna 0.
  5. Buat kueri pengguna dan nama sebutan channel mereka dengan layanan sistem UserManager yang baru:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle) - angka yang tidak didaur ulang yang sesuai dengan nama sebutan channel pengguna.
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() - menampilkan kumpulan profil mandiri dan profil terkelola, jika ada.
  6. Daftar untuk memproses pengguna tertentu atau semua pengguna dan callback dengan API baru aktif ContentObserver, PackageMonitor, BroadcastReceiver yang menyediakan informasi tentang pengguna mana yang menyebabkan callback.

Layanan di beberapa pengguna atau profil

Tidak semua layanan perlu menjalankan instance di profil kerja atau pengguna lain. Jika layanan sistem Anda hanya perlu dijalankan sebagai pengguna 0, nonaktifkan komponen layanan ketika berjalan di bawah pengguna lain untuk membantu melestarikan sumber daya. Contoh berikut menunjukkan cara melakukannya di entri layanan Anda poin:

// Add on all entry points such as boot_completed or other manifest-listed receivers and providers
if (!UserManager.isSystemUser()) {
    // Disable the service
    ComponentName targetServiceName = new ComponentName(this, TargetService.class);
    context.getPackageManager().setComponentEnabledSetting(
        targetServiceName, COMPONENT_ENABLED_STATE_DISABLED, 0);
}

Contoh ini juga dapat menggunakan PackageManager.setApplicationEnabledSetting() untuk menonaktifkan seluruh aplikasi.