İçerik hiyerarşinizi oluşturun

Android Auto ve Android Automotive OS (AAOS), hangi içeriğin kullanılabildiğini öğrenmek için uygulamanızın medya tarayıcı hizmetini çağırır. Bunu desteklemek için medya tarayıcı hizmetinizde bu iki yöntemi uygulayın.

onGetRoot'u uygulama

Hizmetinizin onGetRoot yöntemi, içerik hiyerarşinizin kök düğümü hakkında bilgi döndürür. Android Auto ve AAOS, onLoadChildren yöntemini kullanarak içeriklerinizin geri kalanını istemek için bu kök düğümü kullanır. Bu kod snippet'inde onGetRoot yönteminin bir uygulaması gösterilmektedir:

Kotlin

override fun onGetRoot(
    clientPackageName: String,
    clientUid: Int,
    rootHints: Bundle?
): BrowserRoot? =
    // Verify that the specified package is allowed to access your
    // content. You'll need to write your own logic to do this.
    if (!isValid(clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return null.
        // No further calls will be made to other media browsing methods.

        null
    } else MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null)

Java

@Override
public BrowserRoot onGetRoot(String clientPackageName, int clientUid,
    Bundle rootHints) {

    // Verify that the specified package is allowed to access your
    // content. You'll need to write your own logic to do this.
    if (!isValid(clientPackageName, clientUid)) {
        // If the request comes from an untrusted package, return null.
        // No further calls will be made to other media browsing methods.

        return null;
    }

    return new MediaBrowserServiceCompat.BrowserRoot(MY_MEDIA_ROOT_ID, null);
}

Bu yöntemle ilgili ayrıntılı bir örnek için GitHub'daki Universal Android Music Player örnek uygulamasında onGetRoot bölümüne bakın.

Paket doğrulaması ekleme

Hizmetinizin onGetRoot yöntemine bir arama yapıldığında, arayan paket, tanımlayıcı bilgileri hizmetinize iletir. Hizmetiniz, bu bilgileri kullanarak paketin içeriğinize erişip erişemeyeceğine karar verebilir.

Örneğin, uygulamanızın içeriğine erişimi onaylı paketlerin listesiyle kısıtlayabilirsiniz:

  • clientPackageName ile izin verilenler listenizi karşılaştırın.
  • Paketin APK'sını imzalamak için kullanılan sertifikayı doğrulayın.

Paket doğrulanamazsa içeriğinize erişimi reddetmek için null döndürün.

Android Auto ve AAOS gibi sistem uygulamalarının içeriğinize erişebilmesi için hizmetiniz, bu sistem uygulamaları onGetRoot yöntemini çağırdığında boş olmayan bir BrowserRoot döndürmelidir.

AAOS sistem uygulamasının imzası, arabanın markasına ve modeline göre değişir. AAOS'u desteklemek için tüm sistem uygulamalarından gelen bağlantılara izin verdiğinizden emin olun.

Bu kod snippet'inde, hizmetinizin arayan paketin bir sistem uygulaması olduğunu nasıl doğrulayabileceği gösterilmektedir:

fun isKnownCaller(
    callingPackage: String,
    callingUid: Int
): Boolean {
    ...
    val isCallerKnown = when {
       // If the system is making the call, allow it.
       callingUid == Process.SYSTEM_UID -> true
       // If the app was signed by the same certificate as the platform
       // itself, also allow it.
       callerSignature == platformSignature -> true
       // ... more cases
    }
    return isCallerKnown
}

Bu kod snippet'i, GitHub'daki Universal Android Music Player örnek uygulamasında bulunan PackageValidator sınıfından alınmıştır. Hizmetinizin onGetRoot yöntemi için paket doğrulamasını nasıl uygulayacağınızla ilgili daha ayrıntılı bir örnek için bu sınıfa bakın.

Sistem uygulamalarına izin vermenin yanı sıra Google Asistan'ın MediaBrowserService cihazınıza bağlanmasına da izin vermeniz gerekir. Google Asistan, Android Auto Android AAOS'nin de dahil olduğu telefon için ayrı paket adları kullanır.

onLoadChildren'ı uygulama

Kök düğüm nesnenizi aldıktan sonra Android Auto ve AAOS, kök düğüm nesnesinde onLoadChildren çağrısı yaparak üst düzey bir menü oluşturur. İstemci uygulamaları, alt öğe düğümü nesnelerini kullanarak aynı yöntemi çağırarak alt menüler oluşturur.

İçerik hiyerarşinizdeki her düğüm bir MediaBrowserCompat.MediaItem nesnesiyle temsil edilir. Bu medya öğelerinin her biri benzersiz bir kimlik dizesiyle tanımlanır. İstemci uygulamaları bu kimlik dizelerini opak jetonlar olarak ele alır.

