Arabalar için medya uygulamaları oluşturma

Android Auto ve Android Automotive OS, medya uygulamanızın içeriğini araçlarında etkiniz. Arabalara yönelik bir medya uygulaması, medya tarayıcı hizmeti sağlamalıdır Android Auto ve Android Automotive OS'i ya da medya içeriği olan başka bir uygulamayı içeriğinizi keşfedip görüntüleyebilir.

Bu kılavuzda, şurada ses çalan bir medya uygulamanızın zaten olduğu varsayılmıştır: ve medya uygulamanızın Android medya uygulamasına mimari.

Bu kılavuzda MediaBrowserService ve Uygulamanızın Android Auto veya Android'de çalışması için gereken MediaSession Automotive OS. Temel medya altyapısını tamamladıktan sonra, Android Auto için destek ekleyin ve şura için destek ekleyin: Android Automotive OS'ten medyanıza ekleme uygulamasını indirin.

Başlamadan önce

  1. Android media API dokümanlarını inceleyin.
  2. Medya uygulamaları oluşturma başlıklı makaleyi inceleyin inceleyin.
  3. Bu bölümde listelenen önemli terimleri ve kavramları inceleyin.

Anahtar terimler ve kavramlar

Medya tarayıcı hizmeti
Medya uygulamanız tarafından uygulanan ve MediaBrowserServiceCompat API'ye gidin. Uygulamanız, içeriğini göstermek için bu hizmeti kullanıyor.
Medya tarayıcısı
Medya uygulamaları tarafından medya tarayıcı hizmetlerini keşfetmek ve bunları görüntülemek için kullanılan bir API en iyi yoludur. Android Auto ve Android Automotive OS, şu işlemleri gerçekleştirmek için bir medya tarayıcısı kullanır: uygulamanızın medya tarayıcı hizmetini bulabilirsiniz.
Medya öğesi

Medya tarayıcısı, içeriğini MediaItem ağacında düzenler nesneler'i tıklayın. Bir medya öğesi, aşağıdaki işaretlerin birine veya her ikisine sahip olabilir:

  • FLAG_PLAYABLE: Öğenin, içerik ağacında bir yaprak olduğunu belirtir. Öğe, albümdeki bir şarkı gibi tek bir ses akışını temsil eder. sesli kitaptaki bir bölüm veya bir podcast'in bir bölümü.
  • FLAG_BROWSABLE: Öğenin içerik ağacında bir düğüm olduğunu ve çocukları var. Örneğin, öğe bir albümü temsil eder ve alt öğeleri albümdeki şarkılar.

Hem göz atılabilen hem de oynatılabilen bir medya öğesi, oynatma listesi işlevi görür. Şunları yapabilirsiniz: öğenin kendisini seçerek tüm alt öğelerini oynatabilir veya öğeye göz atabilirsiniz

Araç için optimize edilmiş

Android Automotive OS uygulaması için şu şartlara uyan etkinlik: Android Automotive OS tasarım yönergeleri. Bu etkinliklerin arayüzü Android Automotive OS tarafından çizilmez. Bu nedenle uygulamanızın tasarım yönergelerine uymasını sağlamalıdır. Genellikle bu daha büyük dokunma hedefleri ile yazı tipi boyutlarını, gündüz ve gece modlarını desteklemeyi içerir. yüksek kontrast oranlarına sahip olabilir.

Araç için optimize edilmiş kullanıcı arayüzlerinin yalnızca Araba kullanıcıları tarafından gösterilmesine izin verilir. Kullanıcı Deneyimi Kısıtlamaları (CUXR) yürürlükte değildir. Bu kısıtlamalar arayüzler, kullanıcının daha fazla dikkatini çekmesini veya etkileşimde bulunmasını gerektirebilir. CUXR'ler araç durduğunda veya park edildiğinde etkin değil, ancak her zaman etkin araç hareket halindeyken.

Android Auto için etkinlikler tasarlamanız gerekmez. Android Auto, bilgileri kullanarak kendi araç için optimize edilmiş arayüzünü çizer medya tarayıcı hizmeti.

Uygulamanızın manifest dosyalarını yapılandırma

Medya tarayıcısı hizmetinizi oluşturmadan önce Uygulamanın manifest dosyalarına uyması gerekir.

Medya tarayıcı hizmetinizi bildirin

Hem Android Auto hem de Android Automotive OS, uygulamanıza medya tarayıcı hizmeti. Medyanızı bildirin Android Auto ve Android Automotive OS'e izin vermek için manifest dosyanıza bir tarayıcı hizmeti ekleyin hizmeti keşfedip uygulamanıza bağlanın.

Aşağıdaki kod snippet'i, manifest dosyanız. Bu kodu Android Automotive OS modülünde ve telefon uygulamanızın manifest dosyasında.

<application>
    ...
    <service android:name=".MyMediaBrowserService"
             android:exported="true">
        <intent-filter>
            <action android:name="android.media.browse.MediaBrowserService"/>
        </intent-filter>
    </service>
    ...
</application>

Uygulama simgelerini belirleyin

Android Auto ve Android Automotive OS'in kullanabileceği uygulama simgelerini belirtmeniz gerekir temsil etmek için kullanabilirsiniz. İki simge türü gereklidir:

  • Başlatıcı simgesi
  • İlişkilendirme simgesi
ziyaret edin.

Başlatıcı simgesi

Başlatıcı simgesi, uygulamanızı sistem arayüzünde (ör. başlatıcıdaki) temsil eder. simge tepsisinde görürsünüz. Şuradaki simgeyi kullanmak istediğinizi belirtebilirsiniz: mobil uygulamanızı aşağıdaki manifesti kullanarak araba medya uygulamanızı temsil edecek beyan:

<application
    ...
    android:icon="@mipmap/ic_launcher"
    ...
/>

Mobil uygulamanızdan farklı bir simge kullanmak için android:icon özelliğini ayarlayın medya tarayıcı hizmetinizin manifest dosyasındaki <service> öğesinde:

<application>
    ...
    <service
        ...
        android:icon="@mipmap/auto_launcher"
        ...
    />
</application>

İlişkilendirme simgesi

Şekil 1. Medya kartındaki ilişkilendirme simgesi.

Atıf simgesi, medya içeriğinin öncelikli olduğu yerlerde kullanılır. medya kartlarında çalışır. Bildirimler için kullanılan küçük simgeyi yeniden kullanabilirsiniz. Bu simge tek renkli olmalıdır. Hedef EBM'yi temsil etmek için kullanılan aşağıdaki manifest beyanını kullanarak uygulamanız gerekir:

<application>
    ...
    <meta-data
        android:name="androidx.car.app.TintableAttributionIcon"
        android:resource="@drawable/ic_status_icon" />
    ...
</application>

Medya tarayıcı hizmetinizi oluşturma

MediaBrowserServiceCompat uzantısını genişleterek bir medya tarayıcısı hizmeti oluşturursunuz sınıfını kullanır. Böylece hizmetinizi hem Android Auto hem de Android Automotive OS kullanabilir şunları yapabilirsiniz:

  • Kullanıcıya bir menü sunmak için uygulamanızın içerik hiyerarşisine göz atın.
  • Uygulamanızın MediaSessionCompat jetonunu alın nesnesini ifade eder.

Ayrıca, medya tarayıcı hizmetinizi kullanarak diğer istemcilerin uygulamanızdan medya içeriğine erişin. Bu medya istemcileri, veya başka uzak istemciler olabilir.

Medya tarayıcısı hizmeti iş akışı

Bu bölümde, Android Automotive OS ve Android'in Normal bir kullanıcı iş akışı sırasında medya tarayıcısı hizmetinizle otomatik olarak etkileşimde bulunun.

  1. Kullanıcı, uygulamanızı Android Automotive OS veya Android Auto'da başlatır.
  2. Android Automotive OS veya Android Auto, uygulamanızın medya tarayıcısıyla iletişim kurar onCreate() kullanılan hizmet yöntemidir. onCreate() uygulamanızda bir MediaSessionCompat oluşturup kaydetmeniz gerekir. nesnesini ve geri çağırma nesnesini tanımlayın.
  3. Android Automotive OS veya Android Auto, hizmetinizin onGetRoot() numarasını arar yöntemini kullanabilirsiniz. Kök medya öğesi görüntülenmez; bunun yerine, uygulamanızdan daha fazla içerik almak için kullanılır.
  4. Android Automotive OS veya Android Auto, hizmetinizin onLoadChildren() yöntemini çağırın. Android Automotive OS ve Android Auto, bu medya öğelerini en üst düzey içerik öğeleri olarak gösterir. Görüntüleyin Daha fazla bilgi için bu sayfadaki kök menüyü yapılandırın düzeyde bilgi edinmesine olanak tanır.
  5. Kullanıcı göz atılabilir bir medya öğesi seçerse, hizmetin onLoadChildren(). yöntemi, seçilen menü öğesinin alt öğelerini almak için tekrar çağrılır.
  6. Kullanıcı, oynatılabilir bir medya öğesi seçerse (Android Automotive OS veya Android) Otomatik olarak, bu işlemi gerçekleştirmek için uygun medya oturumu geri çağırma yöntemi çağrılır.
  7. Uygulamanız destekliyorsa kullanıcı da içeriğinizde arama yapabilir. Burada Android Automotive OS veya Android Auto için hizmetinizin onSearch() yöntemidir.

