0

Sometimes I see error if my app run in Android Auto emulator.


2023-06-23 08:44:24.990 12425-12425 AndroidRuntime          com.capsule                          E  FATAL EXCEPTION: main
                                                                                                    Process: com.capsule, PID: 12425
                                                                                                    java.lang.RuntimeException: androidx.car.app.HostException: Remote getTemplate onSuccess call failed
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$0(RemoteUtils.java:155)
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda2.run(Unknown Source:6)
                                                                                                        at androidx.car.app.utils.ThreadUtils.runOnMain(ThreadUtils.java:39)
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallFromHost(RemoteUtils.java:147)
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$1(RemoteUtils.java:186)
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda3.run(Unknown Source:8)
                                                                                                        at android.os.Handler.handleCallback(Handler.java:914)
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100)
                                                                                                        at android.os.Looper.loop(Looper.java:224)
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7560)
                                                                                                        at java.lang.reflect.Method.invoke(Native Method)
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539)
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950)
                                                                                                    Caused by: androidx.car.app.HostException: Remote getTemplate onSuccess call failed
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallToHostForResult(RemoteUtils.java:93)
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallToHost(RemoteUtils.java:106)
                                                                                                        at androidx.car.app.utils.RemoteUtils.sendSuccessResponseToHost(RemoteUtils.java:222)
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$0(RemoteUtils.java:150)
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda2.run(Unknown Source:6) 
                                                                                                        at androidx.car.app.utils.ThreadUtils.runOnMain(ThreadUtils.java:39) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallFromHost(RemoteUtils.java:147) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$1(RemoteUtils.java:186) 
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda3.run(Unknown Source:8) 
                                                                                                        at android.os.Handler.handleCallback(Handler.java:914) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100) 
                                                                                                        at android.os.Looper.loop(Looper.java:224) 
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7560) 
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
                                                                                                    Caused by: java.lang.IllegalStateException: bnm: Unsupported template type as the last step in a task. [template: GridTemplate, ID: 79c973e6-e3a0-4cae-a540-8c4d9b86365f]
                                                                                                        at android.os.Parcel.createException(Parcel.java:2082)
                                                                                                        at android.os.Parcel.readException(Parcel.java:2042)
                                                                                                        at android.os.Parcel.readException(Parcel.java:1990)
                                                                                                        at androidx.car.app.IOnDoneCallback$Stub$Proxy.onSuccess(IOnDoneCallback.java:141)
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$sendSuccessResponseToHost$3(RemoteUtils.java:224)
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda0.call(Unknown Source:6)
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallToHostForResult(RemoteUtils.java:87)
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallToHost(RemoteUtils.java:106) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.sendSuccessResponseToHost(RemoteUtils.java:222) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$0(RemoteUtils.java:150) 
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda2.run(Unknown Source:6) 
                                                                                                        at androidx.car.app.utils.ThreadUtils.runOnMain(ThreadUtils.java:39) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.dispatchCallFromHost(RemoteUtils.java:147) 
                                                                                                        at androidx.car.app.utils.RemoteUtils.lambda$dispatchCallFromHost$1(RemoteUtils.java:186) 
                                                                                                        at androidx.car.app.utils.RemoteUtils$$ExternalSyntheticLambda3.run(Unknown Source:8) 
                                                                                                        at android.os.Handler.handleCallback(Handler.java:914) 
                                                                                                        at android.os.Handler.dispatchMessage(Handler.java:100) 
                                                                                                        at android.os.Looper.loop(Looper.java:224) 
                                                                                                        at android.app.ActivityThread.main(ActivityThread.java:7560) 
                                                                                                        at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:539) 
                                                                                                        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:950) 
2023-06-23 08:44:24.998  1897-5094  ActivityTaskManager     system_server                        W    Force finishing activity com.capsule/.MainActivity

Code of my CarPlayScreen class:


package com.capsule

import android.util.Log
import androidx.car.app.CarContext
import androidx.car.app.Screen
import androidx.car.app.model.*
import androidx.core.graphics.drawable.IconCompat
import com.tencent.mmkv.MMKV
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject


class CarPlayScreen(carContext: CarContext) : Screen(carContext) {

    private val LOG_TAG = "CarPlayScreen"

    private var eventBus = EventBus.getDefault()

