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

Arabalar için Android Uygulama Kitaplığı; navigasyon, önemli yer (ÖY) ve nesnelerin interneti (IOT) uygulamalarını arabaya getirmenizi sağlar. Bunu, sürücünün dikkatini dağıtan unsurlar konusundaki standartları karşılamak için tasarlanmış bir dizi şablon sağlayarak ve çeşitli araç ekranı faktörleri ve giriş modları gibi ayrıntıları dikkate alarak yapar.

Bu kılavuz, kitaplığın temel özelliklerine ve kavramlarına genel bir bakış sunmanın yanı sıra temel bir uygulama oluşturma sürecinde size yol gösterir.

Başlamadan önce

  1. Araba Uygulaması Kitaplığı'nı kapsayan Sürüş İçin Tasarım sayfalarını inceleyin.
  2. Aşağıdaki bölümde bulunan önemli terimler 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ı şablonun izin verdiği ölçüde farklı şekillerde bir araya getirilebilecek model nesnelerinin grafiğiyle gösterilir. Şablonlar, bu grafiklerde kök oluşturabilecek modellerin bir alt kümesidir. Modeller, kullanıcıya metin ve resim biçiminde gösterilecek bilgileri ve bu tür bilgilerin görsel görünümünün (ör. metin renkleri veya resim boyutları) ayarlarını yapılandıran özellikleri içerir. Ana makine, modelleri sürücünün dikkatini dağıtan unsurlar standartlarını karşılayacak şekilde tasarlanmış görünümlere dönüştürür ve çeşitli araç ekranı faktörleri ve giriş modları gibi ayrıntılarla ilgilenir.
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ıza kullanıcı etkileşimleri hakkında bilgi vermeye kadar çeşitlilik gösterir. Mobil cihazlarda, bu ana makine Android Auto tarafından uygulanır. Bu ana makine, Android Automotive OS'te sistem uygulaması olarak yüklenir.
Şablon kısıtlamaları
Farklı şablonlar modellerinin içeriğine dair kısıtlamalar uygular. Örneğin, liste şablonlarında kullanıcıya gösterilebilecek öğe sayısı sınırlıdır. Şablonlar, bir görevin akışını oluşturmak için bağlantı kurma olanaklarına da sahiptir. Örneğin, uygulama ekran yığınına en fazla beş şablon aktarabilir. Diğer ayrıntılar 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, bir yaşam döngüsüne sahiptir ve uygulamanın, ekran görünür olduğunda şablonu görüntülemek üzere gönderme mekanizmasını sağlar. Screen örnekleri, bir Screen yığınına aktarılarak veya bu yığından pop-up olarak çalıştırılabilir. Böylece, şablon akış kısıtlamalarına uymaları sağlanır.
CarAppService
CarAppService, ana makine tarafından keşfedilmesi ve 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 görevi, bir ana makine bağlantısının createHostValidator kullanılarak güvenilir olduğunu doğrulamaktan ve ardından her bağlantı için onCreateSession kullanarak Session örnekleri sağlamaktan sorumludur.
Session

Session, uygulamanızın CarAppService.onCreateSession kullanarak uygulayıp döndürmesi gereken soyut bir sınıftır. Bu, araç ekranında bilgi görüntülemek için giriş noktası görevi görür. Uygulamanızın araç ekranındaki mevcut durumunu (uygulamanızın ne zaman görünür veya gizli olduğu gibi) bildiren bir yaşam döngüsüne sahiptir.

Session başlatıldığında (ör. uygulamanın ilk kullanıma sunulduğunda), ana makine, onCreateScreen yöntemini kullanarak ilk Screen için görüntülenme isteğinde bulunur.

Araba uygulaması kitaplığını yükleme

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 tanımlama