İçerik hiyerarşinizi oluşturma

Android Auto ve Android Automotive OS, uygulamanızın medya tarayıcısı hizmetini çağırarak şunu yapar: ve hangi içeriklerin sunulduğunu öğrenin. Belgenizde iki yöntem uygulamanız gerekiyor. destekleyen medya tarayıcısı hizmeti: onGetRoot() ve onLoadChildren()

onGetRoot'u uygulama

Hizmetinizin onGetRoot() yöntemi, içerik hiyerarşinizin kök düğümüyle ilgili bilgileri döndürür. Android Auto ve Android Automotive OS, bu kök düğümü kullanarak içeriğinizi onLoadChildren() yöntemidir.

Aşağıdaki kod snippet'i, onGetRoot() yöntem:

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öntemin daha ayrıntılı bir örneği için onGetRoot() bölümüne bakın yöntemini kullanabilirsiniz.

onGetRoot() için paket doğrulaması ekleme

Hizmetinizin onGetRoot() numarasına arama yapıldığında yöntemini kullanıyorsanız çağrı paketi, tanımlayıcı bilgileri hizmetinize iletir. Sizin hizmeti, ilgili paketin hesabınıza erişip erişemeyeceğini belirlemek için içerik. Örneğin, uygulamanızın içeriğine erişimi belirli bir izin verilenler listesiyle clientPackageName ile izin verilenler listenizi karşılaştırarak ve Paketin APK'sını imzalamak için kullanılan sertifikayı doğrular. Paketin durumu doğrulama işleminin ardından, içeriğinize erişimi reddetmek için null URL'sini döndürün.

Android Auto ve Android Automotive OS gibi sistem uygulamaları sağlamak için içeriğinize erişimi varsa hizmetiniz her zaman boş olmayan bir değer döndürmelidir Bu sistem uygulamaları onGetRoot() çağırdığında BrowserRoot yöntemidir. Android Automotive OS sistem uygulamasının imzası bağlı olarak değişiklik gösterebilir marka ve modeline göre değişiklik gösterir. Bu nedenle, Android Automotive OS'i güçlü bir şekilde destekleyecek sistem uygulamaları geliştirildi.

Aşağıdaki kod snippet'i, hizmetinizin arama paketi bir sistem uygulamasıdır:

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, PackageValidator sınıfını anlatacağım. O sınıfı göster için paket doğrulamasını nasıl uygulayacağınıza ilişkin daha ayrıntılı bir örnek hizmetin onGetRoot() yöntemidir.

Google Asistan'ın, sistem uygulamalarına izin vermenin yanı sıra, MediaBrowserService cihazınıza bağlanın. Google Asistan'ın ayrı paket adları (Android Auto ve Android Automotive OS için)

onLoadChildren() işlevini uygulama

Kök düğüm nesnenizi aldıktan sonra Android Auto ve Android Automotive OS onLoadChildren() numaralı telefonu arayarak üst düzey bir menü oluşturmak öğesini eklemeniz gerekir. İstemci uygulamaları, aşağıdaki ölçütlere göre alt menüler oluşturur: alt düğüm nesneleri kullanılarak aynı yöntemi çağrıştırması gerekir.

İçerik hiyerarşinizdeki her düğüm bir MediaBrowserCompat.MediaItem ile temsil edilir. nesnesini tanımlayın. Bu medya öğelerinin her biri benzersiz bir kimlik dizesiyle tanımlanır. Müşteri uygulamalar bu kimlik dizelerini opak jetonlar olarak işler. Bir istemci uygulaması göz atmak istediğinde veya bir medya öğesini oynattığında kodu iletir. Uygulamanız sorumluluk bilinciyle .

Aşağıdaki kod snippet'i, onLoadChildren() basit bir kullanımını göstermektedir yöntem:

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<MediaBrowserCompat.MediaItem> = mutableListOf()

    // Check whether 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 children of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems)
}

Java

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

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

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

    // Check whether 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 children of that menu in the mediaItems list.
    }
    result.sendResult(mediaItems);
}

Bu yöntemin tam bir örneği için onLoadChildren() yöntemini kullanabilirsiniz.

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

Şekil 2. Gezinme sekmeleri olarak görüntülenen kök içerik.

Android Auto ve Android Automotive OS'in kök menü yapısı. Bu şartlar MediaBrowserService kök ipuçları üzerinden erişilebilir. Bu ipuçları, iletilen Bundle bağımsız değişkeni onGetRoot(). Bu ipuçlarının uygulanması, sistemin kök içeriği en iyi şekilde görüntüleyebilmesini sağlar. gezinme sekmeleri şeklinde görünür. Bu ipuçlarını uygulamazsanız bazı kök içerikler bulunabilir. İki ipucu gönderilir:

ziyaret edin.

İlgili kök ipuçlarını okumak için aşağıdaki kodu kullanın:

Kotlin

import androidx.media.utils.MediaConstants

// Later, in your MediaBrowserServiceCompat.
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ı için mantığı dallara ayırmayı seçebilirsiniz. bu ipuçlarının değerlerine göre, özellikle hiyerarşiniz Android Auto ve Android Automotive OS dışında MediaBrowser entegrasyonları. Örneğin, normalde kök oynatılabilir bir öğeyi gösteriyorsanız bunu iç içe yerleştirmek isteyebilirsiniz bunun yerine, desteklenen flag'lerin değeri nedeniyle kök göz atılabilir bir öğenin altında ipucu.

Kök ipuçları dışında, uyulması gereken birkaç ek yönerge vardır. oluşturmak için aşağıdaki adımları uygulayın:

  • Her sekme öğesi için tek renkli ve tercihen beyaz simgeler sağlayın.
  • Her sekme öğesi için kısa ama anlamlı etiketler sağlayın. Etiketleri kısa tutma dizelerin kesilme olasılığını azaltır.

Medya posterini göster

Medya öğelerinin posterleri, aşağıdakilerden biri kullanılarak yerel URI olarak iletilmelidir ContentResolver.SCHEME_CONTENT veya ContentResolver.SCHEME_ANDROID_RESOURCE. Bu yerel URI, kaynaklarıdır. Şuradaki öğeleri temsil eden MediaDescriptionCompat nesne için: URI'yı setIconUri() üzerinden iletin. Şu anda oynatılan öğeyi temsil eden MediaMetadataCompat nesne için putString() üzerinden URI, aşağıdaki anahtarlardan herhangi birini kullanarak:

Aşağıdaki adımlarda, bir web URI'sinden nasıl sanat eseri indirileceği ve yerel URI üzerinden gönderebilirsiniz. Daha eksiksiz bir örnek için uygulama Universal Android Music'te openFile() ve çevresindeki yöntemler Oynatıcı örnek uygulaması.

  1. Web URI'sine karşılık gelen bir content:// URI'si oluşturun. Medya tarayıcısı hizmet ve medya oturumu, bu içerik URI'sini Android Auto'ya iletir ve Android Automotive OS.

    Kotlin

    fun Uri.asAlbumArtContentURI(): Uri {
      return Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(CONTENT_PROVIDER_AUTHORITY)
        .appendPath(this.getPath()) // Make sure you trust the URI
        .build()
    }
    

    Java

    public static Uri asAlbumArtContentURI(Uri webUri) {
      return new Uri.Builder()
        .scheme(ContentResolver.SCHEME_CONTENT)
        .authority(CONTENT_PROVIDER_AUTHORITY)
        .appendPath(webUri.getPath()) // Make sure you trust the URI!
        .build();
    }
    
  2. ContentProvider.openFile() uygulamanızda, bir dosyanın bulunmalıdır. Resim dosyası yoksa resim dosyasını indirip önbelleğe alın. İlgili içeriği oluşturmak için kullanılan aşağıdaki kod snippet'i Glide'ı kullanır.

    Kotlin

    override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor? {
      val context = this.context ?: return null
      val file = File(context.cacheDir, uri.path)
      if (!file.exists()) {
        val remoteUri = Uri.Builder()
            .scheme("https")
            .authority("my-image-site")
            .appendPath(uri.path)
            .build()
        val cacheFile = Glide.with(context)
            .asFile()
            .load(remoteUri)
            .submit()
            .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS)
    
        cacheFile.renameTo(file)
        file = cacheFile
      }
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY)
    }
    

    Java

    @Nullable
    @Override
    public ParcelFileDescriptor openFile(@NonNull Uri uri, @NonNull String mode)
        throws FileNotFoundException {
      Context context = this.getContext();
      File file = new File(context.getCacheDir(), uri.getPath());
      if (!file.exists()) {
        Uri remoteUri = new Uri.Builder()
            .scheme("https")
            .authority("my-image-site")
            .appendPath(uri.getPath())
            .build();
        File cacheFile = Glide.with(context)
            .asFile()
            .load(remoteUri)
            .submit()
            .get(DOWNLOAD_TIMEOUT_SECONDS, TimeUnit.SECONDS);
    
        cacheFile.renameTo(file);
        file = cacheFile;
      }
      return ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);
    }
    

