Android for Cars Uygulama Kitaplığı navigasyon, önemli yer (ÖY) ve nesnelerin interneti (IOT) uygulamalarınızı arabanıza taşımanıza olanak tanır. Bunu, sürücünün dikkatini dağıtan standartlara uygun şekilde tasarlanmış bir dizi şablon sağlayarak ve araba ekranı faktörlerinin çeşitliliği, giriş yöntemleri gibi ayrıntıları göz önünde bulundurarak yapar.
Bu rehber, kitaplığın önemli özellik ve kavramlarına genel bir bakış sunarak temel bir uygulama oluşturma sürecinde size yol gösterir.
Başlamadan önce
- Araba Uygulama Kitaplığı'nı kapsayan Sürüş İçin Tasarım sayfalarını inceleyin
- Navigasyon uygulamaları ve Sürüşle ilgili diğer uygulamalar kategorisine genel bakış
- Şablonlarla uygulama derleme'ye genel bakış
- Şablonlar ve Şablon bileşenleri'ni kapsayan yapı taşları
- Yaygın kullanıcı deneyimi kalıplarını gösteren örnek akışlar
- Şablonlu uygulama şartları
- Aşağıdaki bölümde yer alan temel terimleri ve kavramları inceleyin.
- Android Auto Sistem Kullanıcı Arayüzü ve Android Automotive OS tasarımı hakkında bilgi edinin.
- Sürüm Notlarını inceleyin.
- Sana Özel'i inceleyin.
Anahtar terimler ve kavramlar
- Modeller ve Şablonlar
- Kullanıcı arayüzü, ait oldukları şablona göre farklı şekillerde birlikte düzenlenebilen model nesneleri grafiğiyle gösterilir. Şablonlar, bu grafiklerde kök görevi görebilecek modellerin alt kümesidir. Modeller, kullanıcıya metin ve resim biçiminde gösterilecek bilgilerin yanı sıra bu bilgilerin görsel görünümünün çeşitli yönlerini (ör. metin renkleri veya resim boyutları) yapılandıran özellikleri içerir. Sunucu, modelleri sürücünün dikkatini dağıtan standartlara uygun şekilde tasarlanmış görünümlere dönüştürüp araba ekranı faktörlerinin çeşitliliği ve giriş yöntemleri gibi ayrıntıları hallediyor.
- Düzenleyen
- Ana makine, uygulamanızın arabada çalışabilmesi için kitaplığın API'leri tarafından sunulan işlevleri uygulayan arka uç bileşenidir. Ana makinenin sorumlulukları, uygulamanızı keşfetmek ve yaşam döngüsünü yönetmekten modellerinizi görünümlere dönüştürmeye ve uygulamanızı kullanıcı etkileşimleri hakkında bilgilendirmeye kadar değişiklik gösterir. Mobil cihazlarda, bu ana makine Android Auto tarafından uygulanır. Android Automotive OS'te bu ana makine bir sistem uygulaması olarak yüklüdür.
- Şablon kısıtlamaları
- Farklı şablonlar, modellerinin içeriğine kısıtlama getirir. Örneğin, liste şablonlarında kullanıcıya sunulabilecek öğe sayısı sınırlıdır. Şablonların bir görevin akışını oluşturmak için bağlantı kurma biçimleri de kısıtlamalar vardır. Örneğin, uygulama ekran yığınına en fazla beş şablon aktarabilir. Daha fazla bilgi için Şablon kısıtlamaları bölümüne bakın.
Screen
Screen
, uygulamaların kullanıcıya sunulan kullanıcı arayüzünü yönetmek için uyguladığı kitaplık tarafından sağlanan bir sınıftır.Screen
öğesinin bir yaşam döngüsü vardır ve ekran göründüğünde uygulamanın görüntülemek üzere şablonu göndermesi için gereken mekanizmayı sağlar.Screen
örnekleri ayrıca birScreen
yığınına aktarılıp buradan çıkarılabilir. Böylece, şablon akış kısıtlamalarına uymaları sağlanır.CarAppService
CarAppService
, ana makine tarafından keşfedilip yönetilebilmesi için uygulamanızın uygulaması ve dışa aktarması gereken soyut birService
sınıfıdır. UygulamanızınCarAppService
bileşeni, bir ana makine bağlantısınıncreateHostValidator
ile güvenilir olduğunu doğrulamaktan ve ardındanonCreateSession
kullanarak her bağlantı içinSession
örnekleri sağlamaktan sorumludur.Session
Session
, uygulamanızınCarAppService.onCreateSession
kullanarak uygulaması ve döndürmesi gereken soyut bir sınıftır. Arabanın ekranında bilgi görüntülemek için giriş noktası işlevi görür. Uygulamanızın araba ekranındaki mevcut durumunu (ör. uygulamanızın görünür veya gizli olduğu) bildiren bir yaşam döngüsü vardır.Uygulama ilk başlatıldığında olduğu gibi, bir
Session
başlatıldığında ana makine,onCreateScreen
yöntemini kullanarak ilkScreen
öğesinin gösterilmesini ister.
Araba Uygulama Kitaplığı'nı yükleyin
Kitaplığı uygulamanıza nasıl ekleyeceğinizle ilgili talimatlar için Jetpack kitaplığının sürüm sayfasına bakın.
Uygulamanızın manifest dosyalarını yapılandırma
Araba uygulamanızı oluşturmadan önce uygulamanızın manifest dosyalarını aşağıdaki gibi yapılandırın.
CarAppService'inizi beyan edin
Ana makine, uygulamanıza CarAppService
uygulamanız üzerinden bağlanır. Ana makinenin uygulamanızı keşfetmesini ve bağlanmasını sağlamak için bu hizmeti manifest dosyanızda beyan edersiniz.
Ayrıca, uygulamanızın amaç filtresinin <category>
öğesinde uygulamanızın kategorisini beyan etmeniz gerekir. Bu öğede izin verilen değerler için desteklenen uygulama kategorileri listesine bakın.
Aşağıdaki kod snippet'i, manifest dosyanızda bir önemli yer uygulaması için araba uygulaması hizmetinin nasıl tanımlanacağını gösterir:
<application>
...
<service
...
android:name=".MyCarAppService"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService"/>
<category android:name="androidx.car.app.category.POI"/>
</intent-filter>
</service>
...
<application>
Desteklenen uygulama kategorileri
CarAppService
öğenizi önceki bölümde açıklandığı gibi tanımlarken amaç filtresine aşağıdaki kategori değerlerinden birini veya daha fazlasını ekleyerek uygulamanızın kategorisini tanımlayın:
androidx.car.app.category.NAVIGATION
: Adım adım navigasyon yol tarifleri sağlayan bir uygulama. Bu kategoriyle ilgili ek belgeler için Arabalar için navigasyon uygulamaları oluşturma bölümüne göz atın.androidx.car.app.category.POI
: Park yeri, şarj istasyonları ve benzin istasyonları gibi önemli yerleri bulmayla ilgili işlevler sunan bir uygulama. Bu kategoriyle ilgili ek belgeler için Arabalar için önemli yer uygulamaları oluşturma bölümüne göz atın.androidx.car.app.category.IOT
: Kullanıcıların araba içinden, bağlı cihazlarda alakalı işlemler gerçekleştirmesini sağlayan bir uygulamadır. Bu kategoriyle ilgili ek belgeler için Arabalar için nesnelerin internetini oluşturma bölümüne göz atın.
Her kategorinin ayrıntılı açıklamaları ve bu kategorilere ait uygulamalara ilişkin ölçütler için Arabalar için Android uygulama kalitesi bölümüne bakın.
Uygulama adını ve simgesini belirtin
Ana makinenin, uygulamanızı sistem kullanıcı arayüzünde temsil etmek için kullanabileceği bir uygulama adı ve simge belirtmeniz gerekir.
CarAppService
cihazınızın label
ve icon
özelliklerini kullanarak uygulamanızı temsil etmek için kullanılan uygulama adını ve simgesini belirtebilirsiniz:
...
<service
android:name=".MyCarAppService"
android:exported="true"
android:label="@string/my_app_name"
android:icon="@drawable/my_app_icon">
...
</service>
...
Etiket veya simge <service>
öğesinde tanımlanmazsa ana makine, <application>
öğesi için belirtilen değerlere geri döner.
Özel tema ayarlama
Araba uygulamanızda özel bir tema ayarlamak için manifest dosyanıza aşağıdaki şekilde bir <meta-data>
öğesi ekleyin:
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Ardından, özel araba uygulaması temanız için aşağıdaki özellikleri ayarlamak üzere stil kaynağınızı tanımlayın:
<resources> <style name="MyCarAppTheme"> <item name="carColorPrimary">@layout/my_primary_car_color</item> <item name="carColorPrimaryDark">@layout/my_primary_dark_car_color</item> <item name="carColorSecondary">@layout/my_secondary_car_color</item> <item name="carColorSecondaryDark">@layout/my_secondary_dark_car_color</item> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Araba Uygulaması API düzeyi
Araba Uygulama Kitaplığı, kendi API düzeylerini tanımlar. Böylece, bir araçtaki şablon ana makinesi tarafından hangi kitaplık özelliklerinin desteklendiğini öğrenebilirsiniz.
Bir ana makine tarafından desteklenen en yüksek Car App API API düzeyini almak için getCarAppApiLevel()
yöntemini kullanın.
AndroidManifest.xml
dosyanızda, uygulamanızın desteklediği minimum Car App API API düzeyini belirtin:
<manifest ...>
<application ...>
<meta-data
android:name="androidx.car.app.minCarApiLevel"
android:value="1"/>
</application>
</manifest>
Geriye dönük uyumluluğu sürdürme ve bir özelliği kullanmak için gereken minimum API düzeyini bildirme hakkında ayrıntılı bilgi için RequiresCarApi
ek açıklaması belgelerine bakın. Araba Uygulama Kitaplığı'nın belirli bir özelliğini kullanmak için hangi API düzeyinin gerekli olduğunu öğrenmek için CarAppApiLevels
referans dokümanlarına bakın.
CarAppService ve Oturumunuzu oluşturma
Uygulamanızın CarAppService
sınıfını genişletmesi ve ana makineyle olan mevcut bağlantıya karşılık gelen Session
örneğini döndüren onCreateSession
yöntemini uygulaması gerekir:
Kotlin
class HelloWorldService : CarAppService() { ... override fun onCreateSession(): Session { return HelloWorldSession() } ... }
Java
public final class HelloWorldService extends CarAppService { ... @Override @NonNull public Session onCreateSession() { return new HelloWorldSession(); } ... }
Session
örneği, uygulama ilk kez başlatıldığında kullanılması için Screen
örneğinin döndürülmesinden sorumludur:
Kotlin
class HelloWorldSession : Session() { ... override fun onCreateScreen(intent: Intent): Screen { return HelloWorldScreen(carContext) } ... }
Java
public final class HelloWorldSession extends Session { ... @Override @NonNull public Screen onCreateScreen(@NonNull Intent intent) { return new HelloWorldScreen(getCarContext()); } ... }
Araba uygulamanızın, uygulamanızın ana sayfası veya açılış ekranı olmayan bir ekrandan başlatılması gereken durumları (ör. derin bağlantıları işleme) yönetmek için onCreateScreen
'ten dönmeden önce ScreenManager.push
kullanarak arka plan grubunu önceden başlangıç noktası olarak belirleyebilirsiniz.
Önceden yükleme, kullanıcıların uygulamanızın gösterildiği ilk ekrandan önceki ekranlara geri gitmelerine olanak tanır.
Başlangıç ekranınızı oluşturun
Uygulamanızın gösterdiği ekranları Screen
sınıfını genişleten sınıflar tanımlayarak ve onGetTemplate
yöntemini uygulayarak oluşturursunuz. Bu yöntem, araba ekranında görüntülenecek kullanıcı arayüzünün durumunu temsil eden Template
örneğini döndürür.
Aşağıdaki snippet'te basit bir "Hello world!" dizesi göstermek için PaneTemplate
şablonu kullanan bir Screen
'nin nasıl bildirileceği gösterilmektedir:
Kotlin
class HelloWorldScreen(carContext: CarContext) : Screen(carContext) { override fun onGetTemplate(): Template { val row = Row.Builder().setTitle("Hello world!").build() val pane = Pane.Builder().addRow(row).build() return PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build() } }
Java
public class HelloWorldScreen extends Screen { @NonNull @Override public Template onGetTemplate() { Row row = new Row.Builder().setTitle("Hello world!").build(); Pane pane = new Pane.Builder().addRow(row).build(); return new PaneTemplate.Builder(pane) .setHeaderAction(Action.APP_ICON) .build(); } }
CarContext sınıfı
CarContext
sınıfı, Session
veScreen
örneklerinize erişilebilen bir ContextWrapper
alt sınıfıdır. Ekran yığınını yönetmek için ScreenManager
, gezinme uygulamanızın haritasını çizmek için Surface
nesnesine erişme gibi uygulamalarla ilgili genel işlevler için AppManager
ve gezinme etkinlikleri ve diğer meta verilerle ilgili iletişim kurmak için adım adım navigasyon uygulamaları tarafından kullanılan NavigationManager
kullanılan NavigationManager
araç hizmetlerine erişim sağlar.
Gezinme uygulamalarında kullanılabilen kitaplık işlevlerinin kapsamlı bir listesi için Gezinme şablonlarına erişim bölümüne bakın.
CarContext
, araba ekranındaki yapılandırmayı kullanarak çekilebilir kaynakları yüklemenize izin verme, amaçları kullanarak arabada bir uygulamayı başlatma ve navigasyon uygulamanızın haritasını koyu modda görüntüleyip görüntülemeyeceğini belirtme gibi başka işlevler de sunar.
Ekranda gezinme özelliğini uygulayın
Uygulamalar genellikle bir dizi farklı ekran sunar. Bu ekranların her biri, kullanıcının ekranda görüntülenen arayüzle etkileşim kurarken gezinebileceği farklı şablonlar kullanır.
ScreenManager
sınıfı, kullanıcı araba ekranında bir geri düğmesi seçtiğinde veya bazı arabalarda bulunan donanım geri düğmesini kullandığında otomatik olarak açılabilen ekranları itmek için kullanabileceğiniz bir ekran grubu sağlar.
Aşağıdaki snippet'te, hem bir mesaj şablonuna geri işleminin nasıl ekleneceği hem de kullanıcı tarafından seçildiğinde yeni bir ekran iten bir işlemin nasıl ekleneceği gösterilmektedir:
Kotlin
val template = MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( Action.Builder() .setTitle("Next screen") .setOnClickListener { screenManager.push(NextScreen(carContext)) } .build()) .build()
Java
MessageTemplate template = new MessageTemplate.Builder("Hello world!") .setHeaderAction(Action.BACK) .addAction( new Action.Builder() .setTitle("Next screen") .setOnClickListener( () -> getScreenManager().push(new NextScreen(getCarContext()))) .build()) .build();
Action.BACK
nesnesi, otomatik olarak ScreenManager.pop
çağrısı yapan standart bir Action
nesnesidir.
Bu davranış, CarContext
üzerinde bulunan OnBackPressedDispatcher
örneği kullanılarak geçersiz kılınabilir.
Uygulamanın sürüş sırasında güvenli bir şekilde kullanılmasını sağlamak için ekran yığını en fazla beş ekran derinliğine sahip olabilir. Daha fazla ayrıntı için Şablon kısıtlamaları bölümüne bakın.
Şablonun içeriğini yenileme
Uygulamanız, Screen.invalidate
yöntemini çağırarak Screen
içeriğinin geçersiz kılınmasını isteyebilir.
Ardından ana makine, yeni içerikle şablonu almak için uygulamanızın Screen.onGetTemplate
yöntemini geri çağırır.
Bir Screen
öğesini yenilerken ana makinenin yeni şablonu şablon kotasına dahil etmemesi için şablonda güncellenebilecek spesifik içeriği anlamak önemlidir.
Daha fazla bilgi için Şablon kısıtlamaları bölümüne bakın.
Ekranlarınızı, Screen
ile onGetTemplate
uygulaması aracılığıyla döndürdüğü şablon türü arasında bire bir eşleme olacak şekilde yapılandırmanızı öneririz.
Kullanıcıyla etkileşimde bulunun
Uygulamanız, mobil uygulamaya benzer kalıplar kullanarak kullanıcıyla etkileşim kurabilir.
Kullanıcı girişini işleyin
Uygulamanız, uygun işleyicileri onları destekleyen modellere ileterek kullanıcı girişlerine yanıt verebilir. Aşağıdaki snippet, uygulamanızın kodu tarafından tanımlanan bir yöntemi geri çağıran bir OnClickListener
öğesini ayarlayan bir Action
modelinin nasıl oluşturulduğunu gösterir:
Kotlin
val action = Action.Builder() .setTitle("Navigate") .setOnClickListener(::onClickNavigate) .build()
Java
Action action = new Action.Builder() .setTitle("Navigate") .setOnClickListener(this::onClickNavigate) .build();
onClickNavigate
yöntemi, daha sonra CarContext.startCarApp
yöntemini kullanarak varsayılan navigasyon arabası uygulamasını başlatabilir:
Kotlin
private fun onClickNavigate() { val intent = Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)) carContext.startCarApp(intent) }
Java
private void onClickNavigate() { Intent intent = new Intent(CarContext.ACTION_NAVIGATE, Uri.parse("geo:0,0?q=" + address)); getCarContext().startCarApp(intent); }
ACTION_NAVIGATE
amacının biçimi de dahil olmak üzere uygulamaların nasıl başlatılacağıyla ilgili daha fazla bilgi için Bir amacı kullanarak araba uygulaması başlatma bölümüne bakın.
Kullanıcıyı, mobil cihazlarında etkileşimde bulunmaya devam etmesi için yönlendirmeyi gerektiren işlemler gibi bazı işlemlere yalnızca araç park edildiğinde izin verilir.
Bu işlemleri uygulamak için ParkedOnlyOnClickListener
aracını kullanabilirsiniz. Araba park edilmemişse ana makine, kullanıcıya bu durumda söz konusu işleme izin verilmediğini belirtir. Araba park halindeyse kod normal şekilde çalışır. Aşağıdaki snippet, mobil cihazda ayarlar ekranını açmak için ParkedOnlyOnClickListener
öğesinin nasıl kullanılacağını gösterir:
Kotlin
val row = Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(::openSettingsOnPhone)) .build()
Java
Row row = new Row.Builder() .setTitle("Open Settings") .setOnClickListener(ParkedOnlyOnClickListener.create(this::openSettingsOnPhone)) .build();
Bildirimleri görüntüle
Mobil cihaza gönderilen bildirimler yalnızca bir CarAppExtender
ile genişletildiğinde araç ekranında görünür.
İçerik başlığı, metin, simge ve işlemler gibi bazı bildirim özellikleri CarAppExtender
üzerinden ayarlanabilir. Bu sayede, araba ekranında görünen bildirim özellikleri geçersiz kılınır.
Aşağıdaki snippet'te, mobil cihazda gösterilenden farklı bir başlık görüntüleyen araç ekranına nasıl bildirim gönderileceği gösterilmektedir:
Kotlin
val notification = NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build()
Java
Notification notification = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID) .setContentTitle(titleOnThePhone) .extend( new CarAppExtender.Builder() .setContentTitle(titleOnTheCar) ... .build()) .build();
Bildirimler, kullanıcı arayüzünün aşağıdaki bölümlerini etkileyebilir:
- Kullanıcıya uyarı bildirimi (HUN) gösterilebilir.
- Bildirim merkezinde, isteğe bağlı olarak reklam çubuğunda görünen bir rozetle birlikte bir giriş eklenebilir.
- Navigasyon uygulamaları için bildirim, Adım adım bildirimler bölümünde açıklandığı gibi demiryolu widget'ında görüntülenebilir.
CarAppExtender
belgelerinde açıklandığı gibi, bildirimin önceliğini kullanarak uygulamanızın bildirimlerini bu kullanıcı arayüzü öğelerinin her birini etkileyecek şekilde nasıl yapılandıracağınızı seçebilirsiniz.
NotificationCompat.Builder.setOnlyAlertOnce
, true
değeriyle çağrılırsa yüksek öncelikli bildirim yalnızca bir HUN olarak HUN olarak gösterilir.
Araba uygulamanızın bildirimlerini nasıl tasarlayacağınız hakkında daha fazla bilgi için Bildirimler hakkındaki Sürüş için Google Tasarımı kılavuzuna bakın.
Kısa ileti göster
Uygulamanız, bu snippet'te gösterildiği gibi CarToast
kullanarak bir durum mesajı görüntüleyebilir:
Kotlin
CarToast.makeText(carContext, "Hello!", CarToast.LENGTH_SHORT).show()
Java
CarToast.makeText(getCarContext(), "Hello!", CarToast.LENGTH_SHORT).show();
İzin iste
Uygulamanızın kısıtlanmış verilere veya işlemlere (ör. konum) erişmesi gerekiyorsa Android izinlerinin standart kuralları geçerlidir. İzin istemek için CarContext.requestPermissions()
yöntemini kullanabilirsiniz.
Standart Android API'lerini kullanmanın aksine CarContext.requestPermissions()
kullanmanın avantajı, izinler iletişim kutusunu oluşturmak için kendi Activity
'inizi başlatmanızın gerekmemesidir. Üstelik, platforma bağlı akışlar oluşturmak zorunda kalmadan hem Android Auto hem de Android Automotive işletim sisteminde aynı kodu kullanabilirsiniz.
Android Auto'da izinler iletişim kutusunun stilini ayarlama
Android Auto'da telefonda kullanıcıya ilişkin izinler iletişim kutusu görünür.
Varsayılan olarak iletişim kutusunun arkasında arka plan olmaz. Özel bir arka plan ayarlamak için AndroidManifest.xml
dosyanızda bir araba uygulaması teması tanımlayın ve araba uygulamanızın teması için carPermissionActivityLayout
özelliğini ayarlayın.
<meta-data android:name="androidx.car.app.theme" android:resource="@style/MyCarAppTheme />
Ardından, araba uygulamanızın teması için carPermissionActivityLayout
özelliğini ayarlayın:
<resources> <style name="MyCarAppTheme"> <item name="carPermissionActivityLayout">@layout/my_custom_background</item> </style> </resources>
Belirli bir amaçla araba uygulaması başlatma
Aşağıdaki işlemlerden birini gerçekleştirmek için CarContext.startCarApp
yöntemini çağırabilirsiniz:
- Telefon etmek için numara çeviriciyi açın.
- Varsayılan navigasyon araba uygulaması ile bir konum için adım adım navigasyonu başlatın.
- Bir amaçla kendi uygulamanızı başlatın.
Aşağıdaki örnekte, uygulamanızı bir otopark rezervasyonunun ayrıntılarını gösteren bir ekranla açan bir işlemle nasıl bildirim oluşturulacağı gösterilmektedir.
Bildirim örneğini, uygulamanızın işlemine açık bir niyetle sarmalayan PendingIntent
içeren bir content intent ile genişletirsiniz:
Kotlin
val notification = notificationBuilder ... .extend( CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(ComponentName(context, MyNotificationReceiver::class.java)), 0)) .build())
Java
Notification notification = notificationBuilder ... .extend( new CarAppExtender.Builder() .setContentIntent( PendingIntent.getBroadcast( context, ACTION_VIEW_PARKING_RESERVATION.hashCode(), new Intent(ACTION_VIEW_PARKING_RESERVATION) .setComponent(new ComponentName(context, MyNotificationReceiver.class)), 0)) .build());
Ayrıca uygulamanız, kullanıcı bildirim arayüzünde işlemi seçtiğinde ve veri URI'sını içeren bir niyetle CarContext.startCarApp
'ı çağırdığında amacı işlemek için çağrılan bir BroadcastReceiver
da beyan etmelidir:
Kotlin
class MyNotificationReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val intentAction = intent.action if (ACTION_VIEW_PARKING_RESERVATION == intentAction) { CarContext.startCarApp( intent, Intent(Intent.ACTION_VIEW) .setComponent(ComponentName(context, MyCarAppService::class.java)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))) } } }
Java
public class MyNotificationReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { String intentAction = intent.getAction(); if (ACTION_VIEW_PARKING_RESERVATION.equals(intentAction)) { CarContext.startCarApp( intent, new Intent(Intent.ACTION_VIEW) .setComponent(new ComponentName(context, MyCarAppService.class)) .setData(Uri.fromParts(MY_URI_SCHEME, MY_URI_HOST, intentAction))); } } }
Son olarak, uygulamanızdaki Session.onNewIntent
yöntemi bu amacı, zaten üstte değilse park rezervasyonu ekranını yığının üzerine iterek gerçekleştirir:
Kotlin
override fun onNewIntent(intent: Intent) { val screenManager = carContext.getCarService(ScreenManager::class.java) val uri = intent.data if (uri != null && MY_URI_SCHEME == uri.scheme && MY_URI_HOST == uri.schemeSpecificPart && ACTION_VIEW_PARKING_RESERVATION == uri.fragment ) { val top = screenManager.top if (top !is ParkingReservationScreen) { screenManager.push(ParkingReservationScreen(carContext)) } } }
Java
@Override public void onNewIntent(@NonNull Intent intent) { ScreenManager screenManager = getCarContext().getCarService(ScreenManager.class); Uri uri = intent.getData(); if (uri != null && MY_URI_SCHEME.equals(uri.getScheme()) && MY_URI_HOST.equals(uri.getSchemeSpecificPart()) && ACTION_VIEW_PARKING_RESERVATION.equals(uri.getFragment()) ) { Screen top = screenManager.getTop(); if (!(top instanceof ParkingReservationScreen)) { screenManager.push(new ParkingReservationScreen(getCarContext())); } } }
Araba uygulamasıyla ilgili bildirimlerin nasıl ele alınacağı hakkında daha fazla bilgi için Bildirimleri görüntüleme bölümüne bakın.
Şablon kısıtlamaları
Ana makine, belirli bir görev için görüntülenecek şablon sayısını en fazla beşle sınırlandırır. Son şablon, aşağıdaki türlerden biri olmalıdır:
Bu sınırın, yığındaki Screen
örnek sayısı için değil, şablon sayısı için geçerli olduğunu unutmayın. Örneğin, bir uygulama A ekranında iki şablon gönderir ve ardından B ekranını aktarırsa artık üç şablon daha gönderebilir. Alternatif olarak, her ekran tek bir şablon gönderecek şekilde yapılandırılmışsa uygulama, ScreenManager
yığınına beş ekran örneği aktarabilir.
Bu kısıtlamalarla ilgili özel durumlar vardır: şablon yenilemeleri ile geri ve sıfırlama işlemleri.
Şablon yenileniyor
Belirli içerik güncellemeleri şablon sınırına dahil edilmez. Genel olarak, bir uygulama aynı türde ve önceki şablonla aynı ana içeriğe sahip yeni bir şablon aktarırsa yeni şablon kotaya dahil edilmez. Örneğin, ListTemplate
içindeki bir satırın açma/kapatma durumunun güncellenmesi kotaya dahil edilmez. Ne tür içerik güncellemelerinin yenileme sayılabileceği hakkında daha fazla bilgi edinmek için bağımsız şablonların belgelerine bakın.
Geri işlemleri
Ana makine, bir görev içindeki alt akışları etkinleştirmek için bir uygulamanın ScreenManager
yığınından Screen
çıkardığını algılar ve uygulamanın geri gittiği şablon sayısına göre kalan kotayı günceller.
Örneğin, uygulama A ekranında iki şablon gönderir, ardından B ekranını aktarır ve iki şablon daha gönderirse uygulamanın bir kotası kalır. Uygulama daha sonra A ekranında tekrar açılırsa ana makine, uygulama iki şablon geriye gittiği için kotayı üçe sıfırlar.
Uygulamanın bir ekrana geri dönerken söz konusu ekran tarafından en son gönderilenle aynı türde bir şablon göndermesi gerektiğini unutmayın. Diğer şablon türlerini göndermek hataya neden olur. Bununla birlikte, geri işlem sırasında tür aynı kaldığı sürece, uygulama kotayı etkilemeden şablonun içeriğini serbestçe değiştirebilir.
İşlemleri sıfırla
Bazı şablonların, bir görevin sonunu belirten özel anlamları vardır. Örneğin, NavigationTemplate
, kullanıcının tüketimine yönelik yeni adım adım talimatlarla ekranda kalması ve yenilenmesi beklenen bir görünümdür. Bu şablonlardan birine ulaştığında, ana makine şablon kotasını sıfırlar ve şablonu yeni bir görevin ilk adımıymış gibi değerlendirir. Bu, uygulamanın yeni bir görev başlatmasına olanak tanır.
Hangi şablonların ana makinede sıfırlamayı tetiklediğini görmek için şablonların belgelerine tek tek bakın.
Ana makine, uygulamayı bir bildirim işleminden veya başlatıcıdan başlatma isteği alırsa kota da sıfırlanır. Bu mekanizma, uygulamanın bildirimlerden yeni bir görev akışı başlatmasını sağlar ve uygulama zaten bağlı ve ön planda olsa bile geçerlidir.
Uygulamanızın bildirimlerinin araba ekranında nasıl görüntüleneceğiyle ilgili daha fazla ayrıntı için Bildirimleri görüntüleme bölümüne bakın. Uygulamanızı bir bildirim işleminden nasıl başlatacağınızla ilgili bilgi için Amaçla araba uygulaması başlatma bölümüne bakın.
Bağlantı API'sı
Uygulamanızın, çalışma zamanında bağlantı bilgilerini almak için CarConnection
API'sini kullanarak Android Auto'da mı yoksa Android Automotive OS'ta mı çalıştığını belirleyebilirsiniz.
Örneğin, araba uygulamanızın Session
uygulamasında bir CarConnection
başlatın ve LiveData
güncellemelerine abone olun:
Kotlin
CarConnection(carContext).type.observe(this, ::onConnectionStateUpdated)
Java
new CarConnection(getCarContext()).getType().observe(this, this::onConnectionStateUpdated);
Gözlemcide ise bağlantı durumundaki değişikliklere tepki verebilirsiniz:
Kotlin
fun onConnectionStateUpdated(connectionState: Int) { val message = when(connectionState) { CarConnection.CONNECTION_TYPE_NOT_CONNECTED -> "Not connected to a head unit" CarConnection.CONNECTION_TYPE_NATIVE -> "Connected to Android Automotive OS" CarConnection.CONNECTION_TYPE_PROJECTION -> "Connected to Android Auto" else -> "Unknown car connection type" } CarToast.makeText(carContext, message, CarToast.LENGTH_SHORT).show() }
Java
private void onConnectionStateUpdated(int connectionState) { String message; switch(connectionState) { case CarConnection.CONNECTION_TYPE_NOT_CONNECTED: message = "Not connected to a head unit"; break; case CarConnection.CONNECTION_TYPE_NATIVE: message = "Connected to Android Automotive OS"; break; case CarConnection.CONNECTION_TYPE_PROJECTION: message = "Connected to Android Auto"; break; default: message = "Unknown car connection type"; break; } CarToast.makeText(getCarContext(), message, CarToast.LENGTH_SHORT).show(); }
Kısıtlamalar API'sı
Farklı arabalar, kullanıcıya aynı anda farklı sayıda Item
örneğinin gösterilmesine izin verebilir. Çalışma zamanında içerik sınırını kontrol etmek ve şablonlarınızda uygun öğe sayısını ayarlamak için ConstraintManager
aracını kullanın.
CarContext
üzerinden bir ConstraintManager
alarak başlayın:
Kotlin
val manager = carContext.getCarService(ConstraintManager::class.java)
Java
ConstraintManager manager = getCarContext().getCarService(ConstraintManager.class);
Daha sonra, alınan ConstraintManager
nesnesini ilgili içerik sınırı için sorgulayabilirsiniz. Örneğin, bir ızgarada gösterilebilecek öğelerin sayısını öğrenmek için CONTENT_LIMIT_TYPE_GRID
ile getContentLimit
çağrısı yapın:
Kotlin
val gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID)
Java
int gridItemLimit = manager.getContentLimit(ConstraintManager.CONTENT_LIMIT_TYPE_GRID);
Oturum açma akışı ekleme
Uygulamanız kullanıcılara oturum açma deneyimi sunuyorsa arabanın ana biriminden uygulamanızda oturum açma işlemini gerçekleştirmek için Car App API düzey 2 ve üstü ile SignInTemplate
ve LongMessageTemplate
gibi şablonları kullanabilirsiniz.
SignInTemplate
oluşturmak için SignInMethod
tanımlayın. Araba Uygulama Kitaplığı şu anda aşağıdaki oturum açma yöntemlerini desteklemektedir:
InputSignInMethod
(kullanıcı adı/şifre ile oturum açma için).PinSignInMethod
.- Google ile Oturum Açma ve One Tap gibi sağlayıcı oturum açmaları için
ProviderSignInMethod
. QRCodeSignInMethod
(kullanıcının telefonunda oturum açma işlemini tamamlamak üzere bir QR kodu taradığı QR kodu ile oturum açma işlemi için). Bu özellik, Araba API'sı Seviye 4 ve sonraki sürümlerde kullanılabilir.
Örneğin, kullanıcının şifresini toplayan bir şablon uygulamak için kullanıcı girişini işlemek ve doğrulamak amacıyla bir InputCallback
oluşturarak başlayın:
Kotlin
val callback = object : InputCallback { override fun onInputSubmitted(text: String) { // You will receive this callback when the user presses Enter on the keyboard. } override fun onInputTextChanged(text: String) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } }
Java
InputCallback callback = new InputCallback() { @Override public void onInputSubmitted(@NonNull String text) { // You will receive this callback when the user presses Enter on the keyboard. } @Override public void onInputTextChanged(@NonNull String text) { // You will receive this callback as the user is typing. The update // frequency is determined by the host. } };
InputSignInMethod
Builder
için InputCallback
gereklidir.
Kotlin
val passwordInput = InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build()
Java
InputSignInMethod passwordInput = new InputSignInMethod.Builder(callback) .setHint("Password") .setInputType(InputSignInMethod.INPUT_TYPE_PASSWORD) ... .build();
Son olarak, yeni InputSignInMethod
kullanarak bir SignInTemplate
oluşturun.
Kotlin
SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build()
Java
new SignInTemplate.Builder(passwordInput) .setTitle("Sign in with username and password") .setInstructions("Enter your password") .setHeaderAction(Action.BACK) ... .build();
Hesap Yöneticisi'ni kullanma
Kimlik doğrulaması olan Android Automotive OS uygulamaları, aşağıdaki nedenlerden dolayı AccountManager'ı kullanmalıdır:
- Daha iyi kullanıcı deneyimi ve hesap yönetimi kolaylığı: Kullanıcılar, tüm hesaplarını sistem ayarlarındaki hesaplar menüsünden (oturum açma ve kapatma dahil) kolayca yönetebilir.
- "Misafir" deneyimleri: Arabalar ortak cihazlar olduğundan OEM'ler, araçta hesapların eklenemeyeceği şekilde konuk deneyimlerini etkinleştirebilir.
Metin dizesi varyantları ekleme
Farklı araba ekran boyutlarında farklı miktarda metin gösterilebilir. Car App API'nin 2. seviye ve sonraki sürümlerinde, ekrana en uygun şekilde bir metin dizesinin birden fazla varyantını belirtebilirsiniz. Metin varyantlarının kabul edildiği yerleri görmek için CarText
gerektiren şablonları ve bileşenleri arayın.
CarText.Builder.addVariant()
yöntemini kullanarak CarText
öğesine metin dizesi varyantları ekleyebilirsiniz:
Kotlin
val itemTitle = CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build()
Java
CarText itemTitle = new CarText.Builder("This is a very long string") .addVariant("Shorter string") ... .build();
Daha sonra bu CarText
öğesini kullanabilirsiniz. Örneğin, bir GridItem
öğesinin birincil metni olarak.
Kotlin
GridItem.Builder() .addTitle(itemTitle) ... .build()
Java
new GridItem.Builder() .addTitle(itemTitle) ... build();
Dizeleri, en çok tercih edilenden en az tercih edilene (ör. en uzundan en kısaya) doğru sıralayın. Ana makine, araba ekranında kullanılabilen boşluğa bağlı olarak uygun uzunluktaki dizeyi seçer.
Satırlar için satır içi CarIcon'lar ekleme
CarIconSpan
kullanarak uygulamanızın görsel cazibesini zenginleştirmek için metinle birlikte satır içi simgeler ekleyebilirsiniz.
Bu aralıkları oluşturma hakkında daha fazla bilgi için CarIconSpan.create
belgelerine bakın. Aralıklarla metin stilinin nasıl çalıştığına dair genel bir bakış için Aralıklarla açıklayıcı metin biçimlendirme konusuna bakın.
Kotlin
val rating = SpannableString("Rating: 4.5 stars") rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ) val row = Row.Builder() ... .addText(rating) .build()
Java
SpannableString rating = new SpannableString("Rating: 4.5 stars"); rating.setSpan( CarIconSpan.create( // Create a CarIcon with an image of four and a half stars new CarIcon.Builder(...).build(), // Align the CarIcon to the baseline of the text CarIconSpan.ALIGN_BASELINE ), // The start index of the span (index of the character '4') 8, // The end index of the span (index of the last 's' in "stars") 16, Spanned.SPAN_INCLUSIVE_INCLUSIVE ); Row row = new Row.Builder() ... .addText(rating) .build();
Araba Donanımı API'leri
Araba Uygulaması API 3. seviyeden başlayarak, Araç Uygulama Kitaplığı'nda araç özelliklerine ve sensörlerine erişmek için kullanabileceğiniz API'ler bulunur.
Gereksinimler
API'leri Android Auto ile kullanmak için Android Auto modülünüzün build.gradle
dosyasına androidx.car.app:app-projected
öğesine bir bağımlılık ekleyerek başlayın. Android Automotive OS için, Android Automotive OS modülünüzün build.gradle
dosyasına androidx.car.app:app-automotive
öğesine bir bağımlılık ekleyin.
Ayrıca, AndroidManifest.xml
dosyanızda, kullanmak istediğiniz araba verilerini istemek için gereken ilgili izinleri belirtmeniz gerekir. Bu izinlerin size kullanıcı tarafından verilmesi de gerektiğini unutmayın. Platforma bağlı akışlar oluşturmak yerine hem Android Auto hem de Android Automotive OS'te aynı kodu kullanabilirsiniz. Ancak gerekli izinler farklıdır.
Araç Bilgisi
Bu tabloda, CarInfo
API'lerinde bulunan özellikler ve bunları kullanmak için istemeniz gereken izinler açıklanmaktadır:
Yöntemler | Kod | Android Auto İzinleri | Android Automotive OS İzinleri |
---|---|---|---|
fetchModel |
Marka, model, yıl | android.car.permission.CAR_INFO |
|
fetchEnergyProfile |
EV konnektörü türleri, yakıt türleri | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_INFO |
addTollListener
removeTollListener |
Ücret kartı durumu, paralı kart türü | ||
addEnergyLevelListener
removeEnergyLevelListener |
Pil seviyesi, yakıt seviyesi, düşük yakıt seviyesi, kalan menzil | com.google.android.gms.permission.CAR_FUEL |
android.car.permission.CAR_ENERGY ,android.car.permission.CAR_ENERGY_PORTS ,android.car.permission.READ_CAR_DISPLAY_UNITS |
addSpeedListener
removeSpeedListener |
Ham hız, görüntüleme hızı (arabanın küme ekranında gösterilir) | com.google.android.gms.permission.CAR_SPEED |
android.car.permission.CAR_SPEED ,android.car.permission.READ_CAR_DISPLAY_UNITS |
addMileageListener
removeMileageListener |
Kilometre sayacı mesafesi | com.google.android.gms.permission.CAR_MILEAGE |
Bu veriler, Android Automotive OS'te Play Store'dan yüklenen uygulamalar tarafından kullanılamaz. |
Örneğin, kalan aralığı almak için bir CarInfo
nesnesi örnek oluşturun, ardından bir OnCarDataAvailableListener
oluşturun ve kaydedin:
Kotlin
val carInfo = carContext.getCarService(CarHardwareManager::class.java).carInfo val listener = OnCarDataAvailableListener<EnergyLevel> { data -> if (data.rangeRemainingMeters.status == CarValue.STATUS_SUCCESS) { val rangeRemaining = data.rangeRemainingMeters.value } else { // Handle error } } carInfo.addEnergyLevelListener(carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener)
Java
CarInfo carInfo = getCarContext().getCarService(CarHardwareManager.class).getCarInfo(); OnCarDataAvailableListener<EnergyLevel> listener = (data) -> { if(data.getRangeRemainingMeters().getStatus() == CarValue.STATUS_SUCCESS) { float rangeRemaining = data.getRangeRemainingMeters().getValue(); } else { // Handle error } }; carInfo.addEnergyLevelListener(getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carInfo.removeEnergyLevelListener(listener);
Arabadaki verilerin her zaman mevcut olduğunu varsaymayın.
Hata alırsanız istediğiniz verilerin neden alınamadığını daha iyi anlamak için istediğiniz değerin durumunu kontrol edin. CarInfo
sınıf tanımının tamamı için referans belgelerini inceleyin.
Araba Sensörleri
CarSensors
sınıfı aracın ivme ölçer, jiroskop, pusula ve konum verilerine erişmenizi sağlar. Bu değerlerin kullanılabilirliği OEM'ye bağlı olabilir. İvme ölçer, jiroskop ve pusuladan alınan verilerin biçimi, SensorManager
API'den alacağınız biçimle aynıdır. Örneğin,
aracın yönünü kontrol etmek için:
Kotlin
val carSensors = carContext.getCarService(CarHardwareManager::class.java).carSensors val listener = OnCarDataAvailableListener<Compass> { data -> if (data.orientations.status == CarValue.STATUS_SUCCESS) { val orientation = data.orientations.value } else { // Data not available, handle error } } carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, carContext.mainExecutor, listener) … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener)
Java
CarSensors carSensors = getCarContext().getCarService(CarHardwareManager.class).getCarSensors(); OnCarDataAvailableListener<Compass> listener = (data) -> { if (data.getOrientations().getStatus() == CarValue.STATUS_SUCCESS) { List<Float> orientations = data.getOrientations().getValue(); } else { // Data not available, handle error } }; carSensors.addCompassListener(CarSensors.UPDATE_RATE_NORMAL, getCarContext().getMainExecutor(), listener); … // Unregister the listener when you no longer need updates carSensors.removeCompassListener(listener);
Araçtan konum verilerine erişmek için android.permission.ACCESS_FINE_LOCATION
iznini beyan etmeniz ve istemeniz de gerekir.
Test etme
Android Auto'da test ederken sensör verilerini simüle etmek için Masaüstü Ana Birimi kılavuzunun Sensörler ve Sensör yapılandırması bölümlerine bakın. Android Automotive OS'te test ederken sensör verilerini simüle etmek için Android Automotive OS emülatör kılavuzunun Donanım durumunu simüle et bölümüne bakın.
CarAppService, Session ve Screen yaşam döngüleri
Session
ve Screen
sınıfları LifecycleOwner
arayüzünü uygular. Kullanıcı uygulamayla etkileşimde bulunurken Session
ve Screen
nesnelerinizin yaşam döngüsü geri çağırmaları aşağıdaki şemalarda açıklandığı gibi çağrılır.
CarAppService ve Oturumların yaşam döngüleri
Tüm ayrıntılar için Session.getLifecycle
yöntemi belgelerine bakın.
Bir ekranın yaşam döngüsü
Tüm ayrıntılar için Screen.getLifecycle
yöntemiyle ilgili dokümanlara bakın.
Araç mikrofonundan kaydedin
Uygulamanızın CarAppService
ve CarAudioRecord
API'sini kullanarak uygulamanızın kullanıcının araç mikrofonuna erişmesine izin verebilirsiniz. Kullanıcıların, uygulamanızın
araç mikrofonuna erişmesine izin vermesi gerekir. Uygulamanız, kullanıcının uygulamanızdaki
girişlerini kaydedip işleyebilir.
Kayıt izni
Herhangi bir sesi kaydetmeden önce AndroidManifest.xml
cihazınıza kayıt yapma izni vermeniz ve kullanıcıdan bu izni istemesi gerekir.
<manifest ...>
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
...
</manifest>
Çalışma zamanında kayıt için izin istemeniz gerekir. Araba uygulamanızda nasıl izin isteğinde bulunacağınızla ilgili ayrıntılar için İzin isteme bölümüne bakın.
Ses kaydetme
Kullanıcı kayıt için izin verdikten sonra sesi kaydedebilir ve işleyebilirsiniz.
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) carAudioRecord.startRecording() val data = ByteArray(CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) while(carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording()
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); carAudioRecord.startRecording(); byte[] data = new byte[CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE]; while (carAudioRecord.read(data, 0, CarAudioRecord.AUDIO_CONTENT_BUFFER_SIZE) >= 0) { // Use data array // Potentially call carAudioRecord.stopRecording() if your processing finds end of speech } carAudioRecord.stopRecording();
Ses odağı
Araç mikrofonundan kayıt yaparken devam eden medyaların durdurulduğundan emin olmak için önce ses odağını edinin. Ses odağınız kaybolursa kaydetmeyi bırakın.
Aşağıda, ses odağının nasıl elde edileceğine ilişkin bir örnek verilmiştir:
Kotlin
val carAudioRecord = CarAudioRecord.create(carContext) // Take audio focus so that user's media is not recorded val audioAttributes = AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build() val audioFocusRequest = AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener { state: Int -> if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording() } } .build() if (carContext.getSystemService(AudioManager::class.java) .requestAudioFocus(audioFocusRequest) != AudioManager.AUDIOFOCUS_REQUEST_GRANTED ) { // Don't record if the focus isn't granted return } carAudioRecord.startRecording() // Process the audio and abandon the AudioFocusRequest when done
Java
CarAudioRecord carAudioRecord = CarAudioRecord.create(getCarContext()); // Take audio focus so that user's media is not recorded AudioAttributes audioAttributes = new AudioAttributes.Builder() .setContentType(AudioAttributes.CONTENT_TYPE_SPEECH) // Use the most appropriate usage type for your use case .setUsage(AudioAttributes.USAGE_ASSISTANCE_NAVIGATION_GUIDANCE) .build(); AudioFocusRequest audioFocusRequest = new AudioFocusRequest.Builder(AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) .setAudioAttributes(audioAttributes) .setOnAudioFocusChangeListener(state -> { if (state == AudioManager.AUDIOFOCUS_LOSS) { // Stop recording if audio focus is lost carAudioRecord.stopRecording(); } }) .build(); if (getCarContext().getSystemService(AudioManager.class).requestAudioFocus(audioFocusRequest) != AUDIOFOCUS_REQUEST_GRANTED) { // Don't record if the focus isn't granted return; } carAudioRecord.startRecording(); // Process the audio and abandon the AudioFocusRequest when done
Test Kitaplığı
Android for Cars Test Kitaplığı, uygulamanızın bir test ortamındaki davranışını doğrulamak için kullanabileceğiniz yardımcı sınıflar sağlar.
Örneğin SessionController
, ana makine bağlantısını simüle etmenize ve doğru Screen
ile Template
öğelerinin oluşturulup döndürüldüğünü doğrulamanıza olanak tanır.
Kullanım örnekleri için Örnekler'e bakın.
Android for Cars Uygulama Kitaplığı sorununu bildirme
Kitaplıkla ilgili bir sorun bulursanız Google Sorun İzleyici'yi kullanarak bildirin. Sorun şablonunda istenen tüm bilgileri doldurduğunuzdan emin olun.
Yeni bir sorun bildirmeden önce lütfen kitaplığın sürüm notlarında listelenip listelenmediğini veya sorunlar listesinde bildirilip bildirilmediğini kontrol edin. İzleyicideki bir sorunla ilgili yıldızı tıklayarak sorunlara abone olabilir ve oy verebilirsiniz. Daha fazla bilgi için Bir soruna abone olma bölümüne bakın.