Barındırıcı, CarAppService uygulamanız aracılığıyla uygulamanıza bağlanır. Ana makinenin uygulamanızı keşfedip bağlanmasına izin vermek 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ızdaki bir önemli yer uygulaması için araba uygulaması hizmetini nasıl beyan edeceğinizi 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ığı şekilde tanımlarken intent 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 dokümanlar için Arabalar için navigasyon uygulamaları oluşturma sayfasına göz atın.
  • androidx.car.app.category.POI: Otoparklar, şarj istasyonları ve benzin istasyonları gibi önemli yerleri bulmayla ilgili işlevler sağlayan 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, arabada bağlı cihazlarda alakalı işlemler gerçekleştirmesini sağlayan bir uygulama. Bu kategoriyle ilgili ek belgeler için Arabalar için nesne uygulamaları oluşturma sayfasına göz atın.

Her kategorinin ayrıntılı açıklaması ve uygulamaların bunlara ait olmasına ilişkin ölçütler için Arabalar için Android uygulama kalitesi bölümüne bakın.

Uygulama adını ve simgesini belirtme

Ana makinenin, sistem kullanıcı arayüzünde uygulamanızı temsil etmek için kullanabileceği bir uygulama adı ve simgesi belirtmeniz gerekir.

CarAppService öğenizin 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 bildirilmezse ana makine, <application> öğesi için belirtilen değerlere geri döner.

Özel tema ayarlama

Araba uygulamanız için özel bir tema ayarlamak üzere manifest dosyanıza aşağıdaki gibi bir <meta-data> öğesi ekleyin:

<meta-data
    android:name="androidx.car.app.theme"
    android:resource="@style/MyCarAppTheme />

Ardından, özel araba uygulamanızın teması 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ığı, bir araçta şablon ana makinesi tarafından hangi kitaplık özelliklerinin desteklendiğini öğrenebilmeniz için kendi API düzeylerini tanımlar. Bir ana makine tarafından desteklenen en yüksek Car App API Düzeyini almak için getCarAppApiLevel() yöntemini kullanın.

Uygulamanızın desteklediği minimum Car App API Düzeyini AndroidManifest.xml dosyanızda beyan edin:

<manifest ...>
    <application ...>
        <meta-data
            android:name="androidx.car.app.minCarApiLevel"
            android:value="1"/>
    </application>
</manifest>

Geriye dönük uyumluluğun nasıl sağlanacağı ve bir özelliği kullanmak için gereken minimum API düzeyini nasıl bildireceğinizle ilgili ayrıntılar için RequiresCarApi ek açıklamasıyla ilgili dokümanlara bakın. Araba Uygulaması Kitaplığı'nın belirli bir özelliğini kullanmak için hangi API düzeyinin gerekli olduğunun tanımını CarAppApiLevels ile ilgili referans belgelerinde bulabilirsiniz.

CarAppService ve oturumunuzu oluşturma

Uygulamanızın CarAppService sınıfını genişletmesi ve onCreateSession yöntemini uygulaması gerekir. Bu yöntem, ana makineyle olan mevcut bağlantıya karşılık gelen bir Session örneği döndürür:

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 Screen örneğini döndürmekten 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, derin bağlantıları yönetmek gibi, uygulamanızın ana ekranı veya açılış ekranı olmayan bir ekrandan başlaması gereken senaryolarla başa çıkmak için onCreateScreen'ten geri dönmeden önce ScreenManager.push kullanarak bir grup ekranı önceden başlangıç noktası olarak ayarlayabilirsiniz. Ön başlangıç noktası, 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

Screen sınıfını genişleten sınıflar tanımlayarak ve bu sınıfın onGetTemplate yöntemini uygulayarak uygulamanızın görüntülediği ekranları oluşturursunuz. Bu yöntem, araç 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örüntülemek için PaneTemplate şablonu kullanan bir Screen 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 ve Screen örneklerinizin erişebildiği bir ContextWrapper alt sınıfıdır. Ekran yığınını yönetmek için ScreenManager, uygulama ile ilgili genel işlevler (ör. harita çizme için Surface nesnesine erişim) için AppManager ve gezinme.ana makine ile ilgili meta verilerle ve diğer diğer meta verilerle iletişim kurmak amacıyla adım adım navigasyon uygulamalarının kullandığı NavigationManager NavigationManager gibi araba 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, yapılandırmayı kullanarak araç ekranından çekilebilir kaynakları yüklemenize izin verme, amaçları kullanarak arabada bir uygulama başlatma ve uygulamanızın haritasını koyu tema içinde görüntülemesi gerekip gerekmediğ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österilen arayüzle etkileşimde bulunurken gezinebileceği farklı şablonlar kullanabilir.

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 yığını sağlar.