İçerik sağlayıcılarla ilgili daha fazla bilgi için İçerik oluşturma sağlayıcı.

İçerik stillerini uygula

Göz atılabilir veya oynanabilir öğeleri kullanarak içerik hiyerarşinizi oluşturduktan sonra, öğelerin arabada nasıl görüneceğini belirleyen içerik stilleri uygulayabilir.

Aşağıdaki içerik stillerini kullanabilirsiniz:

Liste öğeleri

Bu içerik stili, resimlerden ziyade başlıklara ve meta verilere öncelik verir.

Izgara öğeleri

Bu içerik stili, başlıklardan ve meta verilerden ziyade resimlere öncelik verir.

Varsayılan içerik stillerini ayarla

Medya öğelerinizin nasıl görüntüleneceğine ilişkin genel varsayılanları ayarlamak için hizmetinizin BrowserRoot ekstra paketindeki belirli sabitler onGetRoot() yöntemidir. Android Auto ve Android Automotive OS bu paketi okur ve uygun stili belirlemek için bu sabit değerleri kullanın.

Aşağıdaki ekstra özellikler pakette anahtar olarak kullanılabilir:

Anahtarlar, değeri etkilemek için aşağıdaki tam sayı sabit değerleriyle eşlenebilir. son derece önemlidir:

  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM: ilgili öğeler liste öğeleri olarak sunulur.
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM: ilgili öğeler tablo öğeleri olarak sunulur.
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM: ilgili öğeler "kategori" olarak sunulur liste öğeleri. Bunlar: sıradan liste öğeleriyle aynıdır. Tek fark, kenar boşluklarının öğelerin daha iyi görünürler. Çünkü simgeler küçük olduklarında daha iyi görünürler. Simgeler tonlamalı vektör çekilebilir öğeleri olmalıdır. Bu ipucunun yalnızca sağlanması beklenir bir şablondur.
  • DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM: ilgili öğeler "kategori" olarak sunulur ızgara öğeleri. Bunlar: sıradan ızgara öğeleriyle aynıdır, ancak yalnızca kenar boşluklarının öğelerin daha iyi görünürler. Çünkü simgeler küçük olduklarında daha iyi görünürler. Simgeler tonlamalı vektör çekilebilir öğeleri olmalıdır. Bu ipucunun yalnızca sağlanması beklenir bir şablondur.

Aşağıdaki kod snippet'inde, ızgaralara göz atılabilir öğeler ve listelere oynatılabilir öğeler:

Kotlin

import androidx.media.utils.MediaConstants

@Nullable
override fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    return BrowserRoot(ROOT_ID, extras)
}

Java

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    return new BrowserRoot(ROOT_ID, extras);
}

Öğe başına içerik stillerini ayarlayın

Content Style API, herhangi bir öğe için varsayılan içerik stilini geçersiz kılmanıza medya öğesinin alt öğelerini gösterir.

Göz atılabilir medya öğesinin alt öğeleri için varsayılanı geçersiz kılmak üzere ekstralar paketini medya öğesinin MediaDescription öğesine ekleyin ve aynı bazı ipuçları vereceğim. DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE. söz konusu öğenin oynanabilir çocukları için geçerlidir. DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE bu öğenin şunlar için geçerlidir: emin olun.

Belirli bir medya öğesinin varsayılan değerini değil, kendi değerini geçersiz kılmak için gerekiyorsa medya öğesinin MediaDescription içinde bir ekstra paketi oluşturun ve anahtarın içine bir ipucu DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM. Söz konusu öğenin sunusunu belirtmek için daha önce açıklanan değerleri kullanın.

Aşağıdaki kod snippet'i, web sitenizinMediaItem hem kendisi hem de alt öğeleri için varsayılan içerik stilini geçersiz kılar. Tarzlar kendisini kategori listesi öğesi, göz atılabilir alt öğelerini liste öğesi olarak ve çizelge öğeleri olarak oynanabilir çocuklar:

Kotlin

import androidx.media.utils.MediaConstants

private fun createBrowsableMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM)
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM)
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE)
}

Java

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createBrowsableMediaItem(
    String mediaId,
    String folderName,
    Uri iconUri) {
    MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
    mediaDescriptionBuilder.setMediaId(mediaId);
    mediaDescriptionBuilder.setTitle(folderName);
    mediaDescriptionBuilder.setIconUri(iconUri);
    Bundle extras = new Bundle();
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM);
    extras.putInt(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE,
        MediaConstants.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM);
    mediaDescriptionBuilder.setExtras(extras);
    return new MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), MediaBrowser.MediaItem.FLAG_BROWSABLE);
}

Başlık ipuçlarını kullanarak öğeleri gruplandırma

İlgili medya öğelerini birlikte gruplandırmak için öğe başına ipucu kullanırsınız. Her medya öğesi MediaDescription içinde bir ekstra paketi bildirmesi gerekir. anahtarın yer aldığı bir eşleme içerir DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE aynı dize değeri olacaktır. olarak kullanılan bu dizeyi yerelleştirin başlığı ekleyin.

Aşağıdaki kod snippet'inde, bir alt grupla nasıl MediaItem oluşturulacağı gösterilmektedir "Songs" başlığı:

Kotlin

import androidx.media.utils.MediaConstants

private fun createMediaItem(
    mediaId: String,
    folderName: String,
    iconUri: Uri
): MediaBrowser.MediaItem {
    val mediaDescriptionBuilder = MediaDescription.Builder()
    mediaDescriptionBuilder.setMediaId(mediaId)
    mediaDescriptionBuilder.setTitle(folderName)
    mediaDescriptionBuilder.setIconUri(iconUri)
    val extras = Bundle()
    extras.putString(
        MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
        "Songs")
    mediaDescriptionBuilder.setExtras(extras)
    return MediaBrowser.MediaItem(
        mediaDescriptionBuilder.build(), /* playable or browsable flag*/)
}

Java

import androidx.media.utils.MediaConstants;

private MediaBrowser.MediaItem createMediaItem(String mediaId, String folderName, Uri iconUri) {
   MediaDescription.Builder mediaDescriptionBuilder = new MediaDescription.Builder();
   mediaDescriptionBuilder.setMediaId(mediaId);
   mediaDescriptionBuilder.setTitle(folderName);
   mediaDescriptionBuilder.setIconUri(iconUri);
   Bundle extras = new Bundle();
   extras.putString(
       MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE,
       "Songs");
   mediaDescriptionBuilder.setExtras(extras);
   return new MediaBrowser.MediaItem(
       mediaDescriptionBuilder.build(), /* playable or browsable flag*/);
}

Uygulamanız, birlikte gruplandırmak istediğiniz tüm medya öğelerini takip eder. Örneğin, iki grup görüntülemek istediğinizi varsayalım medya öğesi, "Şarkılar" ve "Albümler" o sırada en iyi şekilde çalışır ve uygulamanız şu sırayla beş medya öğesi:

  1. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") içeren medya öğesi A
  2. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums") içeren medya öğesi B
  3. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") içeren medya öğesi C
  4. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") ile medya öğesi D
  5. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums") içeren medya öğesi E

