通过intent-filter跨App启动Service失效,求排查原因
以下是针对你遇到的问题的具体排查点,按可能性从高到低排序:
检查App A的targetSdkVersion是否升级到31+
Android 12(API 31)开始对跨App隐式启动Service做了严格限制:即使Service声明了android:exported="true",如果隐式Intent没有指定目标App的包名,queryIntentServices()会直接返回空列表。如果最近你把App A的targetSdkVersion升级到了31或更高,这是最可能的原因。
临时验证方法:在App B创建Intent时添加包名限制:Intent intent = new Intent("com.test.START"); intent.setPackage("com.example.app"); // 指定App A的包名 createExplicitIntent(context, intent);核对App A的Service配置是否被误改
检查App A的AndroidManifest.xml中Service的以下配置:- 确认
android:exported="true"没有被改成false,这是跨App访问的必要条件 - 确认
intent-filter中的action字符串完全匹配com.test.START,注意大小写、拼写和特殊字符 - 确认Service的
android:name路径正确,比如是否因为类移动了包目录而未更新manifest
- 确认
检查App A的可用性状态
- 确认App A没有被系统或用户禁用(在系统设置的应用管理中查看)
- 确认App A没有被后台限制、省电策略冻结,或者通过App Bundle分发时对应的split包未安装
排查权限相关变动
如果最近给App A的Service添加了android:permission属性(比如<service android:permission="com.test.permission.START_SERVICE"...>),需要在App B的AndroidManifest.xml中声明对应的权限:<uses-permission android:name="com.test.permission.START_SERVICE" />否则
queryIntentServices()会过滤掉没有权限访问的Service。验证Intent匹配完整性
检查App A的intent-filter是否新增了category或data规则,比如添加了<category android:name="android.intent.category.DEFAULT"/>,此时App B的Intent必须添加对应的category才能匹配:Intent intent = new Intent("com.test.START"); intent.addCategory(Intent.CATEGORY_DEFAULT);排查多Service匹配冲突
如果queryIntentServices()返回的size大于1,说明有其他App或当前App内的其他Service也注册了com.test.START这个action,导致你的方法返回null。可以打印resolveInfo的包名和类名,确认是否存在冲突。检查签名一致性变动
如果最近更换了App A的签名,且之前App A和App B使用同签名权限(比如android:protectionLevel="signature"的自定义权限),现在签名不一致会导致权限验证失败,无法查询到Service。
内容的提问来源于stack exchange,提问作者zaxunobi