Aşağıdaki snippet'te, kullanıcı tarafından seçildiğinde yeni bir ekran aktaran işlemin yanı sıra mesaj şablonuna geri işleminin 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 öğesidir. Bu davranış, CarContext içindeki OnBackPressedDispatcher örneği kullanılarak geçersiz kılınabilir.

Sürüş sırasında uygulamanın güvenli bir şekilde kullanılabilmesini sağlamak için ekran yığını, maksimum 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 bir Screen içeriğinin geçersiz kılınmasını isteyebilir. Ardından ana makine, yeni içeriklerin bulunduğu şablonu almak için uygulamanızın Screen.onGetTemplate yöntemini tekrar çağırır.

Bir Screen öğesini yenilerken ana makinenin yeni şablonu şablon kotasına dahil etmemesi için şablonda güncellenebilecek belirli içeriğin anlaşılması önemlidir. Daha fazla ayrıntı 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.

Harita çizin

Aşağıdaki şablonları kullanan navigasyon ve önemli yer (ÖY) uygulamaları, bir Surfaceya erişerek harita çizebilir:

Şablon Şablon izni Kategori rehberliği
NavigationTemplate androidx.car.app.NAVIGATION_TEMPLATES Gezinme
MapWithContentTemplate androidx.car.app.NAVIGATION_TEMPLATES VEYA
androidx.car.app.MAP_TEMPLATES
Navigasyon, ÖY
MapTemplate (desteği sonlandırılmış) androidx.car.app.NAVIGATION_TEMPLATES Gezinme
PlaceListNavigationTemplate (desteği sonlandırılmış) androidx.car.app.NAVIGATION_TEMPLATES Gezinme
RoutePreviewNavigationTemplate (desteği sonlandırılmış) androidx.car.app.NAVIGATION_TEMPLATES Gezinme

Yüzey izni beyanı

Uygulamanızın kullandığı şablon için gereken izne ek olarak, yüzeye erişmek için AndroidManifest.xml dosyasında androidx.car.app.ACCESS_SURFACE iznini beyan etmesi gerekir:

<manifest ...>
  ...
  <uses-permission android:name="androidx.car.app.ACCESS_SURFACE" />
  ...
</manifest>

Yüzeylere erişin

Ana makinenin sağladığı Surface öğesine erişmek için bir SurfaceCallback uygulamanız ve bu uygulamayı AppManager araba hizmetine sağlamanız gerekir. Geçerli Surface, onSurfaceAvailable() ve onSurfaceDestroyed() geri çağırmasının SurfaceContainer parametresinde SurfaceCallback öğenize aktarılır.

Kotlin

carContext.getCarService(AppManager::class.java).setSurfaceCallback(surfaceCallback)

Java

carContext.getCarService(AppManager.class).setSurfaceCallback(surfaceCallback);

Yüzeyin görünür alanını anlama

Ana makine, haritanın üst kısmındaki şablonlara ilişkin kullanıcı arayüzü öğelerini çizebilir. Barındırıcı, SurfaceCallback.onVisibleAreaChanged yöntemini çağırarak önbelleğin engellenmediği ve kullanıcının tamamen görünür olması garanti edilen yüzey alanını iletir. Ayrıca ana makine, değişiklik sayısını en aza indirmek için SurfaceCallback.onStableAreaChanged yöntemini en küçük dikdörtgenle çağırır. Bu dikdörtgen, geçerli şablona göre her zaman görünür olur.