Çünkü "Şarkılar"ın medya öğeleri, grup ve "Albümler" grup tutulmuyor Android Auto ve Android Automotive OS, bitişik bloklarda bunu aşağıdaki dört grup şeklinde yorumlar:

  • "Şarkılar" adlı 1. Grup A medya öğesi içeren
  • "Albümler" adlı 2. Grup B medya öğesi içeren
  • "Şarkılar" adlı 3. Grup C ve D medya öğelerini içeren
  • "Albümler" adlı 4. grup E medya öğesini içeren

Bu öğeleri iki grupta göstermek için uygulamanızın, medya öğelerini şu sırayı takip ederek:

  1. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") içeren medya öğesi A
  2. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") içeren medya öğesi C
  3. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs") ile medya öğesi D
  4. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums") içeren medya öğesi B
  5. extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums") içeren medya öğesi E

Ek meta veri göstergelerini göster

Bir bakışta bilgi sağlamak için ek meta veri göstergeleri ekleyebilirsiniz içeriği hakkında daha fazla bilgi edinmenize olanak tanır. Şuranın içinde: ağaçlara göz atın, Android Auto ve Android Automotive OS, ilgili ekstraları okur ve hangi göstergelerin gösterileceğini belirlemek için belirli sabit değerleri görüntüleyin. Medya oynatma sırasında Android Auto ve Android Automotive OS şu verileri okur: meta verileri kullanır ve bu veri türünü belirlemek için belirli göstergeleri görebilirsiniz.

Şekil 3. Şarkıyı tanımlayan meta verilerin yer aldığı oynatma görünümü hem de sanatçıyı gösterirsiniz.

4.Şekil Üzerinde oynatılmayan içerikler için nokta bulunan göz atma görünümü ve kısmen oynatılan içerik için bir ilerleme tıklayın.

Aşağıdaki sabit değerler hem MediaItem açıklama ekstralarında hem de MediaMetadata ekstra:

Aşağıdaki sabit değerler yalnızca MediaItem açıklama ekstralarında kullanılabilir:

Kullanıcı medyaya göz atarken görünen göstergeleri görüntülemek için bir veya daha fazla sabit değer içeren bir ekstra paketi oluşturun ve bu paketi MediaDescription.Builder.setExtras() yöntemine geçirin.

Aşağıdaki kod snippet'i, uygunsuz bir medyaya ilişkin göstergelerin nasıl görüntüleneceğini gösterir %70 tamamlanmış bir öğe olacaktır:

Kotlin

import androidx.media.utils.MediaConstants

val extras = Bundle()
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED)
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

Java

import androidx.media.utils.MediaConstants;

Bundle extras = new Bundle();
extras.putLong(
    MediaConstants.METADATA_KEY_IS_EXPLICIT,
    MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
extras.putInt(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS,
    MediaConstants.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED);
extras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.7);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId(/*...*/)
        .setTitle(resources.getString(/*...*/))
        .setExtras(extras)
        .build();
return new MediaBrowserCompat.MediaItem(description, /* flags */);

Oynatılmakta olan bir medya öğesine ilişkin göstergeleri görüntülemek için METADATA_KEY_IS_EXPLICIT veya EXTRA_DOWNLOAD_STATUS için Long değerleri bildir mediaSession içinde MediaMetadataCompat içinde. Gösterilemez. DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS veya Oynatma görünümünde DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE göstergeleri var.

Aşağıdaki kod snippet'i, oynatma görünümü uygunsuz görünüyor ve indirildi:

Kotlin

import androidx.media.utils.MediaConstants

mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build())

Java

import androidx.media.utils.MediaConstants;

mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_TITLE, "Song Name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_DISPLAY_SUBTITLE, "Artist name")
        .putString(
            MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI,
            albumArtUri.toString())
        .putLong(
            MediaConstants.METADATA_KEY_IS_EXPLICIT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        .putLong(
            MediaDescriptionCompat.EXTRA_DOWNLOAD_STATUS,
            MediaDescriptionCompat.STATUS_DOWNLOADED)
        .build());

İçerik oynatılırken göz atma görünümündeki ilerleme çubuğunu güncelleyin

Daha önce belirtildiği gibi, DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE kısmen oynatılan içerik için bir ilerleme çubuğu göstermek üzere göz at görünümündedir. Ancak kullanıcı kısmen oynatılan içeriği oynatmaya devam ederse Android Auto veya Android Automotive OS'ten gelirse bu gösterge zaman geçtikçe yanlış olması.

Android Auto ve Android Automotive OS için güncel kalmasını sağlamak için aşağıdaki sayfaya giderek ek bilgi sağlayabilirsiniz: Devam eden içeriğin bağlanacağı MediaMetadataCompat ve PlaybackStateCompat medya öğelerini görüntülemenizi sağlar. Şunun için aşağıdaki gereksinimlerin karşılanması gerekir: otomatik olarak güncellenen bir ilerleme çubuğu olmasını sağlamak için bir medya öğesi seçin:

Aşağıdaki kod snippet'i, şu anda oynatılan öğenin nasıl belirtileceğini göz atma görünümündeki bir öğeye bağlı:

Kotlin

import androidx.media.utils.MediaConstants

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
val mediaItemExtras = Bundle()
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25)
val description =
    MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build()
return MediaBrowserCompat.MediaItem(description, /* flags */)

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build())

val playbackStateExtras = Bundle()
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id")
mediaSession.setPlaybackState(
    PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build())

Java

import androidx.media.utils.MediaConstants;

// When the MediaItem is constructed to show in the browse view.
// Suppose the item was 25% complete when the user launched the browse view.
Bundle mediaItemExtras = new Bundle();
mediaItemExtras.putDouble(
    MediaConstants.DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE, 0.25);
MediaDescriptionCompat description =
    new MediaDescriptionCompat.Builder()
        .setMediaId("my-media-id")
        .setExtras(mediaItemExtras)
        // ...and any other setters.
        .build();
return MediaBrowserCompat.MediaItem(description, /* flags */);

// Elsewhere, when the user has selected MediaItem for playback.
mediaSession.setMetadata(
    new MediaMetadataCompat.Builder()
        .putString(MediaMetadata.METADATA_KEY_MEDIA_ID, "my-media-id")
        // ...and any other setters.
        .build());

Bundle playbackStateExtras = new Bundle();
playbackStateExtras.putString(
    MediaConstants.PLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID, "my-media-id");
mediaSession.setPlaybackState(
    new PlaybackStateCompat.Builder()
        .setExtras(playbackStateExtras)
        // ...and any other setters.
        .build());

5. Şekil. "Arama sonuçları" seçeneği bulunan oynatma görünümü kullanıcının sesli aramasıyla ilgili medya öğelerini görüntüleme.

Uygulamanız, kullanıcılara aşağıdaki durumlarda gösterilen bağlama dayalı arama sonuçları sağlayabilir bir arama sorgusu başlatırlar. Android Auto ve Android Automotive OS gösterisi Bu sonuçlar, arama sorgusu arayüzleri veya bir özet akışı sağlayan yapılan sorgularda Daha fazla bilgi edinmek için Sesli işlemleri destekle bölümüne göz atın.

Göz atılabilir arama sonuçlarını görüntülemek için sabit tuşunu ekleyin BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED hizmetinizin onGetRoot() ekstra paketinde yöntemini kullanarak boole true eşlemesini sağlayabilirsiniz.

Aşağıdaki kod snippet'i, onGetRoot() ürününde desteği nasıl etkinleştireceğinizi göstermektedir. yöntem:

Kotlin

import androidx.media.utils.MediaConstants

@Nullable
fun onGetRoot(
    @NonNull clientPackageName: String,
    clientUid: Int,
    @Nullable rootHints: Bundle
): BrowserRoot {
    val extras = Bundle()
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true)
    return BrowserRoot(ROOT_ID, extras)
}

Java

import androidx.media.utils.MediaConstants;

@Nullable
@Override
public BrowserRoot onGetRoot(
    @NonNull String clientPackageName,
    int clientUid,
    @Nullable Bundle rootHints) {
    Bundle extras = new Bundle();
    extras.putBoolean(
        MediaConstants.BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED, true);
    return new BrowserRoot(ROOT_ID, extras);
}

Arama sonuçları sağlamaya başlamak için onSearch() geçersiz kılınır yöntemini çağırın. Android Auto ve Android Automotive OS bir kullanıcı bir arama yöntemini çağırdığında, kullanıcının arama terimlerini bu yönteme yönlendirir sorgu arayüzünü veya "Arama sonuçları"

