I am using Google App Actions to run and test my custom intent on my existing Kotlin Multiplatform (KMP) project. The problem is that whenever we run the app action from the Google Assistant plugin, it will not find the activity class. error logs:
startActivityAsUser: callingPid=7402, callingUid=10225, caller=com.android.server.wm.ActivityTaskManagerService.startActivityAsUser:1816 com.android.server.wm.ActivityTaskManagerService.startActivity:1767 android.app.IActivityTaskManager$Stub.onTransact:1244 com.android.server.wm.ActivityTaskManagerService.onTransact:6590 android.os.Binder.execTransactInternal:1316 android.os.Binder.execTransact:1280 <bottom of call stack>
I appLaunchIntent package name is: au.com.packagename.app.android
I START u0 {act=android.intent.action.VIEW dat=https://custom.com/... flg=0x10000000 pkg=au.com.packagename.app.dev cmp=au.com.packagename.app.android/.MainActivity (has extras)} from uid 10225
D startActivity: reason=startActivityAsUser, result=-92
E (REDACTED) %s
android.content.ActivityNotFoundException: Unable to find explicit activity class {au.com.packagename.app.android/au.com.packagename.app.android.MainActivity}; have you declared this activity in your AndroidManifest.xml, or does your intent not match its declared <intent-filter>?
at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:2171)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1805)
at android.app.Activity.startActivityForResult(Activity.java:5596)
at abw.startActivityForResult(PG:4)
at gvlt.startActivityForResult(PG:5)
at android.app.Activity.startActivityForResult(Activity.java:5554)
at abw.startActivityForResult(PG:2)
at gvlt.startActivityForResult(PG:2)
at android.app.Activity.startActivity(Activity.java:6052)
at gvlt.startActivity(PG:5)
at com.google.android.apps.search.assistant.surfaces.voice.ui.host.activity.defaultactivity.FragmentHostDefaultActivity.startActivity(PG:10)
at android.app.Activity.startActivity(Activity.java:6019)
at gvlt.startActivity(PG:2)
at com.google.android.apps.search.assistant.surfaces.voice.ui.host.activity.defaultactivity.FragmentHostDefaultActivity.startActivity(PG:5)
at hdae.o(PG:4)
at chvr.a(PG:3)
at cuqb.accept(PG:22)
at cssw.b(PG:1)
at curt.b(PG:2)
at csss.gA(PG:5)
at hbsd.gA(PG:4)
at hbsw.b(PG:7)
at hbsq.run(PG:18)
at hdaw.run(PG:1)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
at hunl.a(PG:1)
at huml.run(PG:4)
at hunm.run(PG:1)
at hbbz.run(PG:6)
at hdaw.run(PG:1)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:487)
at hunl.a(PG:1)
at huml.run(PG:4)
at hunm.run(PG:1)
at android.os.Handler.handleCallback(Handler.java:942)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:226)
at android.os.Looper.loop(Looper.java:313)
at android.app.ActivityThread.main(ActivityThread.java:8762)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:604)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1067)
W (REDACTED) [%s] Failed to execute %s. Status: %s
I had tried this on a separate sample KMP project, and everything works fine there with the same custom intent. I am not sure if this is an issue with some setting in the KMP project or something else.
Here is my AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-permission android:name="androidx.car.app.MAP_TEMPLATES"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:name=".ApplicationName"
android:allowBackup="false"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.ApplicationName"
android:enableOnBackInvokedCallback="true"
android:localeConfig="@xml/locales_config"
>
<activity
android:name=".MainActivity"
android:theme="@style/Theme.ApplicationName.NoActionBar"
android:windowSoftInputMode="adjustResize"
android:exported="true"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.shortcuts"
android:resource="@xml/shortcuts" />
</activity>
</application>
</manifest>
And here is my shortcuts.xml
<?xml version="1.0" encoding="utf-8"?>
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<capability
android:name="custom.actions.intent.CHANGE_RESOURCE_STATUS"
app:queryPatterns="@array/resourceQueries">
<intent
android:action="android.intent.action.VIEW"
android:targetClass="au.com.packagename.app.android.MainActivity"
android:targetPackage="au.com.packagename.app.android">
<url-template android:value="https://custom.com/{?resourceStatus}" />
<parameter
android:name="resourceStatus"
android:key="resourceStatus" />
</intent>
</capability>
<shortcut
android:shortcutId="CHANGE_STATUS"
android:shortcutShortLabel="@string/assistant_change_resource_status">
<capability-binding android:key="custom.actions.intent.CHANGE_RESOURCE_STATUS">
<parameter-binding
android:key="resourceStatus"
android:value="@array/resourceStatuses" />
</capability-binding>
</shortcut>
</shortcuts>
Fixed this by debugging the app through ADB: found that my Package name was different when the app was built as I am using compose multiplatform. Follow troubleshooting guidelines from Google link