【发布时间】:2021-05-22 10:50:14
【问题描述】:
第一个应用有一个服务:
<service
android:name="com.example.app.service.MyService"
android:exported="true">
<intent-filter>
<action android:name="com.example.app.START_MY_SERVICE" />
</intent-filter>
</service>
另一个应用程序使用(3 种可能的方法)启动第一个应用程序的服务:
1:
val i = Intent("com.example.app.START_MY_SERVICE").apply {
setPackage("com.example.app")
}
startService(i)
2:
val i = Intent().apply {
component = ComponentName("com.example.app", "com.example.app.service.MyService")
}
startService(i)
3:
val i = Intent().apply {
setClassName("com.example.app", "com.example.app.service.MyService")
}
startService(i)
所有这些启动另一个应用程序服务的方法从 23 API (6 Android) 到 29 API (10 Android)
在 Android 11 (30 API) 上它不起作用,服务没有启动,也不例外:
当使用 2-3 种方法时,在 Logcat 中会打印:
W/ActivityManager: Unable to start service Intent { cmp=com.example.app.service/.service.MyService } U=0: not found
对于 1 种方法,什么都没有发生,Logcat 没有消息
那么我们如何在 Android 11 上从另一个应用启动某个应用的服务呢?
【问题讨论】:
-
您是否在清单中添加了
<queries>元素以识别其他应用? -
@CommonsWare 它可以是任何应用程序——Tasker、Automate 等等,不是我的应用程序,我不知道。这只是启动命令的接口
-
“我不知道”——选择一个应用程序。添加
<queries>元素,标识该应用程序。尝试您的startService()呼叫以在该应用程序中启动服务。如果它不起作用,那么您将需要做更多的研究。另一方面,如果它确实起作用,那么您知道package visibility 是您的困难的根源。然后,您需要决定是否可以说服 Google(可能还有其他应用分销商)您的应用有正当理由绕过包可见性规则。 -
@CommonsWare 是的,它与包的可见性有关,我猜像 Automate 和 Tasker 这样的应用程序有
android.permission.QUERY_ALL_PACKAGES,所以它应该可以正常工作 -
但
QUERY_ALL_PACKAGES权限 允许使用包括设备搜索、防病毒应用程序、文件管理器和浏览器。那么我必须使用什么其他目的?如果用户在应用程序 b 中使用某些产品,我想在我的应用程序 a 中存储一些数据,因此我开始了服务。那么如何知道我的应用程序 b 中发生了什么?如何在本地通知到应用程序 A?我不想为此调用网络服务,为什么不能从具有目标 api 30 的应用程序调用服务?
标签: android android-intent android-service android-11