Aramayı organize edebilir ve başlık öğeleri kullanan hizmetinizin onSearch() yönteminden sonuçlar böylece göz atılabilir hale getirirsiniz. Örneğin, uygulamanızda müzik çalıyorsa arama sonuçlarını albüme, sanatçıya ve şarkılara göre düzenleyebilirsiniz.

Aşağıdaki kod snippet'i, onSearch() basit bir kullanımını göstermektedir yöntem:

Kotlin

fun onSearch(query: String, extras: Bundle) {
  // Detach from results to unblock the caller (if a search is expensive).
  result.detach()
  object:AsyncTask() {
    internal var searchResponse:ArrayList
    internal var succeeded = false
    protected fun doInBackground(vararg params:Void):Void {
      searchResponse = ArrayList()
      if (doSearch(query, extras, searchResponse))
      {
        succeeded = true
      }
      return null
    }
    protected fun onPostExecute(param:Void) {
      if (succeeded)
      {
        // Sending an empty List informs the caller that there were no results.
        result.sendResult(searchResponse)
      }
      else
      {
        // This invokes onError() on the search callback.
        result.sendResult(null)
      }
      return null
    }
  }.execute()
}
// Populates resultsToFill with search results. Returns true on success or false on error.
private fun doSearch(
    query: String,
    extras: Bundle,
    resultsToFill: ArrayList
): Boolean {
  // Implement this method.
}

Java

@Override
public void onSearch(final String query, final Bundle extras,
                        Result<List<MediaItem>> result) {

  // Detach from results to unblock the caller (if a search is expensive).
  result.detach();

  new AsyncTask<Void, Void, Void>() {
    List<MediaItem> searchResponse;
    boolean succeeded = false;
    @Override
    protected Void doInBackground(Void... params) {
      searchResponse = new ArrayList<MediaItem>();
      if (doSearch(query, extras, searchResponse)) {
        succeeded = true;
      }
      return null;
    }

    @Override
    protected void onPostExecute(Void param) {
      if (succeeded) {
       // Sending an empty List informs the caller that there were no results.
       result.sendResult(searchResponse);
      } else {
        // This invokes onError() on the search callback.
        result.sendResult(null);
      }
    }
  }.execute()
}

/** Populates resultsToFill with search results. Returns true on success or false on error. */
private boolean doSearch(String query, Bundle extras, ArrayList<MediaItem> resultsToFill) {
    // Implement this method.
}

Özel Göz Atma İşlemleri

Tek bir özel göz atma işlemi.

6. Şekil. Tek Bir Özel Göz Atma İşlemi

Özel Göz Atma İşlemleri, uygulamanızın verilerine özel simgeler ve etiketler eklemenizi sağlar MediaItem, arabanın medya uygulamasındaki nesneleri toplar ve kullanıcı etkileşimlerini işler. izin verilmez. Bu, Medya Uygulaması'nın işlevlerini "İndir", "Sıraya Ekle", "Radyo Çal" veya "Favori" veya "Kaldır" işlemlerdir.

Özel bir göz atma işlemleri taşma menüsü.

7.Şekil Özel Göz Atma İşlemi taşma

OEM'in gösterilmesine izin verdiğinden daha fazla özel işlem varsa kullanıcıya taşma menüsü sunulur.

İşleyiş şekli nasıldır?

Her bir Özel Göz Atma İşlemi şunlarla tanımlanır:

  • İşlem kimliği (benzersiz dize tanımlayıcısı)
  • İşlem Etiketi (kullanıcıya gösterilen metin)
  • İşlem Simgesi URI'si (Tonlama uygulanabilen bir çekilebilir vektör)

BrowseRoot Daha sonra, tek tek kullanıcılara bu işlemlerin bir alt MediaItem..

Kullanıcı, Özel Göz Atma İşlemi ile etkileşimde bulunduğunda uygulamanız geri çağırma alır onCustomAction() içinde. Ardından işlemi gerçekleştirebilir ve MediaItem için işlemler (gerekirse). Bu, durum bilgili işlemler için yararlıdır "En beğendiklerim" gibi ve "İndir"i seçin. Güncelleme gerektirmeyen işlemler için, ör. "Oynat " radyo düğmesi" görüyorsanız işlem listesini güncellemeniz gerekmez.

Bir göz atma düğümü kökünde özel göz atma işlemleri.

8. Şekil. Özel Göz Atma İşlemi araç çubuğu

Ayrıca, bir göz atma düğümü köküne Özel Göz Atma İşlemleri de ekleyebilirsiniz. Bu işlemler ana araç çubuğunun altındaki ikincil araç çubuğunda gösterilir.

Özel Göz Atma İşlemleri nasıl uygulanır?

Projenize Özel Göz Atma İşlemleri eklemek için şu adımları uygulayın:

  1. MediaBrowserServiceCompat uygulama:
  2. Çalışma zamanında işlem sınırlarını ayrıştırın:
  3. Özel Göz Atma İşlemlerinin genel listesini oluşturun:
    • Her işlem için aşağıdaki anahtarlarla bir Bundle nesnesi oluşturun: * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID: İşlem kimliği * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL: İşlem etiketi * EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI: İşlem simgesi URI'si * Tüm işlem Bundle nesnelerini bir listeye ekleyin.
  4. Genel listeyi BrowseRoot cihazınıza ekleyin:
  5. MediaItem nesnenize işlem ekleyin:
    • Şunları ekleyerek MediaItem nesnelerine tek tek işlem ekleyebilirsiniz: anahtarı kullanan MediaDescriptionCompat ekstralarındaki işlem kimliklerinin listesi DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST. Bu liste, şurada tanımladığınız genel işlem listesinin bir alt kümesi olmalıdır BrowseRoot.
  6. İşlemleri ele alma ve ilerleme durumunu veya sonuçları döndürme:

Başlamak için BrowserServiceCompat üzerinde yapabileceğiniz değişikliklerden bazıları şunlardır: özel göz atma işlemleri ekleyebilirsiniz.

BrowserServiceCompat'ı geçersiz kıl

MediaBrowserServiceCompat ürününde aşağıdaki yöntemleri geçersiz kılmanız gerekiyor.

public void onLoadItem(String itemId, @NonNull Result<MediaBrowserCompat.MediaItem> result)

public void onCustomAction(@NonNull String action, Bundle extras, @NonNull Result<Bundle> result)

Ayrıştırma işlemi sınırı

Kaç tane Özel Göz Atma İşleminin desteklendiğini kontrol etmeniz gerekir.

public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid, Bundle rootHints) {
    rootHints.getInt(
            MediaConstants.BROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT, 0)
}

Özel Göz Atma İşlemi Derleme

Her işlemin ayrı bir Bundle altında paketlenmesi gerekir.

  • İşlem kimliği
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                    "<ACTION_ID>")
    
    .
  • İşlem Etiketi
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                    "<ACTION_LABEL>")
    
    .
  • İşlem Simgesi URI'si
    bundle.putString(MediaConstants.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                    "<ACTION_ICON_URI>")
    
    .

Parceable ArrayList adlı kampanya için özel göz atma işlemleri ekleyin

Tüm Özel Göz Atma İşlemi Bundle nesnelerini bir ArrayList öğesine ekleyin.

private ArrayList<Bundle> createCustomActionsList(
                                        CustomBrowseAction browseActions) {
    ArrayList<Bundle> browseActionsBundle = new ArrayList<>();
    for (CustomBrowseAction browseAction : browseActions) {
        Bundle action = new Bundle();
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID,
                browseAction.mId);
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_LABEL,
                getString(browseAction.mLabelResId));
        action.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ICON_URI,
                browseAction.mIcon);
        browseActionsBundle.add(action);
    }
    return browseActionsBundle;
}

Göz atma köküne Özel Göz Atma İşlemi listesi ekleyin

public BrowserRoot onGetRoot(@NonNull String clientPackageName, int clientUid,
                             Bundle rootHints) {
    Bundle browserRootExtras = new Bundle();
    browserRootExtras.putParcelableArrayList(
            BROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST,
            createCustomActionsList()));
    mRoot = new BrowserRoot(ROOT_ID, browserRootExtras);
    return mRoot;
}

MediaItem öğesine işlem ekleyin

MediaDescriptionCompat buildDescription (long id, String title, String subtitle,
                String description, Uri iconUri, Uri mediaUri,
                ArrayList<String> browseActionIds) {

    MediaDescriptionCompat.Builder bob = new MediaDescriptionCompat.Builder();
    bob.setMediaId(id);
    bob.setTitle(title);
    bob.setSubtitle(subtitle);
    bob.setDescription(description);
    bob.setIconUri(iconUri);
    bob.setMediaUri(mediaUri);

    Bundle extras = new Bundle();
    extras.putStringArrayList(
          DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST,
          browseActionIds);

    bob.setExtras(extras);
    return bob.build();
}
MediaItem mediaItem = new MediaItem(buildDescription(...), flags);

