Arabalar için Android Uygulama Kitaplığı'nı kullanma

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 kılavuz, kütüphanenin önemli özellikleri ve kavramlarına genel bir bakış sunmakla birlikte basit bir uygulama oluşturma sürecinde size yol gösterir. Eksiksiz bir adım adım tanıtım için Araba Uygulama Kitaplığı'yla ilgili temel bilgileri öğreten codelab'e göz atın.

Başlamadan önce

  1. Araba Uygulama Kitaplığı'nı kapsayan Sürüş İçin Tasarım sayfalarını inceleyin
  2. Aşağıdaki bölümde yer alan temel terimleri ve kavramları inceleyin.
  3. Android Auto Sistem Kullanıcı Arayüzü ve Android Automotive OS tasarımı hakkında bilgi edinin.
  4. Sürüm Notlarını inceleyin.
  5. 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 bir Screen 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 bir Service sınıfıdır. Uygulamanızın CarAppService bileşeni, bir ana makine bağlantısının createHostValidator ile güvenilir olduğunu doğrulamaktan ve ardından onCreateSession kullanarak her bağlantı için Session örnekleri sağlamaktan sorumludur.
Session

Session, uygulamanızın CarAppService.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 ilk Screen öğ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:

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:

Ö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.

Şartlar

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

Şekil 1. Session yaşam döngüsü.

Tüm ayrıntılar için Session.getLifecycle yöntemi belgelerine bakın.

Bir ekranın yaşam döngüsü

Şekil 2. Screen 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 sayı oluşturma

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.