wear-osandroid-wear-complication

How to start a Wear OS app from a complication setTapAction() BroadcastReceiver?


I've created a Wear OS app with tile and complication using the built-in Android Studio project "Empty Wear App With Tile and Complications".

When the user touches the complication, I want the app to start. I've tried many things in the setTapAction() BroadcastReceiver; eg:

override fun onReceive(context: Context, intent: Intent) {
    //val appIntent = Intent(context.applicationContext, MainActivity::class.java)
    val appIntent = Intent(context, MainActivity::class.java)
    //val appIntent = Intent("au.gondwanasoftware.ontrack.presentation.MAIN")
    //appIntent.setPackage("au.gondwanasoftware.ontrack.presentation")
    //appIntent.setAction("au.gondwanasoftware.ontrack.presentation.MAIN")
    appIntent.addFlags(FLAG_ACTIVITY_NEW_TASK)
    Log.i(tag,"ComplicationBroadcastReceiver.onReceive() before startActivity()")
    //context.startActivity(appIntent)   // WIP 1 start app
    context.applicationContext.startActivity(appIntent)
    //startActivity(context.applicationContext, appIntent, null)
    Log.i(tag,"ComplicationBroadcastReceiver.onReceive() after startActivity()")
}

This version gives the following logcat:

2024-01-29 07:27:17.651 27808-27808 OnTrackTag              au.gondwanasoftware.ontrack          I  ComplicationBroadcastReceiver.onReceive() before startActivity()
2024-01-29 07:27:17.652   501-1691  ActivityTaskManager     system_server                        I  START u0 {flg=0x10000000 cmp=au.gondwanasoftware.ontrack/.presentation.MainActivity} from uid 10107
2024-01-29 07:27:17.653   501-1691  ActivityTaskManager     system_server                        W  Background activity start [callingPackage: au.gondwanasoftware.ontrack; callingUid: 10107; appSwitchState: 1; isCallingUidForeground: false; callingUidHasAnyVisibleWindow: false; callingUidProcState: RECEIVER; isCallingUidPersistentSystemProcess: false; realCallingUid: 10107; isRealCallingUidForeground: false; realCallingUidHasAnyVisibleWindow: false; realCallingUidProcState: RECEIVER; isRealCallingUidPersistentSystemProcess: false; originatingPendingIntent: null; allowBackgroundActivityStart: false; intent: Intent { flg=0x10000000 cmp=au.gondwanasoftware.ontrack/.presentation.MainActivity }; callerApp: ProcessRecord{c0dd48b 27808:au.gondwanasoftware.ontrack/u0a107}; inVisibleTask: false]
2024-01-29 07:27:17.654   501-1691  CellBroadcastUtils      system_server                        E  getDefaultCellBroadcastReceiverPackageName: no package found
2024-01-29 07:27:17.658 27808-27808 OnTrackTag              au.gondwanasoftware.ontrack          I  ComplicationBroadcastReceiver.onReceive() after startActivity()

...and obviously the app doesn't appear (although it starts fine otherwise).

How can I start the app from the complication?


ETA: this might be closer (but still doesn't work):

val appIntent = Intent("au.gondwanasoftware.action.ONTRACK")
intent.setClassName("au.gondwanasoftware.ontrack", "au.gondwanasoftware.ontrack.presentation.MainActivity")
appIntent.setFlags(FLAG_ACTIVITY_NEW_TASK)
context.startActivity(appIntent)

I added this intent-filter in the manifest:

<action android:name="au.gondwanasoftware.action.ONTRACK" />

This throws:

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=au.gondwanasoftware.action.ONTRACK flg=0x10000000 }

Solution

  • Does it have to use a broadcast receiver? If you only want to start an Activity within the same package, there's a simpler way:

    private fun createComplicationData(text: String, contentDescription: String) =
        ShortTextComplicationData.Builder(
            text = PlainComplicationText.Builder(text).build(),
            contentDescription = PlainComplicationText.Builder(contentDescription).build(),
        ).setTapAction(
            PendingIntent.getActivity(
                context,
                1, // request code
                Intent(baseContext, MainActivity::class.java),
                PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE)
        ).build()