Örneğin, bir gezinme uygulaması üst kısmında işlem şeridi bulunan NavigationTemplate simgesini kullandığında, kullanıcı bir süre ekranla etkileşimde bulunmadığında işlem şeridi kendisini gizleyerek haritaya daha fazla yer açabilir. Bu durumda, aynı dikdörtgen ile onStableAreaChanged ve onVisibleAreaChanged için bir geri çağırma yapılır. İşlem şeridi gizlendiğinde daha geniş alanla yalnızca onVisibleAreaChanged çağrılır. Kullanıcı ekranla etkileşimde bulunursa tekrar ilk dikdörtgenle yalnızca onVisibleAreaChanged çağrılır.

Koyu temayı destekleyin

Ana makine, koşulların gerektirdiğini belirlediğinde uygulamalar, arabalar için Android uygulama kalitesi bölümünde açıklandığı üzere haritalarını uygun koyu renklerle Surface örneğine yeniden çizmelidir.

Koyu bir harita çizilip çizilmeyeceğine karar vermek için CarContext.isDarkMode yöntemini kullanabilirsiniz. Koyu tema durumu değiştiğinde Session.onCarConfigurationChanged çağrısı alırsınız.

Kullanıcıların haritanızla etkileşimde bulunmasına izin verme

Aşağıdaki şablonları kullanırken, kullanıcıların çizdiğiniz haritalarla etkileşimde bulunmaları için destek ekleyebilirsiniz. Örneğin, yakınlaştırma ve kaydırma yoluyla kullanıcıların bir haritanın farklı bölümlerini görmelerini sağlayabilirsiniz.

Şablon Car App API Düzeyinden beri desteklenen etkileşim
NavigationTemplate 2
PlaceListNavigationTemplate (kullanımdan kaldırıldı) 4
RoutePreviewNavigationTemplate (kullanımdan kaldırıldı) 4
MapTemplate (kullanımdan kaldırıldı) 5 (şablonun tanıtımı)
MapWithContentTemplate 7 (şablonun tanıtımı)

Etkileşime dayalı geri çağırmalar uygulayın

SurfaceCallback arayüzünde, bir önceki bölümde yer alan şablonlarla oluşturulmuş haritalara etkileşim eklemek için uygulayabileceğiniz çeşitli geri çağırma yöntemleri bulunur:

Etkileşim SurfaceCallback yöntem Car App API düzeyinden itibaren desteklenir
Dokunun onClick 5
Yakınlaştırmak için sıkıştırın onScale 2
Tek dokunuşla sürükleme onScroll 2
Tek dokunuşla hızlıca kaydırma onFling 2
İki kez dokunma onScale (ölçek faktörü, şablon ana makinesi tarafından belirlenir) 2
Kaydırma modunda döner sürükle onScroll (mesafe faktörü şablon ana makinesi tarafından belirlenir) 2

Haritaya ilişkin işlem şeridi ekle

Bu şablonlarda yakınlaştırma ve uzaklaştırma, yeniden ortalama ve pusula görüntüleme gibi haritayla ilgili işlemler için bir harita işlem şeridi olabilir. Haritada işlem şeridinde, görev derinliğini etkilemeden yenilenebilen en fazla 4 tane yalnızca simge düğmesi bulunabilir. Boştayken gizlenir ve etkin durumda yeniden görünür.

Harita etkileşim geri çağırmaları almak için harita işlem şeridine bir Action.PAN düğmesi eklemeniz gerekir. Kullanıcı kaydırma düğmesine bastığında, ana makine aşağıdaki bölümde açıklandığı gibi kaydırma moduna girer.

Uygulamanız harita işlem şeridindeki Action.PAN düğmesini atlarsa SurfaceCallback yöntemlerinden kullanıcı girişi almaz ve ana makine daha önce etkinleştirilmiş olan herhangi bir kaydırma modundan çıkar.

Dokunmatik ekranda yatay kaydırma düğmesi gösterilmez.

Kaydırma modunu anlama

Kaydırma modunda, şablon ana makinesi çevirmeli kumandalar ve dokunmatik alanlar gibi dokunmatik olmayan giriş cihazlarından kullanıcı girişini uygun SurfaceCallback yöntemlerine çevirir. Kaydırma moduna girmek veya moddan çıkmak için NavigationTemplate.Builder'teki setPanModeListener yöntemini kullanarak kullanıcı işlemine yanıt verin. Ana makine, kullanıcı kaydırma modundayken şablondaki diğer kullanıcı arayüzü bileşenlerini gizleyebilir.

