Android Auto ve Android Automotive OS, medya uygulamanızın içeriğini kullanıcıların arabalarına getirmenize yardımcı olur.
Arabalar için medya uygulamaları oluşturmanın iki yolu vardır:
Bu kılavuzda, Android Auto ve Android Automotive OS'in bağlanabileceği bir uygulama oluşturmak için
MediaBrowserService
veMediaSession
nasıl kullanılacağı açıklanmaktadır. Bu uygulama, araç içi kullanıma yönelik olarak optimize edilmiş medya tarama ve oynatma görünümleri oluşturur.Medya uygulamaları, özelleştirilebilir biçimlendirme, göz atma özellikleri ve genişletilmiş özel işlemler için Car App Library şablonları kullanılarak da oluşturulabilir. Uygulama ayrıntıları için Şablonlu bir medya uygulaması oluşturma başlıklı makaleyi inceleyin. Şablonlu medya uygulamaları şu anda yalnızca Android Auto'da desteklenmektedir.
Bu kılavuzda, uygulamanızın Android Auto veya Android Automotive OS'te çalışması için gereken MediaBrowserService
ve MediaSession
bileşenleri açıklanmaktadır. Temel medya altyapısını tamamladıktan sonra medya uygulamanıza Android Auto desteği ve Android Automotive OS desteği ekleyebilirsiniz.
Bu kılavuzda, telefonda ses çalan bir medya uygulamanızın olduğu ve medya uygulamanızın Android medya uygulaması mimarisine uygun olduğu varsayılmaktadır.
Başlamadan önce
- Android Media API belgelerini inceleyin.
- Tasarım rehberliği için Medya uygulamaları oluşturma başlıklı makaleyi inceleyin.
- Bu bölümde listelenen temel terimleri ve kavramları inceleyin.
Temel terimler ve kavramlar
- Medya tarayıcı hizmeti
- Medya uygulamanız tarafından uygulanan ve
MediaBrowserServiceCompat
API'sine uygun bir Android hizmeti. Uygulamanız, içeriğini göstermek için bu hizmeti kullanıyor. - Medya tarayıcı
- Medya uygulamalarının medya tarayıcı hizmetlerini keşfetmek ve içeriklerini göstermek için kullandığı bir API. Android Auto ve Android Automotive OS, uygulamanızın medya tarayıcı hizmetini bulmak için medya tarayıcı kullanır.
- Medya öğesi
Medya tarayıcı, içeriğini
MediaItem
nesnelerden oluşan bir ağaç yapısında düzenler. Bir medya öğesi aşağıdaki işaretlerden birini veya ikisini birden içerebilir:FLAG_PLAYABLE
: Öğenin, içerik ağacında bir yaprak olduğunu gösterir. Öğe, albümdeki bir şarkı, sesli kitaptaki bir bölüm veya podcast'in bir bölümü gibi tek bir ses akışını temsil eder.FLAG_BROWSABLE
: Öğenin içerik ağacında bir düğüm olduğunu ve alt öğeleri olduğunu gösterir. Örneğin, öğe bir albümü, alt öğeleri ise albümdeki şarkıları temsil eder.
Hem göz atılabilir hem de oynatılabilir bir medya öğesi, oynatma listesi gibi davranır. Öğenin tüm alt öğelerini oynatmak için öğeyi seçebilir veya alt öğelerine göz atabilirsiniz.
- Araç optimizasyonlu
Android Automotive OS tasarım kurallarına uyan bir Android Automotive OS uygulaması için etkinlik. Bu etkinliklerin arayüzü Android Automotive OS tarafından çizilmez. Bu nedenle, uygulamanızın tasarım yönergelerine uyduğundan emin olmanız gerekir. Genellikle daha büyük dokunma hedefleri ve yazı tipi boyutları, gündüz ve gece modları desteği ve daha yüksek kontrast oranları bu kapsamdadır.
Araç için optimize edilmiş kullanıcı arayüzlerinin yalnızca Araba Kullanıcı Deneyimi Kısıtlamaları (CUXR'ler) geçerli olmadığında gösterilmesine izin verilir. Çünkü bu arayüzler, kullanıcının uzun süre dikkatini vermesini veya etkileşimde bulunmasını gerektirebilir. CUXR'ler, araç durdurulduğunda veya park edildiğinde geçerli değildir ancak araç hareket halindeyken her zaman geçerlidir.
Android Auto, medya tarayıcı hizmetinizdeki bilgileri kullanarak araca göre optimize edilmiş kendi arayüzünü oluşturduğundan Android Auto için etkinlik tasarlamanız gerekmez.
Uygulamanızın manifest dosyalarını yapılandırma
Medya tarayıcı hizmetinizi oluşturmadan önce uygulamanızın manifest dosyalarını yapılandırmanız gerekir.
Medya tarayıcı hizmetinizi beyan etme
Hem Android Auto hem de Android Automotive OS, medya öğelerine göz atmak için medya tarayıcı hizmetiniz üzerinden uygulamanıza bağlanır. Android Auto ve Android Automotive OS'in hizmeti keşfedip uygulamanıza bağlanabilmesi için medya tarayıcı hizmetinizi manifest dosyanızda beyan edin.
Aşağıdaki kod snippet'inde, medya tarayıcı hizmetinizi manifestinizde nasıl beyan edeceğiniz gösterilmektedir. Bu kodu, Android Automotive OS modülünüzün manifest dosyasına ve telefon uygulamanızın manifest dosyasına ekleyin.
<application>
...
<service android:name=".MyMediaBrowserService"
android:exported="true">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService"/>
</intent-filter>
</service>
...
</application>
Uygulama simgelerini belirtin
Android Auto ve Android Automotive OS'in, uygulamanızı sistem kullanıcı arayüzünde temsil etmek için kullanabileceği uygulama simgelerini belirtmeniz gerekir. İki simge türü gereklidir:
- Başlatıcı simgesi
- İlişkilendirme simgesi
Başlatıcı simgesi
Başlatıcı simgesi, uygulamanızı sistem kullanıcı arayüzünde (ör. başlatıcıda ve simge tepsisinde) temsil eder. Aşağıdaki manifest beyanını kullanarak araba medya uygulamanızı temsil etmek için mobil uygulamanızdaki simgeyi kullanmak istediğinizi belirtebilirsiniz:
<application
...
android:icon="@mipmap/ic_launcher"
...
/>
Mobil uygulamanızın simgesinden farklı bir simge kullanmak için manifest dosyasındaki medya tarayıcı hizmetinizin android:icon
öğesinde android:icon
özelliğini ayarlayın:<service>
<application>
...
<service
...
android:icon="@mipmap/auto_launcher"
...
/>
</application>
İlişkilendirme simgesi

1.şekil Medya kartındaki ilişkilendirme simgesi.
Atıf simgesi, medya içeriğinin öncelikli olduğu yerlerde (ör. medya kartlarında) kullanılır. Bildirimler için kullanılan küçük simgeyi yeniden kullanabilirsiniz. Bu simge tek renkli olmalıdır. Aşağıdaki manifest bildirimini kullanarak uygulamanızı temsil etmek için kullanılan bir simge belirtebilirsiniz:
<application>
...
<meta-data
android:name="androidx.car.app.TintableAttributionIcon"
android:resource="@drawable/ic_status_icon" />
...
</application>
Medya tarayıcı hizmetinizi oluşturma
MediaBrowserServiceCompat
sınıfını genişleterek bir medya tarayıcı hizmeti oluşturursunuz. Android Auto ve Android Automotive OS, hizmetinizi kullanarak şunları yapabilir:
- Kullanıcıya bir menü sunmak için uygulamanızın içerik hiyerarşisine göz atın.
- Ses oynatmayı kontrol etmek için uygulamanızın
MediaSessionCompat
nesnesinin jetonunu alın.
Ayrıca, medya tarayıcı hizmetinizi kullanarak diğer istemcilerin uygulamanızdaki medya içeriklerine erişmesine izin verebilirsiniz. Bu medya istemcileri, kullanıcının telefonundaki diğer uygulamalar veya diğer uzak istemciler olabilir.
Medya tarayıcı hizmeti iş akışı
Bu bölümde, Android Automotive OS ve Android Auto'nun tipik bir kullanıcı iş akışı sırasında medya tarayıcı hizmetinizle nasıl etkileşimde bulunduğu açıklanmaktadır.
- Kullanıcı, uygulamanızı Android Automotive OS veya Android Auto'da başlatır.
- Android Automotive OS veya Android Auto,
onCreate()
yöntemini kullanarak uygulamanızın medya tarayıcı hizmetiyle iletişim kurar.onCreate()
yöntemini uygularken birMediaSessionCompat
nesnesi ve geri çağırma nesnesi oluşturup kaydetmeniz gerekir. - Android Automotive OS veya Android Auto, içerik hiyerarşinizdeki kök medya öğesini almak için hizmetinizin
onGetRoot()
yöntemini çağırır. Kök medya öğesi gösterilmez. Bunun yerine, uygulamanızdan daha fazla içerik almak için kullanılır. - Android Automotive OS veya Android Auto, hizmetinizin kök medya öğesinin alt öğelerini almak için
onLoadChildren()
yöntemini çağırır. Android Automotive OS ve Android Auto, bu medya öğelerini içerik öğelerinin en üst düzeyinde gösterir. Sistemin bu düzeyde ne beklediği hakkında daha fazla bilgi için bu sayfadaki Kök menüyü yapılandırma bölümüne bakın. - Kullanıcı, göz atılabilir bir medya öğesi seçerse seçilen menü öğesinin alt öğelerini almak için hizmetinizin
onLoadChildren()
yöntemi tekrar çağrılır. - Kullanıcı oynatılabilir bir medya öğesi seçerse Android Automotive OS veya Android Auto, bu işlemi gerçekleştirmek için uygun medya oturumu geri çağırma yöntemini çağırır.
- Uygulamanız destekliyorsa kullanıcılar içeriğinizi de arayabilir. Bu durumda, Android Automotive OS veya Android Auto, hizmetinizin
onSearch()
yöntemini çağırır.
İçerik hiyerarşinizi oluşturma
Android Auto ve Android Automotive OS, hangi içeriklerin kullanılabildiğini öğrenmek için uygulamanızın medya tarayıcı hizmetini çağırır. Bunu desteklemek için medya tarayıcı hizmetinizde iki yöntem uygulamanız gerekir: onGetRoot()
ve onLoadChildren()
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 Android Automotive OS, onLoadChildren()
yöntemini kullanarak içeriklerinizin geri kalanını istemek için bu kök düğümü kullanır.
Aşağıdaki kod snippet'inde, onGetRoot()
yönteminin basit 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 daha ayrıntılı bir örnek için GitHub'daki Universal Android Music Player örnek uygulamasında onGetRoot()
yöntemine bakın.
onGetRoot() için paket doğrulaması ekleyin
Hizmetinizin onGetRoot()
yöntemine bir çağrı 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, clientPackageName
değerini izin verilenler listenizle karşılaştırarak ve paketin APK'sını imzalamak için kullanılan sertifikayı doğrulayarak uygulamanızın içeriğine erişimi onaylanmış paketlerin listesiyle kısıtlayabilirsiniz. Paket doğrulanamazsa içeriğinize erişimi reddetmek için null
döndürün.
Android Auto ve Android Automotive OS gibi sistem uygulamalarının içeriğinize erişebilmesi için hizmetiniz, bu sistem uygulamaları onGetRoot()
yöntemini çağırdığında her zaman null olmayan bir BrowserRoot
döndürmelidir. Android Automotive OS sistem uygulamasının imzası, arabanın markasına ve modeline göre değişebilir. Bu nedenle, Android Automotive OS'i güçlü bir şekilde desteklemek için tüm sistem uygulamalarından gelen bağlantılara izin vermeniz gerekir.
Aşağıdaki 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'ın, Android Auto'nun dahil olduğu telefon ve Android Automotive OS için ayrı paket adları olduğunu unutmayın.
onLoadChildren() işlevini uygulama
Android Auto ve Android Automotive OS, kök düğüm nesnenizi aldıktan sonra alt öğelerini almak için kök düğüm nesnesinde onLoadChildren()
çağrısı yaparak üst düzey bir menü oluşturur. İstemci uygulamaları, alt 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ı bir alt menüye göz atmak veya bir medya öğesini oynatmak istediğinde jetonu iletir. Uygulamanız, jetonu uygun medya öğesiyle ilişkilendirmekten sorumludur.
Aşağıdaki kod snippet'inde, onLoadChildren()
yönteminin basit bir uygulaması gösterilmektedir:
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 eksiksiz bir örneği için GitHub'daki Universal Android Music Player örnek uygulamasında onLoadChildren()
yöntemine bakın.
Kök menüyü yapılandırma

Şekil 2. Kök içerik, gezinme sekmeleri olarak gösterilir.
Android Auto ve Android Automotive OS, kök menünün yapısıyla ilgili belirli kısıtlamalara sahiptir. Bunlar, MediaBrowserService
ile Bundle
bağımsız değişkeni kullanılarak okunabilen kök ipuçları aracılığıyla onGetRoot()
'e iletilir.
Bu ipuçlarını uyguladığınızda sistem, kök içeriği gezinme sekmeleri olarak en iyi şekilde gösterebilir. Bu ipuçlarını dikkate almazsanız bazı temel içerikler sistem tarafından kaldırılabilir veya daha az görünür hale getirilebilir. İki ipucu gönderilir:
- Kök öğe sayısı sınırı: Çoğu durumda bu sayının dört olmasını bekleyebilirsiniz. Bu, dört sekmeden fazlasının gösterilemeyeceği anlamına gelir.
- Kök alt öğelerde desteklenen işaretler:
Bu değerin
MediaItem#FLAG_BROWSABLE
olmasını bekleyebilirsiniz. Bu nedenle, sekmeler olarak yalnızca göz atılabilir öğeler (oynatılabilir öğeler değil) gösterilebilir.
İ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... }
Özellikle hiyerarşiniz Android Auto ve Android Automotive OS dışındaki MediaBrowser
entegrasyonlar arasında farklılık gösteriyorsa içerik hiyerarşinizin yapısıyla ilgili mantığı 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, sekmelerin en iyi şekilde oluşturulmasını sağlamak için uymanız gereken birkaç ek yönerge vardır:
- Her sekme öğesi için tek renkli, tercihen beyaz simgeler sağlayın.
- Her sekme öğesi için kısa ama anlamlı etiketler sağlayın. Etiketleri kısa tutmak, dizelerin kesilme olasılığını azaltır.
Görüntülü reklam medya öğesi
Medya öğelerinin resimleri, ContentResolver.SCHEME_CONTENT
veya ContentResolver.SCHEME_ANDROID_RESOURCE
kullanılarak yerel URI olarak iletilmelidir.
Bu yerel URI, uygulamanın kaynaklarında bit eşlem veya vektör çizilebilir öğeye çözümlenmelidir. İçerik hiyerarşisindeki öğeleri temsil eden MediaDescriptionCompat
nesneleri için URI'yi setIconUri()
üzerinden iletin.
Şu anda oynatılan öğeyi temsil eden MediaMetadataCompat
nesneleri için URI'yi aşağıdaki anahtarlardan herhangi birini kullanarak putString()
üzerinden iletin:
MediaMetadataCompat.METADATA_KEY_DISPLAY_ICON_URI
MediaMetadataCompat.METADATA_KEY_ART_URI
MediaMetadataCompat.METADATA_KEY_ALBUM_ART_URI
Aşağıdaki adımlarda, bir web URI'sinden nasıl resim indirileceği ve yerel bir URI aracılığıyla nasıl gösterileceği açıklanmaktadır. Daha eksiksiz bir örnek için Universal Android Music Player örnek uygulamasında openFile()
ve çevreleyen yöntemlerin uygulanmasına bakın.
Web URI'sine karşılık gelen bir
content://
URI'si oluşturun. Medya tarayıcı hizmeti ve medya oturumu, bu içerik URI'sini Android Auto ve Android Automotive OS'e iletir.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(); }
ContentProvider.openFile()
uygulamanızda, ilgili URI için bir dosyanın mevcut olup olmadığını kontrol edin. Aksi takdirde, resim dosyasını indirip önbelleğe alın. Aşağıdaki kod snippet'inde Glide kullanılıyor.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ılar hakkında daha fazla bilgi için İçerik sağlayıcı oluşturma başlıklı makaleyi inceleyin.
İçerik stillerini uygulama
Göz atılabilir veya oynatılabilir öğeler kullanarak içerik hiyerarşinizi oluşturduktan sonra, bu öğelerin arabada nasıl görüntüleneceğini belirleyen içerik stilleri uygulayabilirsiniz.
Aşağıdaki içerik stillerini kullanabilirsiniz:
- Liste öğeleri
-
Bu içerik stilinde başlıklar ve meta veriler, resimlere göre önceliklidir.
- Tablo öğeleri
-
Bu içerik stilinde, başlıklar ve meta veriler yerine resimlere öncelik verilir.
Varsayılan içerik stillerini ayarlama
Hizmetinizin onGetRoot()
yönteminin BrowserRoot
ekstralar paketine belirli sabitleri ekleyerek medya öğelerinizin nasıl görüntüleneceğiyle ilgili genel varsayılanlar ayarlayabilirsiniz. Android Auto ve Android Automotive OS, bu paketi okur ve uygun stili belirlemek için bu sabitleri arar.
Pakette anahtar olarak aşağıdaki ekstralar kullanılabilir:
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
: Göz atma ağacındaki tüm göz atılabilir öğeler için bir sunum ipucunu gösterir.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
: Göz atma ağacındaki tüm oynatılabilir öğeler için bir sunum ipucunu gösterir.
Anahtarlar, bu öğelerin sunumunu etkilemek için aşağıdaki tam sayı sabit değerleriyle eşlenebilir:
DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_LIST_ITEM
: İlgili öğeler liste öğeleri olarak sunulur.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_GRID_ITEM
: İlgili öğeler ızgara öğeleri olarak sunulur.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_LIST_ITEM
: İlgili öğeler "kategori" liste öğeleri olarak sunulur. Bunlar, öğelerin simgeleri küçük olduğunda daha iyi göründüğünden, öğelerin simgelerinin etrafına kenar boşlukları uygulanması dışında normal liste öğeleriyle aynıdır. Simgeler, renklendirilebilir vektör çizimleri olmalıdır. Bu ipucunun yalnızca göz atılabilir öğeler için sağlanması beklenir.DESCRIPTION_EXTRAS_VALUE_CONTENT_STYLE_CATEGORY_GRID_ITEM
: İlgili öğeler "kategori" ızgara öğeleri olarak sunulur. Bunlar, öğelerin simgelerinin etrafına kenar boşlukları uygulanması dışında normal tablo öğeleriyle aynıdır. Bunun nedeni, simgelerin küçükken daha iyi görünmesidir. Simgeler, renklendirilebilir vektör çizimleri olmalıdır. Bu ipucunun yalnızca göz atılabilir öğeler için sağlanması beklenir.
Aşağıdaki kod snippet'inde, göz atılabilir öğeler için varsayılan içerik stilinin ızgara, oynatılabilir öğeler için ise liste olarak nasıl ayarlanacağı gösterilmektedir:
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 stilleri ayarlama
Content Style API, göz atılabilir herhangi bir medya öğesinin alt öğeleri ve medya öğesinin kendisi için varsayılan içerik stilini geçersiz kılmanıza olanak tanır.
Göz atılabilir bir medya öğesinin alt öğeleri için varsayılanı geçersiz kılmak istiyorsanız medya öğesinin MediaDescription
bölümünde bir ekler paketi oluşturun ve daha önce bahsedilen ipuçlarını ekleyin. DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_PLAYABLE
bu öğenin oynatılabilir alt öğeleri için geçerliyken
DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_BROWSABLE
bu öğenin
göz atılabilir alt öğeleri için geçerlidir.
Bir medya öğesinin kendisi için varsayılanı geçersiz kılmak istiyorsanız (alt öğeleri için değil) medya öğesinin MediaDescription
bölümünde bir ekler paketi oluşturun ve DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_SINGLE_ITEM
anahtarıyla bir ipucu ekleyin.
Öğenin sunumunu belirtmek için daha önce açıklanan değerleri kullanın.
Aşağıdaki kod snippet'inde, hem kendisi hem de alt öğeleri için varsayılan içerik stilini geçersiz kılan, göz atılabilir bir MediaItem
öğesinin nasıl oluşturulacağı gösterilmektedir. Kendisini kategori liste öğesi, göz atılabilir alt öğelerini liste öğesi ve oynatılabilir alt öğelerini ızgara öğesi olarak biçimlendirir:
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); }
SINGLE_ITEM
ipucu kullanılır.
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. Bir gruptaki her medya öğesi, MediaDescription
içinde bir ek paket bildirmelidir. Bu paket, DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE
anahtarıyla eşleme ve aynı dize değerini içermelidir. Grubun başlığı olarak kullanılan bu dizeyi yerelleştirin.
Aşağıdaki kod snippet'inde, "Songs"
alt grup başlığına sahip bir MediaItem
öğesinin nasıl oluşturulacağı gösterilmektedir:
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, gruplandırmak istediğiniz tüm medya öğelerini bitişik bir blok olarak iletmelidir. Örneğin, "Şarkılar" ve "Albümler" olmak üzere iki grup medya öğesini bu sırayla göstermek istediğinizi ve uygulamanızın beş medya öğesini aşağıdaki sırayla ilettiğini varsayalım:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
içeren A medya öğesiextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
içeren B medya öğesiextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
ile medya öğesi Cextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
ile medya öğesi Dextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
içeren E medya öğesi
"Şarkılar" ve "Albümler" grubundaki medya öğeleri bitişik bloklar halinde tutulmadığından Android Auto ve Android Automotive OS bunu aşağıdaki dört grup olarak yorumlar:
- "Şarkılar" adlı 1. grup (A medya öğesini içerir)
- Medya öğesi B'yi içeren "Albümler" adlı 2. grup
- C ve D medya öğelerini içeren "Şarkılar" adlı 3. grup
- Medya öğesi E'yi içeren "Albümler" adlı 4. grup
Bu öğeleri iki grupta göstermek için uygulamanızın medya öğelerini aşağıdaki sırayla iletmesi gerekir:
extras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
içeren A medya öğesiextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
ile medya öğesi Cextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Songs")
ile medya öğesi Dextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
içeren B medya öğesiextras.putString(MediaConstants.DESCRIPTION_EXTRAS_KEY_CONTENT_STYLE_GROUP_TITLE, "Albums")
içeren E medya öğesi
Ek meta veri göstergelerini görüntüleme
Medya tarayıcı ağacındaki ve oynatma sırasındaki içeriklerle ilgili bilgileri bir bakışta görmek için ek meta veri göstergeleri ekleyebilirsiniz. Göz atma ağacında Android Auto ve Android Automotive OS, bir öğeyle ilişkili ekstraları okur ve hangi göstergelerin görüntüleneceğini belirlemek için belirli sabitleri arar. Medya oynatma sırasında Android Auto ve Android Automotive OS, medya oturumunun meta verilerini okur ve gösterilecek göstergeleri belirlemek için belirli sabitleri arar.

