KMP项目中Google App Actions触发ActivityNotFoundException问题
在现有Kotlin Multiplatform(KMP)项目中使用Google App Actions测试自定义意图,每次通过Google Assistant插件执行应用操作时,都会抛出ActivityNotFoundException,提示找不到指定的Activity类。相同的自定义意图在单独的KMP示例项目中可正常运行,怀疑是现有项目配置存在问题。
错误日志
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
现有配置
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>
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>
解决方案
统一包名配置:从错误日志可见,实际启动的包名是
au.com.packagename.app.dev,但shortcuts.xml中android:targetPackage设置的是au.com.packagename.app.android,两者不匹配。修改shortcuts.xml中的targetPackage为当前测试构建变体的包名(即au.com.packagename.app.dev),或确保所有构建变体的包名与配置一致。简化Activity类名:将
shortcuts.xml中android:targetClass改为相对路径.MainActivity,避免全路径拼写错误,同时适配KMP项目中Android模块包名可能随构建变体变化的情况。检查构建变体Manifest合并:确认当前测试的构建变体(如dev)的Manifest已正确合并,
MainActivity的exported="true"属性未被覆盖,且类名与包名对应。添加匹配的Intent Filter:在
MainActivity的Manifest配置中添加对应VIEW动作和URL的Intent Filter,确保系统能通过链接匹配到Activity:
<intent-filter> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <data android:scheme="https" android:host="custom.com" /> </intent-filter>
内容的提问来源于stack exchange,提问作者Sultan