Bir istemci uygulaması, alt menüye göz atmak veya bir medya öğesini oynatmak istediğinde jetonu iletir. Uygulamanız, jetonu uygun medya öğesiyle ilişkilendirmekten sorumludur.

Bu kod snippet'i, onLoadChildren uygulamasını gösterir.

Kotlin

override fun onLoadChildren(
    parentMediaId: String,
    result: Result<List<MediaBrowserCompat.MediaItem>>
) {
    // Assume for example that the music catalog is already loaded/cached.

    val mediaItems: MutableList&lt;MediaBrowserCompat.MediaItem> = mutableListOf()

    // Check if this is the root menu:
    if (MY_MEDIA_ROOT_ID == parentMediaId) {

        // Build the MediaItem objects for the top level
        // and put them in the mediaItems list.
    } else {

        // Examine the passed parentMediaId to see which submenu we're at
        // and put the descendants of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems)
}

Java

@Override
public void onLoadChildren(final String parentMediaId,
    final Result&lt;List&lt;MediaBrowserCompat.MediaItem>> result) {

    // Assume for example that the music catalog is already loaded/cached.

    List&lt;MediaBrowserCompat.MediaItem> mediaItems = new ArrayList&lt;>();

    // Check if this is the root menu:
    if (MY_MEDIA_ROOT_ID.equals(parentMediaId)) {

        // Build the MediaItem objects for the top level
        // and put them in the mediaItems list.
    } else {

        // Examine the passed parentMediaId to see which submenu we're at
        // and put the descendants of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems);
}

Bu yöntemin bir örneğini görmek için GitHub'daki Universal Android Music Player örnek uygulamasında onLoadChildren bölümüne bakın.

Kök menüyü yapılandırma

Android Auto ve Android Automotive OS'in, kök menü yapısıyla ilgili belirli kısıtlamaları vardır. Bunlar, MediaBrowserService kök ipuçları aracılığıyla iletilir. Kök ipuçları, onGetRoot()'ye iletilen Bundle bağımsız değişkeni aracılığıyla okunabilir. Bu ipuçları uygulandığında sistem, kök içeriği gezinme sekmeleri olarak gösterebilir. Bu ipuçlarını dikkate almazsanız bazı temel içerikler sistem tarafından kaldırılabilir veya daha az bulunabilir hale getirilebilir.

Kök içerik, gezinme sekmeleri olarak gösterilir.

1.şekil Kök içerik, gezinme sekmeleri olarak gösterilir.

Bu ipuçları uygulandığında sistem, kök içeriği gezinme sekmeleri olarak gösterir. Bu ipuçları uygulanmadığında bazı kök içerikler bırakılabilir veya daha az görünür hale gelebilir. Bu ipuçları şu şekilde iletilir:

Kotlin

import androidx.media.utils.MediaConstants

override fun onGetRoot(
    clientPackageName: String,
    clientUid: Int,
    rootHints: Bundle
): BrowserRoot {

  val maximumRootChildLimit = rootHints.getInt(
      MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
      /* defaultValue= */ 4)
  val supportedRootChildFlags = rootHints.getInt(
      MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
      /* defaultValue= */ MediaItem.FLAG_BROWSABLE)

  // Rest of method...
}

Java

import androidx.media.utils.MediaConstants;

// Later, in your MediaBrowserServiceCompat.
@Override
public BrowserRoot onGetRoot(
    String clientPackageName, int clientUid, Bundle rootHints) {

    int maximumRootChildLimit = rootHints.getInt(
        MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_LIMIT,
        /* defaultValue= */ 4);
    int supportedRootChildFlags = rootHints.getInt(
        MediaConstants.BROWSER_ROOT_HINTS_KEY_ROOT_CHILDREN_SUPPORTED_FLAGS,
        /* defaultValue= */ MediaItem.FLAG_BROWSABLE);

    // Rest of method...
}

İçerik hiyerarşinizin yapısıyla ilgili mantığı, özellikle hiyerarşiniz Android Auto ve AAOS dışındaki MediaBrowser entegrasyonlarında farklılık gösteriyorsa bu ipuçlarının değerlerine göre dallandırmayı seçebilirsiniz.

Örneğin, normalde bir kök oynanabilir öğe gösteriyorsanız desteklenen işaretlerin ipucu değeri nedeniyle bunu bir kök göz atılabilir öğenin altına yerleştirmek isteyebilirsiniz.

Kök ipuçlarının yanı sıra sekmeleri en iyi şekilde oluşturmak için aşağıdaki yönergeleri kullanın:

  • Her sekme öğesi için tek renkli (tercihen beyaz) simgeler

  • Her sekme öğesi için kısa ve anlamlı etiketler (kısa etiketler, etiketlerin kesilme olasılığını azaltır)