3.Şekil Şarkıyı ve sanatçıyı tanımlayan meta verilerin yanı sıra uygunsuz içeriği gösteren bir simge içeren oynatma görünümü.

Şekil 4. İlk öğede oynatılmamış içerik için nokta, ikinci öğede ise kısmen oynatılmış içerik için ilerleme çubuğu bulunan göz atma görünümü.
Aşağıdaki sabitler hem MediaItem
açıklama ekstralarında hem de MediaMetadata
ekstralarında kullanılabilir:
EXTRA_DOWNLOAD_STATUS
: Bir öğenin indirme durumunu gösterir. Bu sabiti anahtar olarak kullanın. Olası değerler aşağıdaki uzun sabitlerdir:STATUS_DOWNLOADED
: Öğe tamamen indirildiğinde.STATUS_DOWNLOADING
: Öğe indiriliyor.STATUS_NOT_DOWNLOADED
: Öğe indirilmemiştir.
METADATA_KEY_IS_EXPLICIT
: Öğenin uygunsuz içerik barındırıp barındırmadığını gösterir. Bir öğenin uygunsuz olduğunu belirtmek için anahtar olarak bu sabiti, değer olarak ise uzunMETADATA_VALUE_ATTRIBUTE_PRESENT
değerini kullanın.
Aşağıdaki sabitler yalnızca MediaItem
açıklama eklerinde kullanılabilir:
DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
: Podcast bölümleri veya sesli kitaplar gibi uzun içeriklerin tamamlanma durumunu gösterir. Anahtar olarak bu sabiti kullanın. Olası değerler aşağıdaki tam sayı sabitleridir:DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_NOT_PLAYED
: Öğe hiç oynatılmamıştır.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_PARTIALLY_PLAYED
: Öğe kısmen oynatılmış ve geçerli konum ortada bir yerdedir.DESCRIPTION_EXTRAS_VALUE_COMPLETION_STATUS_FULLY_PLAYED
: Öğe tamamlanmıştır.
DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
: Uzun içeriklerdeki tamamlama ilerleme durumunu 0,0 ile 1,0 arasında (bu değerler dahil) bir çift sayı olarak gösterir. Bu ek,PARTIALLY_PLAYING
durumu hakkında daha fazla bilgi sağlar. Böylece Android Auto veya Android Automotive OS, ilerleme çubuğu gibi daha anlamlı bir ilerleme göstergesi görüntüler. Bu ek özelliği kullanıyorsanız ilk gösterimden sonra bu göstergeyi nasıl güncel tutacağınızı öğrenmek için bu rehberdeki içerik oynatılırken göz atma görünümündeki ilerleme çubuğunu güncelleme bölümüne bakın.
Kullanıcı medya göz atma ağacına göz atarken görünen göstergeleri görüntülemek için bu sabitlerden birini veya daha fazlasını içeren bir ekler paketi oluşturun ve bu paketi MediaDescription.Builder.setExtras()
yöntemine iletin.
Aşağıdaki kod snippet'inde, %70'i tamamlanmış bir uygunsuz medya öğesi için göstergelerin nasıl görüntüleneceği gösterilmektedir:
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 */);
Şu anda oynatılan bir medya öğesi için göstergeleri görüntülemek üzere METADATA_KEY_IS_EXPLICIT
veya EXTRA_DOWNLOAD_STATUS
için Long
değerlerini mediaSession
öğenizin MediaMetadataCompat
bölümünde bildirebilirsiniz. Oynatma görünümünde DESCRIPTION_EXTRAS_KEY_COMPLETION_STATUS
veya DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
göstergelerini görüntüleyemezsiniz.
Aşağıdaki kod snippet'inde, oynatma görünümündeki mevcut şarkının uygunsuz içerik barındırdığı ve indirildiği nasıl belirtileceği gösterilmektedir:
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üncelleme
Daha önce de belirtildiği gibi, göz atma görünümünde kısmen oynatılan içerik için ilerleme çubuğu göstermek üzere DESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
ekstrasını kullanabilirsiniz. Ancak, kullanıcı kısmen oynatılan içeriği Android Auto veya Android Automotive OS'de oynatmaya devam ederse bu gösterge zaman geçtikçe yanlış hale gelir.
Android Auto ve Android Automotive OS'de ilerleme çubuğunun güncel kalması için MediaMetadataCompat
ve PlaybackStateCompat
içinde ek bilgiler sağlayarak devam eden içerikleri göz atma görünümündeki medya öğelerine bağlayabilirsiniz. Medya öğesinin otomatik olarak güncellenen bir ilerleme çubuğuna sahip olması için aşağıdaki koşulların karşılanması gerekir:
- Oluşturulduğunda
MediaItem
, ekstralarında 0,0 ile 1,0 arasında (bu değerler dahil) bir değere sahipDESCRIPTION_EXTRAS_KEY_COMPLETION_PERCENTAGE
göndermelidir. MediaMetadataCompat
,MediaItem
'ya iletilen medya kimliğine eşit bir dize değeriyleMETADATA_KEY_MEDIA_ID
göndermelidir.PlaybackStateCompat
,MediaItem
'ya iletilen medya kimliği ile eşit bir dize değerine karşılık gelenPLAYBACK_STATE_EXTRAS_KEY_MEDIA_ID
anahtarıyla bir ek içermelidir.
Aşağıdaki kod snippet'inde, şu anda oynatılan öğenin göz atma görünümündeki bir öğeye nasıl bağlandığı gösterilmektedir:
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());
Göz atılabilir arama sonuçlarını görüntüleme

