Mem-build aplikasi yang mendukung multi-pengguna

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

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

Fasilitas ini:

  • Menghemat resource
  • Menyelesaikan sengketa satu atau beberapa resource bersama di seluruh pengguna
  • Mengurangi overhead jaringan dengan menggunakan satu koneksi server

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

Alur izin beberapa pengguna

Gambar 1. Izin beberapa pengguna

Mengaktifkan komponen singleton

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

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

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

Berinteraksi dengan pengguna

Setel izin

Izin berikut diperlukan:

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

Menggunakan API

Gunakan API berikut untuk membuat aplikasi mengetahui beberapa pengguna.

  1. Ekstrak nama sebutan pengguna dari panggilan Binder yang masuk:
    • int userHandle = UserHandle.getCallingUserId()
  2. Gunakan API baru yang dilindungi untuk memulai layanan, aktivitas, siaran di pengguna tertentu:
    • 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 di aplikasi Anda sendiri: (INTERACT_ACROSS_USERS) Atau dengan komponen di aplikasi lain: (INTERACT_ACROSS_USERS_FULL)
  4. Anda mungkin perlu membuat komponen proxy yang berjalan dalam proses pengguna yang kemudian mengakses komponen singleUser di pengguna 0.
  5. Buat kueri pengguna dan nama sebutan channel mereka dengan layanan sistem UserManager baru:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle) - nomor yang tidak didaur ulang yang sesuai dengan nama sebutan pengguna.
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles() - menampilkan kumpulan profil mandiri dan terkelola, jika ada.
  6. Daftar untuk memproses pengguna tertentu atau semua pengguna dan callback dengan API baru di ContentObserver, PackageMonitor, BroadcastReceiver yang memberikan informasi tambahan tentang pengguna 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 berjalan sebagai pengguna 0, nonaktifkan komponen layanan saat berjalan di bawah pengguna lain untuk membantu menghemat resource. Contoh berikut menunjukkan cara melakukannya di titik entri layanan:

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