Derleme onCustomAction sonucu

  • Bundle extras öğesinden mediaId öğesini ayrıştır:
    @Override
    public void onCustomAction(
              @NonNull String action, Bundle extras, @NonNull Result<Bundle> result){
      String mediaId = extras.getString(MediaConstans.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID);
    }
    
  • Eşzamansız sonuçlar için sonucu ayırın. result.detach().
  • Derleme sonucu paketi
    • Kullanıcıya mesaj
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE,
                mContext.getString(stringRes))
      
      .
    • Öğeyi güncelle(bir öğedeki işlemleri güncellemek için kullanın)
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
      
      .
    • Oynatma görünümünü aç
      //Shows user the PBV without changing the playback state
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_SHOW_PLAYING_ITEM, null);
      
      .
    • Göz Atma Düğümünü Güncelle
      //Change current browse node to mediaId
      mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
      
      .
  • Hata oluşursa result.sendError(resultBundle). numaralı telefonu arayın
  • İlerleme durumu güncellenirse result.sendProgressUpdate(resultBundle) numaralı telefonu arayın.
  • result.sendResult(resultBundle) numaralı telefonu arayarak işlemi tamamlayın.

İşlem Durumunu Güncelle

result.sendProgressUpdate(resultBundle) yöntemini EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM tuşuna basarak, MediaItem öğesini işlemin yeni durumunu yansıtacak şekilde güncelleyebilirsiniz. Bu kullanıcıya ilerleme durumu ve ilerleme durumu hakkında anlık geri bildirim bir sonucu olarak görünür.

Örnek: İndirme İşlemi

Aşağıda, bir indirme işlemi uygulamak için bu özelliği nasıl kullanabileceğinize dair bir örnek verilmiştir: üç durum vardır:

  1. İndir: İşlemin ilk durumudur. Kullanıcı bu işlemi "İndiriliyor" şeklinde değiştirebilirsiniz. arayın Kullanıcı arayüzünü güncellemek için sendProgressUpdate.
  2. İndiriliyor: Bu durum, indirme işleminin devam ettiğini gösterir. Şunları yapabilirsiniz: kullanıcıya bir ilerleme çubuğu veya başka bir gösterge göstermek için bu durumu kullanın.
  3. İndirildi: Bu durum indirme işleminin tamamlandığını gösterir. "İndiriliyor"u, ardından "İndiriliyor"u "İndirilenler" simgesiyle arayın sendResult EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM tuşunu kullanın. Ayrıca, "the" EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE tuşuna basarak kullanıcıya bir başarı mesajı gösterin.

Bu yaklaşım, kullanıcıya indirme işlemi hakkında net geri bildirim sağlamanıza olanak tanır mevcut durumu hakkında bilgi edineceksiniz. Gösterilecek simgelerle daha da fazla ayrıntı ekleyebilirsiniz. İndirme durumu: %25, %50, %75.

Örnek: Favori İşlem

Başka bir örnek, iki eyalet içeren favori bir işlemdir:

  1. Favori: Bu işlem, şurada bulunmayan öğeler için görüntülenir: kullanıcının sık kullanılanlar listesi. Kullanıcı bu işlemi seçtiğinde bunu değiştirebilirsiniz "Favorilere eklendi" ve sendResult numaralı telefonu EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM tuşuna basın.
  2. Favorilere eklendi: Bu işlem, kullanıcının Favoriler listesi. Kullanıcı bu işlemi seçtiğinde bunu "Favori" ve sendResult numaralı telefonu EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM tuşuna basın.

Bu yaklaşım, kullanıcıların cihazlarını yönetmek için favori öğeler.

Bu örnekler, Özel Göz Atma İşlemleri'nin esnekliğini ve Özel Göz Atma İşlemleri'nin çeşitli işlevleri uygulamak için kullanılır ve gerçek zamanlı geri bildirim sağlar. arabanın medya uygulamasında gelişmiş bir kullanıcı deneyimi.

Bu özelliğin eksiksiz bir örneği için TestMediaApp tıklayın.

Oynatma kontrolünü etkinleştir

Android Auto ve Android Automotive OS, oynatma kontrolü komutlarını MediaSessionCompat. Bir oturum kaydetmeniz ve ilişkili geri çağırma yöntemlerini uygulamanız gerekir.

Medya oturumu kaydetme

Medya tarayıcı hizmetinizin onCreate() yönteminde, bir MediaSessionCompat oluşturun, Ardından setSessionToken() numaralı telefonu arayarak medya oturumunu kaydedin.

Aşağıdaki kod snippet'i, bir medya oturumunun nasıl oluşturulacağını ve kaydedileceğini gösterir:

Kotlin

override fun onCreate() {
    super.onCreate()
    ...
    // Start a new MediaSession.
    val session = MediaSessionCompat(this, "session tag").apply {
        // Set a callback object that implements MediaSession.Callback
        // to handle play control requests.
        setCallback(MyMediaSessionCallback())
    }
    sessionToken = session.sessionToken
    ...
}

Java

public void onCreate() {
    super.onCreate();
    ...
    // Start a new MediaSession.
    MediaSessionCompat session = new MediaSessionCompat(this, "session tag");
    setSessionToken(session.getSessionToken());

    // Set a callback object that implements MediaSession.Callback
    // to handle play control requests.
    session.setCallback(new MyMediaSessionCallback());
    ...
}

Medya oturumu nesnesini oluşturduğunuzda, kullanılan bir geri çağırma nesnesini ayarlarsınız. oynatma kontrol isteklerini yerine getirmek için kullanılır. Bu geri çağırma nesnesini şu şekilde oluşturursunuz: MediaSessionCompat.Callback uygulanmasını sağlama seçin. Bir sonraki bölümde, bu nesnenin nasıl uygulanacağı açıklanmaktadır.

Oynatma komutlarını uygulama

Bir kullanıcı, uygulamanızdan medya öğesi oynatma isteğinde bulunduğunda Android Automotive OS ve Android Auto MediaSessionCompat.Callback kullanır Uygulamanızın MediaSessionCompat grubundaki sınıf bir nesne kullanır. Bir kullanıcı Kullanıcı, oynatmayı duraklatmak veya sonraki parça, Android Auto ve Android Automotive OS için geçerli değildir.

İçerik oynatma işlemini işlemek için uygulamanızın soyut MediaSessionCompat.Callback öğesini genişletmesi gerekir ve uygulamanızın desteklediği yöntemleri uygulayın.

Aşağıdakiler açısından sizin için yararlı olan tüm geri çağırma yöntemlerini uygulayın: Uygulamanızın sunduğu içerik türü:

onPrepare()
Medya kaynağı değiştirildiğinde çağrılır. Android Automotive OS ayrıca şunları da çağırır: bu yöntemi kullanmanızı öneririz. Medya uygulamanız bunu uygulamalıdır yöntemidir.
onPlay()
Kullanıcı belirli bir öğe seçmeden oynatmayı seçerse çağrılır. Sizin uygulamanın varsayılan içeriğini oynatması veya onPause(), Uygulama oynatmaya devam eder.

Not: Uygulamanız otomatik olarak müzik çalmaya başlamamalıdır Android Automotive OS veya Android Auto medya tarayıcınıza bağlandığında geliştirmenizi sağlar. Daha fazla bilgi için ilk oynatma durumunu ayarlamanız gerekir.

onPlayFromMediaId()
Kullanıcı belirli bir öğeyi çalmayı seçtiğinde çağrılır. Yöntem başarılı Medya tarayıcı hizmetinizin atadığı kimlik ekler.
onPlayFromSearch()
Kullanıcı bir arama sorgusundan oynatma işlemini seçtiğinde çağrılır. Uygulama, iletilen arama dizesine göre uygun bir seçim yapın.
onPause()
Kullanıcı oynatmayı duraklatmayı seçtiğinde çağrılır.
onSkipToNext()
Kullanıcı bir sonraki öğeye atlamayı seçtiğinde çağrı yapılır.
onSkipToPrevious()
Kullanıcı bir önceki öğeye atlamayı seçtiğinde çağrılır.
onStop()
Kullanıcı oynatmayı durdurmayı seçtiğinde çağrılır.