Kullanıcıyla etkileşim kurma

Uygulamanız, mobil uygulamaya benzer kalıplar kullanarak kullanıcıyla etkileşim kurabilir.

Kullanıcı girişini işleme

Uygulamanız, uygun dinleyicileri destekleyen modellere yönlendirerek kullanıcı girişlerine yanıt verebilir. Aşağıdaki snippet'te, uygulamanızın kodu tarafından tanımlanan bir yönteme çağrı gönderen OnClickListener kodlu bir Action modelinin nasıl oluşturulacağı gösterilmektedir:

Kotlin

val action = Action.Builder()
    .setTitle("Navigate")
    .setOnClickListener(::onClickNavigate)
    .build()

Java

Action action = new Action.Builder()
    .setTitle("Navigate")
    .setOnClickListener(this::onClickNavigate)
    .build();

Daha sonra onClickNavigate yöntemi, CarContext.startCarApp yöntemini kullanarak varsayılan navigasyon araba 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 niyetinin biçimi de dahil olmak üzere uygulamaları nasıl başlatacağınızla ilgili daha fazla bilgi için Amaç ile araba uygulaması başlatma bölümüne bakın.

Kullanıcıyı mobil cihazlarında etkileşimi devam ettirmeye 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 işleme izin verilmediğine dair bir uyarı görüntüler. Araba park edilmişse kod normal şekilde çalışır. Aşağıdaki snippet, mobil cihazda bir ayarlar ekranını açmak için ParkedOnlyOnClickListener öğesinin nasıl kullanılacağını göstermektedir:

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 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 içinde ayarlanarak araba ekranında göründüğünde bildirimin ö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 araba 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 bir uyarı bildirimi (HUN) gösterilebilir.
  • İsteğe bağlı olarak, bildirimde bulunan bir rozetle bildirim merkezine bir giriş eklenebilir.
  • Navigasyon uygulamaları için bildirim, Adım adım bildirimler bölümünde açıklandığı gibi ray widget'ında görüntülenebilir.

Uygulamanızın bildirimlerini, bu kullanıcı arayüzü öğelerinin her birini etkileyecek şekilde nasıl yapılandıracağınızı, CarAppExtender belgelerinde açıklandığı gibi bildirimin önceliğini kullanarak seçebilirsiniz.

NotificationCompat.Builder.setOnlyAlertOnce true değeriyle çağrılırsa yüksek öncelikli bildirim yalnızca bir kez HUN olarak gösterilir.

Araba uygulamanızın bildirimlerini nasıl tasarlayacağınızla ilgili daha fazla bilgi için Bildirimler ile ilgili Google Sürüş İçin Tasarım kılavuzuna bakın.

Kısa ileti göster

Uygulamanız, şu snippet'te gösterildiği gibi CarToast kullanarak bir durum mesajı gösterebilir:

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'leri kullanmak yerine CarContext.requestPermissions() kullanmanın avantajı, izinler iletişim kutusunu oluşturmak için kendi Activity sürümünüzü başlatmanızın gerekmemesidir. Ayrıca, platforma bağlı akışlar oluşturmak yerine aynı kodu hem Android Auto hem de Android Automotive OS'te kullanabilirsiniz.

Android Auto'da izinler iletişim kutusunun stilini belirleme

Android Auto'da, kullanıcıya ait izinler iletişim kutusu telefonda 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>

Amaçla araba uygulaması başlatma

Aşağıdaki işlemlerden birini gerçekleştirmek için CarContext.startCarApp yöntemini çağırabilirsiniz:

  • Telefon araması yapmak için numara çeviriciyi açın.
  • Varsayılan navigasyon araç uygulaması olan bir konum için adım adım navigasyonu başlatın.
  • Bir amaç doğrultusunda kendi uygulamanızı başlatın.