5.şekil Kullanıcının sesli aramasıyla ilgili medya öğelerini görüntülemek için "Arama sonuçları" seçeneği içeren oynatma görünümü.
Uygulamanız, kullanıcılar arama sorgusu başlattığında gösterilen bağlamsal arama sonuçları sağlayabilir. Android Auto ve Android Automotive OS, bu sonuçları arama sorgusu arayüzleri veya oturumda daha önce yapılan sorgulara dayalı olanaklar aracılığıyla gösterir. Daha fazla bilgi edinmek için bu kılavuzdaki Sesli işlemleri destekleme bölümüne bakın.
Göz atılabilir arama sonuçları göstermek için hizmetinizin onGetRoot()
yönteminin ekstralar paketine BROWSER_SERVICE_EXTRAS_KEY_SEARCH_SUPPORTED
sabit anahtarını ekleyin ve bunu true
boole'uyla eşleyin.
Aşağıdaki kod snippet'inde, onGetRoot()
yönteminde desteğin nasıl etkinleştirileceği gösterilmektedir:
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 medya tarayıcı hizmetinizdeki onSearch()
yöntemini geçersiz kılın. Android Auto ve Android Automotive OS, kullanıcı bir arama sorgusu arayüzünü veya "Arama sonuçları" işlevini her çağırdığında kullanıcının arama terimlerini bu yönteme yönlendirir.
Hizmetinizin onSearch()
yönteminden gelen arama sonuçlarını, daha kolay göz atılabilir hale getirmek için başlık öğeleri kullanarak düzenleyebilirsiniz. Örneğin, uygulamanızda müzik çalınıyorsa arama sonuçlarını albüme, sanatçıya ve şarkıya göre düzenleyebilirsiniz.
Aşağıdaki kod snippet'inde, onSearch()
yönteminin basit bir uygulaması gösterilmektedir:
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

