I want to display a map, a pane and some icons on the car head unit using Android Auto. The following Kotlin code runs without errors. It displays the pane and the icons on a black background, but no map. What am I missing? Using androidx.car.app:app:1.7.0-beta03. I have tested both in the emulator (dhu) and in a car.
package se.ndssoft.autoglucose
import android.content.Intent
import androidx.car.app.CarAppService
import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.Session
import androidx.car.app.annotations.ExperimentalCarApi
import androidx.car.app.model.Action
import androidx.car.app.model.ActionStrip
import androidx.car.app.model.Header
import androidx.car.app.model.Pane
import androidx.car.app.model.PaneTemplate
import androidx.car.app.model.Row
import androidx.car.app.model.Template
import androidx.car.app.navigation.model.MapController
import androidx.car.app.navigation.model.MapWithContentTemplate
import androidx.car.app.validation.HostValidator
class CarHomeService : CarAppService() {
override fun createHostValidator(): HostValidator {
return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR
}
override fun onCreateSession(): Session {
return CarHomeSession()
}
}
class CarHomeSession : Session() {
override fun onCreateScreen(intent: Intent): Screen {
return CarHomeScreen(carContext)
}
}
class CarHomeScreen(carContext: CarContext) : Screen(carContext)
override fun onGetTemplate(): Template {
val myPane = Pane.Builder().addRow(Row.Builder().setTitle("Row 1").build()).build()
val myHeader = Header.Builder().setTitle("Header").build()
val myPaneTemplate = PaneTemplate.Builder(myPane)
.setHeader(myHeader)
.build()
val myActionStrip = ActionStrip.Builder()
.addAction(Action.APP_ICON)
.addAction(Action.PAN)
.addAction(Action.BACK)
.build()
val myMapController = MapController.Builder()
.setMapActionStrip(myActionStrip)
.build()
val myMwcTemplate = MapWithContentTemplate.Builder()
.setContentTemplate(myPaneTemplate)
.setMapController(myMapController)
.build()
return myMwcTemplate
}
}
Here is the manifest:
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES"/>
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:label="AutoGlucose"
android:name="${applicationName}"
android:icon="@mipmap/logo">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
<meta-data android:name="androidx.car.app.minCarApiLevel"
android:value="1" />
<service
android:name=".CarHomeService"
android:stopWithTask="false"
android:exported="true">
<intent-filter>
<action android:name="androidx.car.app.CarAppService" />
<category android:name="androidx.car.app.category.POI"/>
</intent-filter>
</service>
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>
The only template that draws maps on your behalf is the PlaceListMapTemplate
, which can only be used by POI apps.
The MapWithContentTemplate
, which can be used by POI apps (as well as Weather and Navigation apps), requires that you draw the maps yourself. See https://developer.android.com/training/cars/apps#draw-maps for more details on how to do that.