Aşağıdaki örnekte, uygulamanızı bir park yeri 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 niyet sarmalayan PendingIntent içeren bir içerik niyetiyle 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());

Uygulamanız ayrıca, kullanıcı bildirim arayüzünde işlemi seçtiğinde ve veri URI'sini de içeren bir intent ile CarContext.startCarApp yöntemini çağırdığında niyeti işlemek için çağrılan bir BroadcastReceiver 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, park rezervasyonu ekranını en üstte değilse park rezervasyonu ekranını yığına iterek bu amacı yerine getirir.

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. Bu sayılardan sonuncu şablon aşağıdaki türlerden biri olmalıdır:

Bu sınırın, yığındaki Screen örneklerinin sayısı için değil, şablon sayısı için geçerli olduğunu unutmayın. Örneğin, bir uygulama A ekranındayken iki şablon gönderip B ekranına iterse 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ıtlamaların özel durumları vardır: şablon yenileme, geri ve sıfırlama işlemleri.

Şablon yenilemeleri

Belirli içerik güncellemeleri şablon sınırına dahil edilmez. Genel olarak, bir uygulama önceki şablonla aynı türde 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. Hangi içerik güncellemesi türlerinin yenileme olarak kabul edildiği hakkında daha fazla bilgi edinmek için her bir şablonun dokümanlarına bakın.

Önceki işlemler

Bir görev içindeki alt akışları etkinleştirmek için ana makine, bir uygulamanın ScreenManager yığınından bir Screen çıkardığını algılar ve kalan kotayı uygulamanın geri aldığı şablon sayısına göre günceller.

Örneğin, uygulama A ekranıdayken iki şablon gönderir, ardından B ekranına itip iki şablon daha gönderirse uygulamanın bir kotası kalır. Uygulama daha sonra A ekranına geri dönerse uygulama iki şablon geri gittiği için ana makine kotayı üçe sıfırlar.

Bir ekrana geri döndüğünüzde, uygulamanın o ekran tarafından son gönderilenle aynı türde bir şablon göndermesi gerektiğini unutmayın. Başka bir şablon türünü göndermek hataya neden olur. Bununla birlikte, bir geri işlemi sırasında tür aynı kaldığı sürece bir uygulama, kotayı etkilemeden şablonun içeriğini özgürce değiştirebilir.

Sıfırlama işlemleri

Bazı şablonlar bir görevin sonunu belirten özel anlamlara sahiptir. Örneğin NavigationTemplate, ekranda kalması ve kullanıcının tüketimine yönelik yeni adım adım talimatlarla yenilenmesi beklenen bir görünümdür. Bu şablonlardan birine ulaştığında ana makine şablon kotasını sıfırlar ve bu şablonu yeni bir görevin ilk adımıymış gibi değerlendirir. Bu işlem, uygulamanın yeni bir göreve başlamasına olanak tanır. Hangilerinin ana makinede sıfırlamayı tetiklediğini görmek için her bir şablonun dokümanlarına bakın.

Ana makine, uygulamayı bir bildirim işleminden veya başlatıcıdan başlatmak isterse kota da sıfırlanır. Bu mekanizma, uygulamanın bildirimlerden yeni bir görev akışı başlatmasını sağlar. Uygulama zaten bağlı ve ön planda olsa bile her zaman geçerlidir.

Uygulamanızın bildirimlerini araç ekranında nasıl görüntüleyeceğiniz hakkında daha fazla bilgi 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 Bir araba uygulamasını bir niyetle başlatma bölümüne bakın.

Bağlantı API'sı

Çalışma zamanında bağlantı bilgilerini almak için CarConnection API'yi kullanarak uygulamanızın Android Auto veya Android Automotive OS'te çalışıp çalışmadığını belirleyebilirsiniz.

Örneğin, araba uygulamanızın Session bölümünde 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, 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 tek seferde farklı sayıda Item örneği gösterilmesine izin verebilir. Çalışma zamanında içerik sınırını kontrol etmek ve şablonlarınızda uygun sayıda öğe ayarlamak için ConstraintManager kodunu kullanın.