6.şekil Tek Özel Göz Atma İşlemi
Özel Göz Atma İşlemleri, uygulamanızın MediaItem
nesnelerine özel simgeler ve etiketler eklemenize, ayrıca bu işlemlerle kullanıcı etkileşimlerini yönetmenize olanak tanır. Bu sayede, "İndir", "Kuyruğa ekle", "Radyo çal", "Favorilere ekle" veya "Kaldır" gibi işlemler ekleyerek Medya Uygulaması'nın işlevselliğini çeşitli şekillerde genişletebilirsiniz.

Şekil 7. Özel Göz Atma İşlemi taşması
OEM'nin görüntülenmesine izin verdiğinden daha fazla özel işlem varsa kullanıcıya bir taşma menüsü gösterilir.
İşleyiş şekli nasıldır?
Her özel göz atma işlemi şu şekilde tanımlanır:
- İşlem kimliği (benzersiz dize tanımlayıcı)
- İşlem etiketi (kullanıcıya gösterilen metin)
- İşlem simgesi URI'si (renklendirilebilen bir drawable vektör)
BrowseRoot
kapsamında, özel göz atma işlemlerinin listesini genel olarak tanımlarsınız. Ardından, bu işlemlerin bir alt kümesini ayrı ayrıMediaItem.
Kullanıcı, özel göz atma işlemiyle etkileşim kurduğunda uygulamanız onCustomAction()
içinde geri çağırma alır. Ardından, işlemi gerçekleştirebilir ve gerekirse MediaItem
için işlem listesini güncelleyebilirsiniz. Bu, "Favorilere ekle" ve "İndir" gibi durum bilgisi içeren işlemler için kullanışlıdır. "Radyo Çal" gibi güncellenmesi gerekmeyen işlemler için işlem listesini güncellemeniz gerekmez.