    private var lastConnectedDeviceId: String? = null
    private var pinCode: String? = null
    private var capsuleState: CapsuleState? = null
    private fun renderScreen() {
        invalidate()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onCapsuleStateUpdate(state: CapsuleState) {
        capsuleState = state
        renderScreen()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onGetCurrentConnection(event: ConnectedDevice) {
        Log.d(LOG_TAG, "onConnectToDevice()  connection to ${event.currentConnection?.identifier}")

        if (event.currentConnection != null)
            lastConnectedDeviceId = event.currentConnection.identifier
        else if (lastConnectedDeviceId != null)
            eventBus.post(
                BleManagerActions(
                    BleManagerActionTypes.CONNECT_DEVICE,
                    lastConnectedDeviceId
                )
            )

        renderScreen()
    }

    @Subscribe(threadMode = ThreadMode.MAIN)
    fun onConnectToDevice(device: AdvDevice) {
        Log.d(LOG_TAG, "onConnectDevice()  connected to ${device.identifier}")
        lastConnectedDeviceId = device.identifier
        renderScreen()
    }


    init {
        eventBus.register(this)
        MMKV.defaultMMKV().decodeString("StoreCapsuleControl")?.let {
            val lastConnectedDevice = JSONObject(it)
            if (!lastConnectedDevice.isNull("lastCapsuleBleDeviceId"))
                lastConnectedDeviceId = lastConnectedDevice.getString("lastCapsuleBleDeviceId")
            pinCode = lastConnectedDevice.getString("currentPIN")

            eventBus.post(BleManagerActionTypes.GET_CONNECTED_DEVICE)
        }
    }


    override fun onGetTemplate(): Template {

        return if (lastConnectedDeviceId == null)
            GridTemplate.Builder().apply {
                setLoading(false)
                setTitle("Need Capsule connection")
                setHeaderAction(Action.APP_ICON)

                val itemList = ItemList.Builder()
                    .setNoItemsMessage("Please use your mobile application first to connect to your Capsule")
                    .build()

                setSingleList(itemList)

                setHeaderAction(Action.APP_ICON)
            }.build()
        else if (capsuleState == null)
            GridTemplate.Builder().apply {
                setLoading(true)
                setTitle("Wait Capsule connection")
                setHeaderAction(Action.APP_ICON)
            }.build()
        else buildFullStateScreenTemplate()
    }


    private fun buildFullStateScreenTemplate(): Template {

        val closedDoorIcon = CarIcon.Builder(
            IconCompat.createWithResource(
                carContext, R.drawable.locked_door
            )
        ).build()

        val openDoorIcon = CarIcon.Builder(
            IconCompat.createWithResource(
                carContext, R.drawable.open_door
            )
        ).build()

        val gridListBuilder = ItemList.Builder()
            .apply {

                // LeftDoor Mode
                val leftDoor = GridItem.Builder()
                when (capsuleState!!.leftDoorStatus) {
                    DoorState.CLOSED -> {
                        leftDoor.setTitle("OPEN")
                        leftDoor.setImage(closedDoorIcon)
                        leftDoor.setOnClickListener(capsuleCommand(2, 0x9))
                    }
                    DoorState.OPEN -> {
                        leftDoor.setTitle("CLOSE")
                        leftDoor.setImage(openDoorIcon)
                        leftDoor.setOnClickListener(capsuleCommand(2, 0xA))
                    }
                    else -> {
                        leftDoor.setLoading(true)
                        leftDoor.setTitle(capsuleState!!.leftDoorStatus.name.lowercase())
                    }
                }
                addItem(leftDoor.build())

                // RightDoor Mode
                val rightDoor = GridItem.Builder()
                when (capsuleState!!.rightDoorStatus) {
                    DoorState.CLOSED -> {
                        rightDoor.setTitle("OPEN")
                        rightDoor.setImage(closedDoorIcon)
                        rightDoor.setOnClickListener(capsuleCommand(3, 0x9))
                    }
                    DoorState.OPEN -> {
                        rightDoor.setTitle("CLOSE")
                        rightDoor.setImage(openDoorIcon)
                        rightDoor.setOnClickListener(capsuleCommand(3, 0xA))
                    }
                    else -> {
                        rightDoor.setLoading(true)
                        rightDoor.setTitle(capsuleState!!.rightDoorStatus.name.lowercase())
                    }
                }
                addItem(rightDoor.build())


                // Temperature
                val temperatureState = GridItem.Builder()
                temperatureState.setTitle("${capsuleState!!.temperature}°C")
                val temperatureIcon = IconCompat.createWithResource(
                    carContext, R.drawable.temperature_icon
                )
                temperatureState.setImage(CarIcon.Builder(temperatureIcon).build())
                addItem(temperatureState.build())


                // Front Light Mode
                val frontLight = GridItem.Builder()
                var frontLightIcon = IconCompat.createWithResource(
                    carContext, R.drawable.frontlight_on
                )

                when (capsuleState!!.frontLightMode) {
                    LightState.OFF -> {
                        frontLight.setTitle("ON")
                        frontLightIcon = IconCompat.createWithResource(
                            carContext, R.drawable.frontlight_off
                        )
                        frontLight.setOnClickListener(capsuleCommand(0, 1))
                    }
                    LightState.ON -> {
                        frontLight.setTitle("OFF")
                        frontLight.setOnClickListener(capsuleCommand(0, 0))
                    }
                    LightState.STROBE -> {
                        frontLight.setTitle("OFF")
                        frontLight.setOnClickListener(capsuleCommand(0, 0))
                    }
                }
                frontLight.setImage(CarIcon.Builder(frontLightIcon).build())
                addItem(frontLight.build())


                // Front Sublight Mode
                val frontSublight = GridItem.Builder()
                var frontSublightIcon = IconCompat.createWithResource(
                    carContext, R.drawable.frontsublight_on
                )
                when (capsuleState!!.frontSubLightMode) {
                    LightState.OFF -> {
                        frontSublight.setTitle("ON")
                        frontSublightIcon = IconCompat.createWithResource(
                            carContext, R.drawable.frontsublight_off
                        )
                        frontSublight.setOnClickListener(capsuleCommand(1, 1))
                    }
                    LightState.ON -> {
                        frontSublight.setTitle("OFF")
                        frontSublight.setOnClickListener(capsuleCommand(1, 0))
                    }
                    LightState.STROBE -> {
                        frontSublight.setTitle("OFF")
                        frontSublight.setOnClickListener(capsuleCommand(1, 0))
                    }
                }
                frontSublight.setImage(CarIcon.Builder(frontSublightIcon).build())
                addItem(frontSublight.build())

            }


        return GridTemplate.Builder().apply {
            setHeaderAction(Action.APP_ICON)
            setTitle("Capsule connected")
            setSingleList(gridListBuilder.build())
        }.build()
    }

    private fun capsuleCommand(command: Int, value: Int): OnClickListener {
        return OnClickListener {
            eventBus.post(
                BleManagerActions(
                    BleManagerActionTypes.TRANSMIT_COMMAND,
                    CapsuleCommand(command, value, pinCode ?: "")
                )
            )
        }
    }

}

Rerender is happening on events from EventBus. Few rerenders works good but after half minute I see exception which ruins my application on an Android Auto emulator and on a phone.

I have met information this error may happens because Android Auto interface is too difficult and it have many steps for some business logic but in my case I have only one Screen with easy GridTemplate without any menus.

  • This specific error is happening because the final of the five templates that can be displayed must be one of the templates listed here https://developer.android.com/training/cars/apps#template-restrictions. To understand what counts as a refresh vs a new step for the GridTemplate see https://developer.android.com/reference/androidx/car/app/model/GridTemplate. Finally, turning on the developer overlay may help you debug when new steps are being counted https://developer.android.com/training/cars/apps#template-restrictions (the section in blue) – Ben Sagmoe Jun 26 '23 at 15:48
  • @BenSagmoe Hi! Unfortunately I have not solved the problem. My stack size is constantly 1. I have noticed that androidx.car.app.HostException happens only when delay between rerenders is fractions of a second. What can I do to solve it? – Timur Ruziev Jul 18 '23 at 10:26
  • Is the cause of the exception still the same? e.g. for the above stack trace, the cause is "Caused by: java.lang.IllegalStateException: bnm: Unsupported template type as the last step in a task." – Ben Sagmoe Jul 19 '23 at 19:25

0 Answers0