İstediğiniz işlevleri sunmak için uygulamanızda bu yöntemleri geçersiz kılın. Siz işlevi uygulamanız tarafından desteklenmeyen bir yöntem uygulamanıza gerek yoktur. Örneğin, Uygulamanız spor yayını gibi bir canlı yayın oynatıyorsa onSkipToNext() yöntemini uygulamanız gerekmez. Varsayılan URL'yi kullanabilirsiniz onSkipToNext() uygulanmasıdır.

Uygulamanızın, arabanın ana makinesiyle içerik oynatmak için özel bir mantığa ihtiyacı yok. sağlayabilirsiniz. Uygulamanız içerik oynatma isteği aldığında ses çalabilir video oynattığı gibi Kullanıcının telefonunda hoparlörden veya kulaklığından. Android Auto ve Android Automotive OS ses içeriğini otomatik olarak arabanın sistemine gönderir. araba hoparlörlerinden

Ses içeriği oynatma hakkında daha fazla bilgi için bkz. MediaPlayer'a genel bakış, Ses uygulamasına genel bakış, ve ExoPlayer'a genel bakış sayfasına göz atın.

Standart oynatma işlemlerini ayarlama

Android Auto ve Android Automotive OS ekran oynatma kontrolleri PlaybackStateCompat'nda etkinleştirilen işlemler nesnesini tanımlayın.

Uygulamanız varsayılan olarak aşağıdaki işlemleri desteklemelidir:

Uygulamanız ayrıca uygulama içeriği:

Buna ek olarak, istediğiniz zaman içerikleriniz için görüntülenebilecek bir oynatma sırası kullanıcıdır ancak zorunlu değildir. Bunu yapmak için setQueue() numaralı telefonu arayın ve setQueueTitle() yöntemleri için ACTION_SKIP_TO_QUEUE_ITEM ve geri çağırmayı tanımlayın onSkipToQueueItem().

Ayrıca, Ne çalıyor? simgesi için destek ekleyin. Bu simge, şu anda oynatılıyor. Bunu yapmak için setActiveQueueItemId() numaralı telefonu arayın yöntemini kullanın ve sırada oynatılan öğenin kimliğini iletin. Şunları yapmanız gerekir: sırada değişiklik olduğunda setActiveQueueItemId() uygulamasını güncelleyin.

Etkinleştirilen her işlem için Android Auto ve Android Automotive OS ekran düğmeleri oynatma sırasına göre de kontrol edilir. Düğmeler sistem bu düğmeye bastığında MediaSessionCompat.Callback.

Kullanılmayan alanı ayır

Android Auto ve Android Automotive OS Rezerv alanı ACTION_SKIP_TO_PREVIOUS ve ACTION_SKIP_TO_NEXT işlem. Uygulamanız şu işlevlerden birini desteklemediğinden: Android Auto ve Android Automotive OS alanda gezinebilirsiniz.

Bu alanları özel işlemlerle doldurmak istemiyorsanız rezerve edebilirsiniz Android Auto ve Android Automotive OS'in alanı boş bırakmasını sağlayın uygulamanız karşılık gelen işlevi desteklemediğinde. Bunun için şu numarayı arayın: setExtras() yöntemindeki sabit değerler içeren bir ekstra paketi ayrılmış işlevler. SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT ACTION_SKIP_TO_NEXT değerine karşılık gelir ve SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV ACTION_SKIP_TO_PREVIOUS değerine karşılık gelir. Bu sabit değerleri paket haline getirebilir ve değerleri için true boole değerini kullanabilir.

İlk Oynatma Durumunu ayarla

Android Auto ve Android Automotive OS, medya tarayıcınızla iletişim kurarken hizmetini kaldırdığınızda, medya oturumunuz içerik oynatma durumunu PlaybackStateCompat. Android Automotive OS şu anda uygulamanız müzik çalmaya otomatik olarak başlamamalıdır veya Android Auto'nun medya tarayıcı hizmetinize bağlanmasını sağlayın. Mobil cihaz yerine Android Aracın durumuna göre oynatmayı devam ettirmek veya başlatmak için Auto ve Android Automotive OS veya kullanıcı işlemleri olabilir.

Bunu yapmak için başlangıçtaki PlaybackStateCompat değerini ayarlayın son 30 gün içinde STATE_STOPPED, STATE_PAUSED, STATE_NONE veya STATE_ERROR.

Android Auto ve Android Automotive OS'teki medya oturumları yalnızca Böylece kullanıcılar bu oturumları sık sık başlatıp durdurabilir. Alıcı: sürüşler arasında sorunsuz bir deneyim sağlamak, kullanıcının geçmiş oturum durumunu gösterir. Böylece, medya uygulaması isteği devam ettirdiğinde kullanıcı kaldığı yerden otomatik olarak devam edebilir kapalı olabilir. Örneğin, son oynatılan medya öğesi, PlaybackStateCompat, sıradan bahsediyoruz.

Özel oynatma işlemleri ekleyin

Videolarınızda izlediğiniz diğer işlevleri göstermek için destekler. Alan izin veriyorsa (ve rezerve edilmediyse), Android aktarım denetimlerine özel işlemler yapabilir. Aksi halde özel işlemler görüntüleyebilirsiniz. Özel işlemler sırayla gösterilir PlaybackStateCompat içine eklenir.

Standart standartlardan farklı bir davranış sağlamak için özel işlemler kullanın. işlemler bölümüne gidin. Standartları değiştirmek veya kopyalamak için kullanmayın işlemlerdir.

addCustomAction() kullanarak özel işlemler ekleyebilirsiniz. PlaybackStateCompat.Builder içinde sınıfını kullanır.

Aşağıdaki kod snippet'i, özel bir "Radyo kanalı başlatın" için nasıl ekleneceğini gösterir eylem:

Kotlin

stateBuilder.addCustomAction(
    PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon
    ).run {
        setExtras(customActionExtras)
        build()
    }
)

Java

stateBuilder.addCustomAction(
    new PlaybackStateCompat.CustomAction.Builder(
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA,
        resources.getString(R.string.start_radio_from_media),
        startRadioFromMediaIcon)
    .setExtras(customActionExtras)
    .build());

Bu yöntemin daha ayrıntılı bir örneği için setCustomAction() bölümüne bakın yöntemini kullanabilirsiniz.

Özel işleminizi oluşturduktan sonra, medya oturumunuz işleme yanıt verebilir onCustomAction() değerini geçersiz kılarak yöntemidir.

Aşağıdaki kod snippet'i, uygulamanızın bir "Radyo kanalı başlatma" işlemi:

Kotlin

override fun onCustomAction(action: String, extras: Bundle?) {
    when(action) {
        CUSTOM_ACTION_START_RADIO_FROM_MEDIA -> {
            ...
        }
    }
}

Java

@Override
public void onCustomAction(@NonNull String action, Bundle extras) {
    if (CUSTOM_ACTION_START_RADIO_FROM_MEDIA.equals(action)) {
        ...
    }
}

Bu yöntemin daha ayrıntılı bir örneği için onCustomAction bölümüne bakın yöntemini kullanabilirsiniz.

Özel işlemler için simgeler

Oluşturduğunuz her özel işlem için bir simge kaynağı gerekir. Arabalardaki uygulamalar pek çok farklı ekran boyutunda ve yoğunluğunda çalıştığı için, vektör çekilebilirleri olmalıdır. CEVAP çizim özelliği, ayrıntıları kaybetmeden öğeleri ölçeklendirmenizi sağlar. Vektör çekilebilir, aynı zamanda kenarları ve köşeleri piksel sınırlarıyla hizalamayı da de kullanabilirsiniz.