CarContext'dan 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ı almak 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ılar için oturum açma deneyimi sunuyorsa arabanın ana biriminde uygulamanızda oturum açma işlemini halletmek için Car App API düzey 2 ve üzeri ile SignInTemplate ve LongMessageTemplate gibi şablonları kullanabilirsiniz.

SignInTemplate oluşturmak için bir SignInMethod tanımlayın. Araba Uygulaması Kitaplığı şu anda aşağıdaki oturum açma yöntemlerini desteklemektedir:

  • Kullanıcı adı/şifre ile oturum açmak için InputSignInMethod.
  • PIN ile oturum açmak için PinSignInMethod. Kullanıcı, ana birimde gösterilen PIN'i kullanarak hesabını telefonundan bağlamalıdır.
  • Sağlayıcı oturumu açmak için Google ile Oturum Açma ve One Tap gibi ProviderSignInMethod.
  • QR koduyla oturum açmak için QRCodeSignInMethod. Kullanıcı, telefonunda oturum açma işlemini tamamlamak için QR kodunu tarar. Bu özellik, Car API düzeyi 4 ve üzeri sürümlerde kullanılabilir.

Örneğin, kullanıcının şifresini toplayan bir şablon uygulamak için öncelikle kullanıcı girişini işlemek ve doğrulamak üzere bir InputCallback oluşturun:

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 öğenizi 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 bir kullanıcı deneyimi ve hesap yönetimi kolaylığı: Kullanıcılar, oturum açma ve oturum kapatma gibi, sistem ayarlarındaki hesaplar menüsünden tüm hesaplarını kolayca yönetebilir.
  • "Misafir" deneyimleri: Araçlar paylaşılan cihazlar olduğundan OEM'ler, araçta misafir deneyimlerini etkinleştirebilir ve hesap eklenemez.

Metin dizesi varyantları ekleyin

Farklı araç ekran boyutlarında farklı miktarlarda metin gösterilebilir. Car App API seviye 2 ve üzeriyle, bir metin dizesinin ekrana en iyi şekilde sığması için birden fazla varyantını belirtebilirsiniz. Metin varyantlarının nerede kabul edildiğini görmek için CarText alan şablonları ve bileşenleri arayın.

CarText.Builder.addVariant() yöntemiyle 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();

Ardından bu CarText öğesini, örneğin bir GridItem öğesinin birincil metni olarak kullanabilirsiniz.

Kotlin

GridItem.Builder()
    .addTitle(itemTitle)
    ...
    .build()

Java

new GridItem.Builder()
    .addTitle(itemTitle)
    ...
    build();

Dizeleri en çok tercih edilenden en az tercih edilene doğru (ör. en uzundan en kısaya) ekleyin. Ana makine, araç ekranındaki kullanılabilir alan miktarına 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 çekiciliğini 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 belgelerini inceleyin. Aralıklarla metin stilinin nasıl çalıştığına genel bir bakış için Spantastik metin stilleri ve Spans'lar bölümünü inceleyin.

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

Car App API düzey 3'ten başlayarak Araba Uygulama Kitaplığı'nda, araç özelliklerine ve sensörlerine erişmek için kullanabileceğiniz API'ler bulunur.

Gereksinimler

API'leri Android Auto ile kullanmak üzere 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'te, Android Automotive OS modülünüz için build.gradle dosyasına androidx.car.app:app-automotive bağımlılığı ekleyin.

Ayrıca AndroidManifest.xml dosyanızda, kullanmak istediğiniz araç verilerini istemek için gereken ilgili izinleri beyan etmeniz gerekir. Bu izinlerin ayrıca kullanıcı tarafından size verilmesi 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 gereken izinler farklıdır.

Araç Bilgileri

Bu tabloda CarInfo API'lerinin sunduğu özellikler ve bunları kullanmak için istemeniz gereken izinler açıklanmaktadır:

Yöntemler Kod Android Auto İzinleri Android Automotive OS İzinleri Car App API düzeyinden itibaren desteklenir
fetchModel Marka, model, yıl android.car.permission.CAR_INFO 3
fetchEnergyProfile EV konnektörü türleri, yakıt türleri com.google.android.gms.permission.CAR_FUEL android.car.permission.CAR_INFO 3
fetchExteriorDimensions

