Çok kullanıcılı uygulamalar geliştirme

Bir cihaz birden fazla kullanıcıyı desteklediğinde, uygulamalarının bu farklı kullanıcılardan haberdar olması gerekir.

Bazı uygulamaların bazı bileşenlerinin tekil olarak çalıştırılması ve herhangi bir kullanıcıdan istek kabul edebilmesi gerekir. Bu özelliği şu anda yalnızca sistem uygulamaları kullanabilir.

Bu tesis:

  • Kaynakları korur
  • Kullanıcılar arasında bir veya daha fazla paylaşılan kaynağın arabuluculuğunu yapar.
  • Tek bir sunucu bağlantısı kullanarak ağ ek yükünü azaltır

Birden fazla kullanıcının bulunduğu izin akışı için aşağıdaki şemaya bakın.

Birden fazla kullanıcı izin akışı

Şekil 1. Birden fazla kullanıcının izinleri

Tekil bileşeni etkinleştirme

Bir uygulamayı tekil olarak tanımlamak için Android manifest dosyasında hizmetinize, alıcınıza veya sağlayıcınıza android:singleUser="true" ekleyin.

Sistem, bu bileşeni yalnızca 0 numaralı kullanıcı olarak çalışan işlemde oluşturur. Herhangi bir kullanıcıdan bu sağlayıcıya veya hizmete bağlanma ya da bu alıcıya yayın yapma istekleri, 0 numaralı kullanıcıdaki işleme yönlendirilir. Uygulamanızdaki tek bileşen bu ise uygulamanızın yalnızca bir örneği çalışır.

Paketinizdeki etkinlikler her kullanıcı için ayrı bir işlemde başlatılmaya devam eder. UID, ilgili kullanıcının UID aralığındadır (ör. 1010034).

Kullanıcılarla etkileşim kurma

İzinleri ayarla

Aşağıdaki izinler gereklidir:

INTERACT_ACROSS_USERS (signature|system)
INTERACT_ACROSS_USERS_FULL (signature)

API'leri kullanma

Uygulamaların birden fazla kullanıcıdan haberdar olması için aşağıdaki API'leri kullanın.

  1. Gelen Binder çağrılarından kullanıcı herkese açık kullanıcı adını ayıklayın:
    • int userHandle = UserHandle.getCallingUserId()
  2. Belirli bir kullanıcıda hizmet, etkinlik veya yayın başlatmak için yeni ve korumalı API'leri kullanın:
    • Context.startActivityAsUser(Intent, UserHandle)
    • Context.bindServiceAsUser(Intent, …, UserHandle)
    • Context.sendBroadcastAsUser(Intent, … , UserHandle)
    • Context.startServiceAsUser(Intent, …, UserHandle)
    UserHandle, gerçek bir kullanıcı veya özel herkese açık kullanıcı adlarından biri olabilir: UserHandle.CURRENT veya UserHandle.ALL. CURRENT, şu anda ön planda olan kullanıcıyı gösterir. Tüm kullanıcılara yayın göndermek istediğinizde ALL simgesini kullanın.
  3. Kendi uygulamanızdaki bileşenlerle iletişim kurma: (INTERACT_ACROSS_USERS) Veya diğer uygulamalardaki bileşenlerle iletişim kurma: (INTERACT_ACROSS_USERS_FULL)
  4. Kullanıcının sürecinde çalışan ve ardından 0 numaralı kullanıcıdaki singleUser bileşenine erişen proxy bileşenleri oluşturmanız gerekebilir.
  5. Yeni UserManager sistem hizmetini kullanarak kullanıcıları ve herkese açık kullanıcı adlarını sorgulayın:
    • UserManager.getUsers()
    • UserManager.getUserInfo()
    • UserManager.supportsMultipleUsers()
    • UserManager.getUserSerialNumber(int userHandle): Kullanıcı herkese açık kullanıcı adına karşılık gelen, yeniden kullanılmayan bir sayı.
    • UserManager.getUserHandle(int serialNumber)
    • UserManager.getUserProfiles(): Kendi profilinizi ve varsa yönetilen profillerin koleksiyonunu döndürür.
  6. Belirli veya tüm kullanıcıları ve geri çağırma işlemlerini dinlemek için ContentObserver, PackageMonitor, BroadcastReceiver'da yeni API'lerle kaydolun. Bu API'ler, geri çağırma işlemine hangi kullanıcının neden olduğu hakkında ek bilgi sağlar.

Birden fazla kullanıcı veya profildeki hizmetler

Tüm hizmetlerin başka bir kullanıcı veya iş profilinde bir örnek çalıştırması gerekmez. Sistem hizmetinizin yalnızca 0 numaralı kullanıcı olarak çalışması gerekiyorsa kaynakları korumak için hizmetin diğer kullanıcılar altında çalışırken bileşenlerini devre dışı bırakın. Aşağıdaki örnekte, bunu hizmetinizin giriş noktalarında nasıl yapabileceğiniz gösterilmektedir:

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

Örnekte, uygulamanın tamamını devre dışı bırakmak için PackageManager.setApplicationEnabledSetting() de kullanılabilir.