Özel bir işlem durum bilgiliyse (örneğin, bir oynatma ayarını açar veya kapalı—farklı eyaletler için farklı simgeler sağlar. Böylece, kullanıcılar işlemi seçtiğinde bir değişiklik görebilir.

Devre dışı bırakılan işlemler için alternatif simge stilleri sağlama

Bir özel işlem mevcut bağlam için kullanılamadığında işlemi gösteren bir alternatif simgeyle birlikte özel işlem simgesi devre dışı bırakıldı.

6. Şekil. Tarz dışı özel işlem simgesi örnekleri.

Ses biçimini belirtin

Şu anda oynatılan medyanın özel bir ses biçimi kullandığını belirtmek için: bu özelliği destekleyen arabalarda oluşturulan simgeleri belirtebilirsiniz. Siz CANNOT TRANSLATE KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI ve KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI oynatılan medya öğesinin ekstra paketinde ( MediaSession.setMetadata()) tıklayın. Her iki farklı tasarımlara yer verebilirsiniz.

Ayrıca, KEY_IMMERSIVE_AUDIO ekstra bunu otomobil OEM'lerine söyler. OEM'ler bunu mümkün olduğunca çalışmasını kesintiye uğratabilecek ses efektlerinin etkileyici içerikler oluşturabilirsiniz.

Şu anda oynatılan medya öğesini yapılandırarak altyazısını, açıklamasını, veya her ikisi de diğer medya öğelerine bağlantıdır. Böylece, kullanıcı hemen ilgili öğeler; Örneğin, aynı sanatçının diğer şarkılarına podcast'in diğer bölümleri gibi içerikleri görüntülemenizi sağlar. Araba bu özelliği destekliyorsa kullanıcılar, bağlantıya dokunarak o içeriğe göz atabilirsiniz.

Bağlantı eklemek için KEY_SUBTITLE_LINK_MEDIA_ID meta verileri (alt başlıktan bağlantı verin) veya KEY_DESCRIPTION_LINK_MEDIA_ID (şuradan bağlanacak: girin). Ayrıntılı bilgi için bu meta veri alanlarını da kullanabilirsiniz.

Sesli işlemleri destekle

Sürücülere güvenli bir ortam sağlamak için medya uygulamanız sesli işlemleri desteklemelidir. Ayrıca, dikkat dağıtıcı unsurları en aza indiren uygun bir deneyim sunar. Örneğin, uygulamanız bir medya öğesi çalıyorsa kullanıcı “[Şarkı adı]adlı şarkıyı çal" diyebilirsiniz. arabanınkine bakmadan veya dokunmadan farklı bir şarkı çalmasını söylemek için görüntüleyin. Kullanıcılar, web sitelerindeki uygun düğmeleri tıklayarak direksiyon başında veya "Ok Google" özel kelimesini söylemek.

Android Auto veya Android Automotive OS bir sesi algıladığında ve yorumladığında bu sesli işlem uygulamaya onPlayFromSearch(). Bu geri aramayı aldıktan sonra, uygulama query ile eşleşen içerik bulur çalmaya başlar.

Kullanıcılar, sorgularında farklı terim kategorileri belirtebilir: tür, sanatçı, albüm, şarkı adı, radyo istasyonu veya şarkı listesi. Yapı oluştururken arama desteği, uygulamanız için anlam ifade eden tüm kategorileri hesaba katın. Android Auto veya Android Automotive OS, belirli bir sorgunun belirli kategorilerde ise extras parametresine ekstralar ekler. İlgili içeriği oluşturmak için kullanılan şu ekstralar gönderilebilir:

tarafından gönderilebilecek boş bir query dizesi hesaba katılır. Kullanıcı arama terimleri belirtmezse Android Auto veya Android Automotive OS. Örneğin, kullanıcı "Müzik çal" derse. Bu durumda, uygulamanız yeni çalınan veya yeni önerilen bir parçayı başlatmayı seçin.

Bir arama hızlı bir şekilde işlenemiyorsa onPlayFromSearch() içinde engelleme yapmayın. Bunun yerine, oynatma durumunu STATE_CONNECTING olarak ayarlayın. eş zamansız bir iş parçacığında arama yapın.

Oynatma işlemi başladıktan sonra, medya oturumunun sırasını emin olun. Örneğin, kullanıcı bir albümün çalınmasını isterse, uygulaması sırayı albümün parça listesiyle doldurabilir. Şunları da uygulayabilirsiniz: Kullanıcının seçim yapabilmesi için göz atılabilir arama sonuçları desteği sorguyla eşleşen farklı bir parçayı seçer.

"play" öğesine ek olarak sorguları, Android Auto ve Android Automotive OS "müziği duraklat" gibi çalmayı kontrol etmek için sesli sorguları tanıma ve "next" şarkı" bu komutları uygun medya oturumu geri çağırmalarıyla eşleştirdikten sonra, onPause() ve onSkipToNext() gibi.

Sesle etkinleştirilen oynatma işlemlerinin Google Asistan ve medya uygulamalarına bakın.

Dikkat dağıtıcı önlemler alın

Android kullanırken kullanıcının telefonu, arabasının hoparlörlerine bağlı olduğu için Auto. Sürücünün dikkatinin dağılmasını önlemeye yardımcı olacak ek önlemler almalısınız.

Arabadaki alarmları bastır

Android Auto medya uygulamaları, araç hoparlörlerinden ses çalmaya başlamamalıdır kullanıcı oynatma düğmesine basarak (örneğin, oynat) başlatmadığı sürece. Medya uygulamanızdaki kullanıcı tarafından programlanmış bir alarm bile başlamamalıdır araç hoparlörlerinden müzik çalıyor.

Uygulamanız bu şartı karşılamak için CarConnection kullanabilir sinyal olarak kullanabilirsiniz. Uygulamanız, telefonun şurada olup olmadığını kontrol edebilir: araba bağlantısı için LiveData gözlemleyerek bir araç ekranına yansıtma tür eşit olup olmadığını kontrol etmek CONNECTION_TYPE_PROJECTION.

Kullanıcının telefonu yansıtılıyorsa alarmları destekleyen medya uygulamalarının bunu yapması gerekir. şunlar olabilir:

  • Alarmı devre dışı bırakın.
  • Alarmı şu saatten çal: STREAM_ALARM ve telefon ekranında alarmı devre dışı bırakacak bir kullanıcı arayüzü sağlayın.

Medya reklamlarını işleme

Varsayılan olarak Android Auto, medya meta verileri değiştiğinde bir bildirim gösterir devam edebilir. Bir medya uygulaması müzik çalmaktan geçtiğinde bir reklam yayınlamaktan başka kullanıcıya bildirim göndermelidir. Android Auto'nun bildirim görüntülemesini önlemek için Bu durumda, medya meta veri anahtarını METADATA_KEY_IS_ADVERTISEMENT - METADATA_VALUE_ATTRIBUTE_PRESENT, aşağıdaki kod snippet'inde gösterildiği gibidir:

Kotlin

import androidx.media.utils.MediaConstants

override fun onPlayFromMediaId(mediaId: String, extras: Bundle?) {
    MediaMetadataCompat.Builder().apply {
        if (isAd(mediaId)) {
            putLong(
                MediaConstants.METADATA_KEY_IS_ADVERTISEMENT,
                MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT)
        }
        // ...add any other properties you normally would.
        mediaSession.setMetadata(build())
    }
}

Java

import androidx.media.utils.MediaConstants;

@Override
public void onPlayFromMediaId(String mediaId, Bundle extras) {
    MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder();
    if (isAd(mediaId)) {
        builder.putLong(
            MediaConstants.METADATA_KEY_IS_ADVERTISEMENT,
            MediaConstants.METADATA_VALUE_ATTRIBUTE_PRESENT);
    }
    // ...add any other properties you normally would.
    mediaSession.setMetadata(builder.build());
}

Genel hataları ele alma

Uygulamada hata oluştuğunda oynatma durumunu STATE_ERROR olarak ayarlayın ve setErrorMessage() aracını kullanarak bir hata mesajı sağlayın yöntemidir. Bkz. PlaybackStateCompat inceleyin. Hata mesajları, kullanıcılara gösterilmeli ve kullanıcının güncel özelliklerine göre yerelleştirilmelidir. yerel ayar. Bu işlemin ardından Android Auto ve Android Automotive OS bu hatayı gösterebilir. mesajı görebilirsiniz.

Örneğin, içerik kullanıcının geçerli bölgesinde kullanılamıyorsa şunları yapabilirsiniz: ERROR_CODE_NOT_AVAILABLE_IN_REGION bağlantısını kullanın. hata mesajı ayarlanır.

Kotlin

mediaSession.setPlaybackState(
    PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR)
        .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region))
        // ...and any other setters.
        .build())

Java

mediaSession.setPlaybackState(
    new PlaybackStateCompat.Builder()
        .setState(PlaybackStateCompat.STATE_ERROR)
        .setErrorMessage(PlaybackStateCompat.ERROR_CODE_NOT_AVAILABLE_IN_REGION, getString(R.string.error_unsupported_region))
        // ...and any other setters.
        .build());

Hata durumları hakkında daha fazla bilgi için Medya oturumu kullanma: Durumlar bölümüne bakın ve hatalar.

Bir Android Auto kullanıcısının hatayı çözmek için telefon uygulamanızı açması gerekiyorsa mesajınızda kullanıcıya bu bilgiyi sağlar. Örneğin, aldığınız hata Bu mesajda "[Uygulamanızın adı] uygulamasında oturum açın" yazıyor olabilir yerine "Lütfen oturum açın."

Diğer kaynaklar