Bu veriler yalnızca API 30 veya sonraki sürümleri çalıştıran bazı Android Automotive OS araçlarda kullanılabilir

Dış boyutlar Yok android.car.permission.CAR_INFO 7
addTollListener
removeTollListener
Ücret kartı durumu, ücret kartı türü 3
addEnergyLevelListener
removeEnergyLevelListener
Pil seviyesi, yakıt seviyesi, yakıt seviyesi düşük, 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
3
addSpeedListener
removeSpeedListener
Ham hız, hız bilgisi (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
3
addMileageListener
removeMileageListener
Kilometre sayacı mesafesi com.google.android.gms.permission.CAR_MILEAGE Bu veriler, Android Automotive OS'te Play Store'dan yüklenen uygulamalarda bulunmaz. 3

Örneğin, kalan aralığı elde etmek için bir CarInfo nesnesi örneklendirin, ardından bir OnCarDataAvailableListener oluşturup 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);

Araçtan gelen verilerin her zaman ulaşılabilir 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 belgelerine bakın.

Kar Sensörleri

CarSensors sınıfı sayesinde aracın ivme ölçer, jiroskop, pusula ve konum verilerine erişebilirsiniz. Bu değerlerin kullanılabilirliği OEM'ye bağlı olarak değişebilir. İvme ölçer, jiroskop ve pusuladan alınan verilerin biçimi SensorManager API'den alacağınız verilerle 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 de beyan etmeniz ve istemeniz gerekir.

Test etme

Android Auto'da test yaparken 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 yaparken sensör verilerini simüle etmek için Android Automotive OS emülatör kılavuzunun Donanım durumu emülasyonu bölümüne bakın.

CarAppService, Oturum ve Ekran yaşam döngüleri

Session ve Screen sınıfları, LifecycleOwner arayüzünü uygular. Kullanıcı uygulamayla etkileşim kurarken 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öntemiyle ilgili belgelere göz atı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 belgelere bakın.

Araç mikrofonundan kayıt yapın

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şim izni vermesi gerekir. Uygulamanız, kullanıcının girişini kaydedip işleyebilir.

Kaydetme izni

Herhangi bir sesi kaydetmeden önce, AndroidManifest.xml içinde kayıt yapma iznini beyan etmeniz ve kullanıcıdan bu izni vermesini istemeniz gerekir.

<manifest ...>
   ...
   <uses-permission android:name="android.permission.RECORD_AUDIO" />
   ...
</manifest>

Çalışma zamanında kayıt yapmak için izin istemeniz gerekir. Araba uygulamanızda nasıl izin isteyeceğinizle ilgili ayrıntılar için İzin isteme bölümüne bakın.

Ses kaydetme

Kullanıcı kayıt izni verdikten sonra sesi kaydedebilir ve bu kaydı 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 medyanın durdurulduğundan emin olmak için önce ses odağı özelliğini kullanın. Ses odağını kaybederseniz kaydı durdurun.

Burada, 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ığı

Arabalar için Android Test Kitaplığı, uygulamanızın bir test ortamında davranışını doğrulamak için kullanabileceğiniz yardımcı sınıflar sağlar. Örneğin SessionController, ana makineyle bağlantı simülasyonu yapmanızı ve doğru Screen ile Template'ın oluşturulup döndürüldüğünü doğrulamanızı sağlar.

Kullanım örnekleri için Örnekler bölümüne bakın.

Arabalar için Android uygulama kitaplığı sorunu bildirme

Kitaplıkla ilgili bir sorun bulursanız Google Sorun İzleyici'yi kullanarak bildirin. Sorun şablonuna istenen tüm bilgileri girdiğinizden emin olun.

Yeni sayı oluştur

Yeni bir sorun oluşturmadan önce lütfen sorunun kitaplığın sürüm notlarında veya sorunlar listesinde yer alıp almadığını kontrol edin. İzleyicideki bir sorun için 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.