Şekil 8. Özel Göz Atma İşlemi araç çubuğu
Özel Göz Atma İşlemleri'ni bir göz atma düğümü köküne de ekleyebilirsiniz. Bu işlemler, ana araç çubuğunun altındaki ikincil bir araç çubuğunda gösterilir.
Özel göz atma işlemlerini uygulama
Projenize özel göz atma işlemleri eklemek için aşağıdaki adımları uygulayın:
MediaBrowserServiceCompat
uygulamanızda iki yöntemi geçersiz kılın:- Çalışma zamanında işlem sınırlarını ayrıştırın:
onGetRoot()
içinde,rootHints
Bundle
içindekiBROWSER_ROOT_HINTS_KEY_CUSTOM_BROWSER_ACTION_LIMIT
anahtarını kullanarak herMediaItem
için izin verilen maksimum işlem sayısını alın. 0 sınırı, özelliğin sistem tarafından desteklenmediğini gösterir.
- Özel Göz Atma İşlemleri'nin genel listesini oluşturun:
- Her işlem için aşağıdaki anahtarlara sahip 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şlemBundle
nesnelerini bir listeye ekleyin.
- Her işlem için aşağıdaki anahtarlara sahip bir
- Genel listeyi
BrowseRoot
hesabınıza ekleyin:BrowseRoot
ekstralarındaBundle
, işlem listesini anahtarı kullanarakParcelable
Arraylist
olarak ekleyinBROWSER_SERVICE_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ROOT_LIST
.
MediaItem
nesnelerinize işlemler ekleyin:DESCRIPTION_EXTRAS_KEY_CUSTOM_BROWSER_ACTION_ID_LIST
anahtarını kullanarakMediaDescriptionCompat
ekstralarında işlem kimliklerinin listesini ekleyerek işlemleri tek tekMediaItem
nesnelerine ekleyebilirsiniz. Bu liste,BrowseRoot
içinde tanımladığınız genel işlem listesinin bir alt kümesi olmalıdır.
- İşlemleri gerçekleştirme ve ilerleme durumunu veya sonuçları döndürme:
onCustomAction
içinde, işlemi işlem kimliğine ve ihtiyaç duyduğunuz diğer verilere göre gerçekleştirin.EXTRAS_KEY_CUSTOM_BROWSER_ACTION_MEDIA_ITEM_ID
anahtarını kullanarak, işlemi tetikleyenMediaItem
öğesinin kimliğini ekstralardan alabilirsiniz.- İlerleme veya sonuç paketine
MediaItem
anahtarını ekleyerekEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
için işlem listesini güncelleyebilirsiniz.
Özel Göz Atma İşlemleri'ni kullanmaya başlamak için BrowserServiceCompat
bölümünde yapabileceğiniz bazı değişiklikler aşağıda verilmiştir.
Override BrowserServiceCompat
MediaBrowserServiceCompat
içinde aşağıdaki yöntemleri geçersiz kılmanız gerekir.
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şlemleri sınırı
Kaç özel göz atma iş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 Oluşturma
Her işlem ayrı bir Bundle
içine yerleştirilmelidir.
- İş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
'e özel göz atma işlemleri ekleme
Tüm Özel Göz Atma İşlemi Bundle
nesnelerini bir ArrayList
içine 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 işlemi listesi ekleme
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
adlı reklam grubuna işlem ekleme
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 değerini ayrıştırın:@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üncelleme(bir öğedeki işlemleri güncellemek için kullanılır)
mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM, mediaId);
- Oynatma görünümünü açma
//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üncelleme
//Change current browse node to mediaId mResultBundle.putString(EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_BROWSE_NODE, mediaId);
- Kullanıcıya mesaj
- Hata varsa
result.sendError(resultBundle).
numaralı telefonu arayın. - İlerleme durumu güncellemesi için
result.sendProgressUpdate(resultBundle)
numaralı telefonu arayın. result.sendResult(resultBundle)
numarasını arayarak işlemi tamamlayın.
İşlem durumunu güncelleme
result.sendProgressUpdate(resultBundle)
yöntemini EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
anahtarıyla kullanarak MediaItem
değerini işlemin yeni durumunu yansıtacak şekilde güncelleyebilirsiniz. Bu sayede, kullanıcılara işlemlerinin ilerleme durumu ve sonucu hakkında anlık geri bildirim verebilirsiniz.
Örnek: İndirme İşlemi
Bu özelliği kullanarak üç durumlu bir indirme işlemi uygulama örneğini aşağıda bulabilirsiniz:
- İndir: Bu, işlemin ilk durumudur. Kullanıcı bu işlemi seçtiğinde "İndiriliyor" ile değiştirebilir ve kullanıcı arayüzünü güncellemek için
sendProgressUpdate
işlevini çağırabilirsiniz. - İndiriliyor: Bu durum, indirme işleminin devam ettiğini gösterir. Bu durumu, kullanıcıya bir ilerleme çubuğu veya başka bir gösterge göstermek için kullanabilirsiniz.
- İndirildi: Bu durum, indirme işleminin tamamlandığını gösterir. İndirme işlemi tamamlandığında "İndiriliyor" ifadesini "İndirildi" ile değiştirebilir ve öğenin yenilenmesi gerektiğini belirtmek için
sendResult
işleviniEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
anahtarıyla çağırabilirsiniz. Ayrıca, kullanıcıya başarı mesajı göstermek içinEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_MESSAGE
anahtarını da kullanabilirsiniz.
Bu yaklaşım, indirme işlemi ve mevcut durumu hakkında kullanıcıya net geri bildirim vermenizi sağlar. %25, %50 ve% 75 indirme durumlarını göstermek için simgelerle daha fazla ayrıntı ekleyebilirsiniz.
Örnek: Favori İşlem
Bir başka örnek de iki durumu olan favori bir işlem:
- Favori: Bu işlem, kullanıcının favoriler listesinde olmayan öğeler için gösterilir. Kullanıcı bu işlemi seçtiğinde, işlemi "Favorilere eklendi" ile değiştirebilir ve kullanıcı arayüzünü güncellemek için
EXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
anahtarıylasendResult
işlevini çağırabilirsiniz. - Favorilere eklenenler: Bu işlem, kullanıcının favoriler listesindeki öğeler için gösterilir. Kullanıcı bu işlemi seçtiğinde "Favori" ile değiştirebilir ve kullanıcı arayüzünü güncellemek için
sendResult
işleviniEXTRAS_KEY_CUSTOM_BROWSER_ACTION_RESULT_REFRESH_ITEM
anahtarıyla çağırabilirsiniz.
Bu yaklaşım, kullanıcıların favori öğelerini yönetmesi için net ve tutarlı bir yol sunar.
Bu örnekler, Özel Göz Atma İşlemlerinin esnekliğini ve bunları kullanarak arabanın medya uygulamasında gelişmiş bir kullanıcı deneyimi için çeşitli işlevleri nasıl uygulayabileceğinizi gösterir.
Bu özelliğin eksiksiz bir örnek uygulaması için
TestMediaApp
projesine başvurabilirsiniz.
Oynatma kontrolünü etkinleştirme
Android Auto ve Android Automotive OS, oynatma kontrolü komutlarını hizmetinizin MediaSessionCompat
üzerinden gönderir.
Bir oturum kaydetmeniz ve ilişkili geri çağırma yöntemlerini uygulamanız gerekir.
Medya oturumu kaydetme
Medya tarayıcı hizmetinizin onCreate()
yönteminde MediaSessionCompat
oluşturun,
ardından setSessionToken()
'ı çağırarak medya oturumunu kaydedin.
Aşağıdaki kod snippet'inde medya oturumunun nasıl oluşturulacağı ve kaydedileceği gösterilmektedir:
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, oynatma kontrolü isteklerini işlemek için kullanılan bir geri çağırma nesnesi ayarlarsınız. Bu geri çağırma nesnesini, uygulamanız için MediaSessionCompat.Callback
sınıfının bir uygulamasını sağlayarak oluşturursunuz. Sonraki bölümde, bu nesnenin nasıl uygulanacağı açıklanmaktadır.
Oynatma komutlarını uygulama
Bir kullanıcı uygulamanızdan bir medya öğesinin oynatılmasını istediğinde Android Automotive OS ve Android Auto, uygulamanızın medya tarayıcı hizmetinden elde ettikleri uygulamanızın MediaSessionCompat
nesnesindeki MediaSessionCompat.Callback
sınıfını kullanır. Kullanıcılar, içeriğin oynatılmasını kontrol etmek (ör. oynatmayı duraklatmak veya sonraki parçaya geçmek) istediğinde Android Auto ve Android Automotive OS, geri çağırma nesnesinin yöntemlerinden birini çağırır.
İçerik oynatmayı işlemek için uygulamanız, soyut MediaSessionCompat.Callback
sınıfını genişletmeli ve uygulamanızın desteklediği yöntemleri uygulamalıdır.
Uygulamanızın sunduğu içerik türü için anlamlı olan aşağıdaki geri çağırma yöntemlerinin tümünü uygulayın:
onPrepare()
- Medya kaynağı değiştirildiğinde çağrılır. Android Automotive OS de bu yöntemi başlatmadan hemen sonra çağırır. Medya uygulamanız bu yöntemi uygulamalıdır.
onPlay()
- Kullanıcı belirli bir öğe seçmeden oynatmayı seçerse çağrılır. Uygulamanız varsayılan içeriğini oynatmalı veya oynatma
onPause()
ile duraklatıldıysa oynatmaya devam etmelidir.Not: Android Automotive OS veya Android Auto, medya tarayıcı hizmetinize bağlandığında uygulamanız otomatik olarak müzik çalmaya başlamamalıdır. Daha fazla bilgi için ilk oynatma durumunu ayarlama bölümüne bakın.
onPlayFromMediaId()
- Kullanıcı belirli bir öğeyi oynatmayı seçtiğinde çağrılır. Yönteme, medya tarayıcı hizmetinizin içerik hiyerarşinizdeki medya öğesine atadığı kimlik iletilir.
onPlayFromSearch()
- Kullanıcı bir arama sorgusundan oynatmayı seçtiğinde çağrılır. Uygulama, iletilen arama dizesine göre uygun bir seçim yapmalıdır.
onPause()
- Kullanıcı oynatmayı duraklatmayı seçtiğinde çağrılır.
onSkipToNext()
- Kullanıcı bir sonraki öğeye geçmeyi seçtiğinde çağrılır.
onSkipToPrevious()
- Kullanıcı bir önceki öğeye gitmeyi seçtiğinde çağrılır.
onStop()
- Kullanıcı oynatmayı durdurmayı seçtiğinde çağrılır.
İstediğiniz işlevleri sağlamak için bu yöntemleri uygulamanızda geçersiz kılın. İşlevi uygulamanız tarafından desteklenmiyorsa yöntemi uygulamanız gerekmez. Örneğin, uygulamanızda spor yayını gibi bir canlı yayın oynatılıyorsa onSkipToNext()
yöntemini uygulamanız gerekmez. Bunun yerine onSkipToNext()
öğesinin varsayılan uygulamasını kullanabilirsiniz.
Uygulamanızın, içeriği arabanın hoparlörlerinden çalmak için özel bir mantığa ihtiyacı yoktur. Uygulamanız içerik oynatma isteği aldığında sesi, kullanıcının telefon hoparlörleri veya kulaklıkları aracılığıyla içerik oynattığı şekilde oynatabilir. Android Auto ve Android Automotive OS, sesli içeriği arabanın hoparlörlerinden çalmak için otomatik olarak arabanın sistemine gönderir.
Ses içeriği oynatma hakkında daha fazla bilgi için MediaPlayer'a genel bakış, Ses uygulamasına genel bakış ve ExoPlayer genel bakış bölümlerine bakın.
Standart oynatma işlemlerini ayarlama
Android Auto ve Android Automotive OS, PlaybackStateCompat
nesnesinde etkinleştirilen işlemlere göre oynatma kontrollerini gösterir.
Uygulamanız varsayılan olarak aşağıdaki işlemleri desteklemelidir:
Uygulamanız, içeriğiyle alakalı olması durumunda aşağıdaki işlemleri de destekleyebilir:
Ayrıca, kullanıcıya gösterilebilecek bir oynatma sırası oluşturma seçeneğiniz de vardır ancak bu zorunlu değildir. Bunu yapmak için setQueue()
ve setQueueTitle()
yöntemlerini çağırın, ACTION_SKIP_TO_QUEUE_ITEM
işlemini etkinleştirin ve geri çağırmayı onSkipToQueueItem()
tanımlayın.
Ayrıca, Ne çalıyor? simgesi için destek ekleyin. Bu simge, şu anda neyin çaldığını gösterir. Bunu yapmak için setActiveQueueItemId()
yöntemini çağırın ve kuyrukta şu anda oynatılan öğenin kimliğini iletin. Kuyrukta değişiklik olduğunda setActiveQueueItemId()
güncellemeniz gerekir.
Android Auto ve Android Automotive OS, etkinleştirilen her işlem için düğmelerin yanı sıra oynatma sırasını da gösterir. Düğmeler tıklandığında sistem, MediaSessionCompat.Callback
içindeki ilgili geri çağırmayı başlatır.
Kullanılmayan alanı ayırma
Android Auto ve Android Automotive OS, kullanıcı arayüzünde ACTION_SKIP_TO_PREVIOUS
ve ACTION_SKIP_TO_NEXT
işlemleri için yer ayırır. Uygulamanız bu işlevlerden birini desteklemiyorsa Android Auto ve Android Automotive OS, oluşturduğunuz özel işlemleri göstermek için bu alanı kullanır.
Bu alanları özel işlemlerle doldurmak istemiyorsanız Android Auto ve Android Automotive OS'in, uygulamanız ilgili işlevi desteklemediğinde alanı boş bırakması için bu alanları ayırabilirsiniz. Bunu yapmak için, ayrılmış işlevlere karşılık gelen sabitleri içeren bir ekstralar paketiyle setExtras()
yöntemini çağırın.
SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_NEXT
, ACTION_SKIP_TO_NEXT
'e, SESSION_EXTRAS_KEY_SLOT_RESERVATION_SKIP_TO_PREV
ise ACTION_SKIP_TO_PREVIOUS
'e karşılık gelir. Bu sabitleri pakette anahtar olarak, değerleri için ise boole true
olarak kullanın.
İlk PlaybackState'i ayarlama
Android Auto ve Android Automotive OS, medya tarayıcı hizmetinizle iletişim kurarken medya oturumunuz, PlaybackStateCompat
kullanarak içerik oynatma durumunu bildirir.
Uygulamanız, Android Automotive OS veya Android Auto medya tarayıcı hizmetinize bağlandığında müziği otomatik olarak çalmaya başlamamalıdır. Bunun yerine, arabanın durumuna veya kullanıcı işlemlerine göre oynatmayı devam ettirmek ya da başlatmak için Android Auto ve Android Automotive OS'e güvenin.
Bunu yapmak için medya oturumunuzun ilk PlaybackStateCompat
değerini STATE_STOPPED
, STATE_PAUSED
, STATE_NONE
veya STATE_ERROR
olarak ayarlayın.
Android Auto ve Android Automotive OS'teki medya oturumları yalnızca sürüş süresi boyunca devam eder. Bu nedenle kullanıcılar bu oturumları sık sık başlatır ve durdurur. Sürücüler arasında sorunsuz bir deneyim sağlamak için kullanıcının önceki oturum durumunu takip edin. Böylece, medya uygulaması devam ettirme isteği aldığında kullanıcı, kaldığı yerden (ör. son oynatılan medya öğesi, PlaybackStateCompat
ve sıra) otomatik olarak devam edebilir.
Özel oynatma işlemleri ekleme
Medya uygulamanızın desteklediği ek işlemleri göstermek için özel oynatma işlemleri ekleyebilirsiniz. Alan izin veriyorsa (ve ayrılmamışsa) Android, özel işlemleri aktarım kontrollerine ekler. Aksi takdirde, özel işlemler taşma menüsünde gösterilir. Özel işlemler, PlaybackStateCompat
hesabına eklendikleri sırayla gösterilir.
Standart işlemlerden farklı davranışlar sağlamak için özel işlemleri kullanın. Bunları standart işlemleri değiştirmek veya kopyalamak için kullanmayın.
PlaybackStateCompat.Builder
sınıfındaki addCustomAction()
yöntemini kullanarak özel işlemler ekleyebilirsiniz.
Aşağıdaki kod snippet'inde, özel bir "Radyo kanalı başlat" işleminin nasıl ekleneceği gösterilmektedir:
Kotlin
val customActionExtras = Bundle() customActionExtras.putInt( androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT, androidx.media3.session.CommandButton.ICON_RADIO) stateBuilder.addCustomAction( PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon // or R.drawable.media3_icon_radio ).run { setExtras(customActionExtras) build() } )
Java
Bundle customActionExtras = new Bundle(); customActionExtras.putInt( androidx.media3.session.MediaConstants.EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT, androidx.media3.session.CommandButton.ICON_RADIO); stateBuilder.addCustomAction( new PlaybackStateCompat.CustomAction.Builder( CUSTOM_ACTION_START_RADIO_FROM_MEDIA, resources.getString(R.string.start_radio_from_media), startRadioFromMediaIcon) // or R.drawable.media3_icon_radio .setExtras(customActionExtras) .build());
Bu yöntemle ilgili daha ayrıntılı bir örnek için GitHub'daki Universal Android Music Player örnek uygulamasında setCustomAction()
yöntemine bakın.
Özel işleminizi oluşturduktan sonra medya oturumunuz, onCustomAction()
yöntemini geçersiz kılarak işleme yanıt verebilir.
Aşağıdaki kod snippet'inde, uygulamanızın "Radyo kanalı başlat" işlemine nasıl yanıt verebileceği gösterilmektedir:
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öntemle ilgili daha ayrıntılı bir örnek için GitHub'daki Universal Android Music Player örnek uygulamasında onCustomAction
yöntemine bakın.
Özel işlemler için simgeler
Oluşturduğunuz her özel işlem için bir simge gerekir.
Bu simgenin açıklaması CommandButton.ICON_
sabitlerinden biriyle eşleşiyorsa özel işlemin ekstralarının EXTRAS_KEY_COMMAND_BUTTON_ICON_COMPAT
anahtarı için bu tam sayı değerini ayarlamanız gerekir. Desteklenen sistemlerde bu, CustomAction.Builder
öğesine iletilen simge kaynağını geçersiz kılarak sistem bileşenlerinin işleminizi ve diğer oynatma işlemlerini tutarlı bir tarzda oluşturmasına olanak tanır.
Ayrıca bir simge kaynağı da belirtmeniz gerekir. Arabalardaki uygulamalar birçok farklı ekran boyutunda ve yoğunluğunda çalışabilir. Bu nedenle, sağladığınız simgeler vektör çizilebilir olmalıdır. Vektör çizilebilir öğeler, ayrıntıları kaybetmeden öğeleri ölçeklendirmenize olanak tanır. Vektör çizilebilir öğeler, daha düşük çözünürlüklerde kenar ve köşeleri piksel sınırlarıyla hizalamayı da kolaylaştırır.
Özel bir işlem durum bilgiliyse (ör. oynatma ayarını açıp kapatıyorsa) farklı durumlar için farklı simgeler sağlayın. Böylece kullanıcılar işlemi seçtiklerinde bir değişiklik görebilir.
Devre dışı bırakılan işlemler için alternatif simge stilleri sağlama
Özel işlem geçerli bağlamda kullanılamıyorsa özel işlem simgesini, işlemin devre dışı olduğunu gösteren alternatif bir simgeyle değiştirin.
Ses biçimini belirtme
Ş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. Şu anda oynatılan medya öğesinin ekstralar paketinde (MediaSession.setMetadata()
'a iletilir) KEY_CONTENT_FORMAT_TINTABLE_LARGE_ICON_URI
ve KEY_CONTENT_FORMAT_TINTABLE_SMALL_ICON_URI
değerlerini ayarlayabilirsiniz. Farklı düzenlere uyum sağlamak için bu ekstraların ikisini de ayarladığınızdan emin olun.
Ayrıca, KEY_IMMERSIVE_AUDIO
ekstrasını ayarlayarak otomobil üreticilerine bunun sarmal ses olduğunu ve sarmal içerikle etkileşime girebilecek ses efektleri uygulayıp uygulamayacaklarına karar verirken çok dikkatli olmaları gerektiğini söyleyebilirsiniz.
Şu anda oynatılan öğeden bağlantı ekleme
Şu anda oynatılan medya öğesini, altyazısı, açıklaması veya her ikisi de diğer medya öğelerine bağlantı verecek şekilde yapılandırabilirsiniz. Bu sayede kullanıcı, ilgili öğelere hızlıca gidebilir. Örneğin, aynı sanatçının diğer şarkılarına veya söz konusu podcast'in diğer bölümlerine gidebilir. Araba bu özelliği destekliyorsa kullanıcılar bağlantıya dokunarak bu içeriğe göz atabilir.
Bağlantı eklemek için KEY_SUBTITLE_LINK_MEDIA_ID
meta verilerini (altyazıdan bağlantı oluşturmak için) veya KEY_DESCRIPTION_LINK_MEDIA_ID
meta verilerini (açıklamadan bağlantı oluşturmak için) yapılandırın. Ayrıntılar için bu meta veri alanlarının referans belgelerine bakın.
Sesli işlemleri destekleme
Sürücülere güvenli ve rahat bir deneyim sunmak için medya uygulamanızın sesli işlemleri desteklemesi gerekir. Bu sayede sürücülerin dikkati dağılmaz. Örneğin, uygulamanız bir medya öğesi oynatırken kullanıcı, arabanın ekranına bakmadan veya dokunmadan farklı bir şarkı çalmasını istemek için"[Şarkı adını]çal" diyebilir. Kullanıcılar, direksiyonlarındaki uygun düğmeleri tıklayarak veya "Ok Google" etkinleştirme kelimelerini söyleyerek sorgu başlatabilir.
Android Auto veya Android Automotive OS bir sesli işlemi algılayıp yorumladığında bu sesli işlem, onPlayFromSearch()
üzerinden uygulamaya iletilir.
Bu geri çağırma alındığında uygulama, query
dizesiyle eşleşen içeriği bulur ve oynatmaya başlar.
Kullanıcılar sorgularında farklı terim kategorileri (ör. tür, sanatçı, albüm, şarkı adı, radyo istasyonu veya şarkı listesi) belirtebilir. Arama desteği oluştururken uygulamanız için anlamlı olan tüm kategorileri hesaba katın. Android Auto veya Android Automotive OS, belirli bir sorgunun belirli kategorilere uygun olduğunu algılarsa extras
parametresine ek bilgiler ekler. Aşağıdaki ekler gönderilebilir:
Kullanıcı arama terimlerini belirtmezse Android Auto veya Android Automotive OS tarafından gönderilebilen boş query
dizesini hesaba katın.
Örneğin, kullanıcı "Müzik çal" derse. Bu durumda uygulamanız, kısa süre önce çalınan veya yeni önerilen bir parçayı başlatmayı tercih edebilir.
Bir arama hızlıca işlenemiyorsa onPlayFromSearch()
içinde engellemeyin.
Bunun yerine, oynatma durumunu STATE_CONNECTING
olarak ayarlayın ve aramayı eşzamansız bir iş parçacığında gerçekleştirin.
Oynatma başladıktan sonra medya oturumunun sırasını ilgili içeriklerle doldurabilirsiniz. Örneğin, kullanıcı bir albümün çalınmasını isterse uygulamanız sırayı albümün parça listesiyle doldurabilir. Ayrıca, kullanıcının sorgusuyla eşleşen farklı bir parça seçebilmesi için göz atılabilir arama sonuçları desteğini uygulamayı da düşünebilirsiniz.
Android Auto ve Android Automotive OS, "oynat" sorgularının yanı sıra "müziği duraklat" ve "sonraki şarkı" gibi oynatmayı kontrol etmeye yönelik sesli sorguları da tanır ve bu komutları onPause()
ve onSkipToNext()
gibi uygun medya oturumu geri çağırmalarıyla eşleştirir.
Uygulamanızda sesli oynatma işlemlerini nasıl uygulayacağınızla ilgili ayrıntılı bir örnek için Google Asistan ve medya uygulamaları başlıklı makaleyi inceleyin.
Dikkat dağıtıcı unsurlara karşı koruma önlemleri uygulama
Android Auto kullanılırken kullanıcının telefonu aracının hoparlörlerine bağlı olduğundan sürücünün dikkatini dağıtmasını önlemek için ek önlemler almanız gerekir.
Araçtaki alarmları kapatma
Android Auto medya uygulamaları, kullanıcı oynatma düğmesine basarak oynatmayı başlatmadığı sürece arabanın hoparlörlerinden ses çalmaya başlamamalıdır. Medya uygulamanızdan kullanıcı tarafından planlanan bir alarm bile arabanın hoparlörlerinden müzik çalmaya başlamamalıdır.
Bu şartı karşılamak için uygulamanız, ses çalmadan önce sinyal olarak CarConnection
kullanabilir. Uygulamanız, araba bağlantı türü için LiveData
gözlemlenerek ve CONNECTION_TYPE_PROJECTION
değerine eşit olup olmadığı kontrol edilerek telefonun araba ekranına yansıtılıp yansıtılmadığını kontrol edebilir.
Kullanıcının telefonu projeksiyon yapıyorsa alarmları destekleyen medya uygulamaları aşağıdakilerden birini yapmalıdır:
- Alarmı devre dışı bırakın.
- Alarmı
STREAM_ALARM
üzerinden çalın ve alarmı devre dışı bırakmak için telefon ekranında bir kullanıcı arayüzü sağlayın.
Medya reklamlarını işleme
Android Auto, varsayılan olarak ses oynatma oturumu sırasında medya meta verileri değiştiğinde bildirim gösterir. Bir medya uygulaması müzik çalmaktan reklam yayınlamaya geçtiğinde kullanıcıya bildirim göstermek dikkat dağıtıcı olur. Android Auto'nun bu durumda bildirim göstermesini önlemek için medya meta verileri anahtarını METADATA_KEY_IS_ADVERTISEMENT
aşağıdaki kod snippet'inde gösterildiği gibi METADATA_VALUE_ATTRIBUTE_PRESENT
olarak ayarlamanız gerekir:
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ı işleme
Uygulamada bir hata oluştuğunda oynatma durumunu STATE_ERROR
olarak ayarlayın ve setErrorMessage()
yöntemini kullanarak bir hata mesajı sağlayın. Hata mesajını ayarlarken kullanabileceğiniz hata kodlarının listesi için PlaybackStateCompat
başlıklı makaleyi inceleyin.
Hata mesajları kullanıcıya yönelik olmalı ve kullanıcının mevcut yerel ayarına göre yerelleştirilmelidir. Android Auto ve Android Automotive OS, hata mesajını kullanıcıya gösterebilir.
Örneğin, içerik kullanıcının bulunduğu bölgede kullanılamıyorsa hata mesajını ayarlarken ERROR_CODE_NOT_AVAILABLE_IN_REGION
hata kodunu kullanabilirsiniz.
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 ve hatalar başlıklı makaleyi inceleyin.
Bir Android Auto kullanıcısının hatayı çözmek için telefon uygulamanızı açması gerekiyorsa mesajınızda bu bilgiyi kullanıcıya iletin. Örneğin, hata mesajınızda "Lütfen oturum açın" yerine "[Uygulama adınız] uygulamasında oturum açın" yazabilir.