You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ATAK插件启动自定义Service报错缺少BIND_JOB_SERVICE权限问题求助

问题根因
  1. 普通服务错误声明了系统保留权限:android.permission.BIND_JOB_SERVICE是Android系统专门为JobService类型服务保留的系统级权限,普通服务添加该属性后,系统会强制要求所有启动该服务的调用方必须持有该权限才能调用,而普通应用/ATAK插件都无法申请到这个系统专属权限。
  2. 跨包调用触发权限校验:你自己开发的示例应用和服务属于同一应用上下文,同应用内部调用服务不会触发权限校验,因此可以正常运行;但ATAK插件运行在ATAK主应用的com.atakmap.android进程中,相当于从主应用进程调用插件定义的服务,属于跨包调用场景,系统会执行严格的权限校验,因此抛出异常。
  3. 隐式Intent适配问题:Android 8.0及以上系统禁止使用隐式Intent启动后台服务,你当前使用的是仅指定action的隐式Intent,虽然调用了startForegroundService,但隐式匹配过程也可能触发额外的权限校验逻辑。
解决方案
  • 第一步:删除服务上错误的BIND_JOB_SERVICE权限声明,若服务仅插件内部使用,同时将exported改为false降低安全风险,修改后的Manifest配置如下:
<service
    android:name="mqtt.MqttBrokerService"
    android:exported="false">
    <intent-filter>
        <action android:name="mqtt.MqttBrokerService"></action>
    </intent-filter>
</service>

如果确实需要让其他应用调用该服务,请自定义普通级别的权限,不要使用系统保留的BIND_JOB_SERVICE。

  • 第二步:将隐式启动改为显式启动,避免Android 8.0+的隐式Intent启动限制,修改后的启动代码如下:
Intent startMqtt = new Intent();
// 明确指定服务的类名和插件的包名,替换为你插件自身的包名
startMqtt.setComponent(new ComponentName("你的插件包名", "mqtt.MqttBrokerService"));
getMapView().getContext().startForegroundService(startMqtt);

不需要额外设置setPackage("com.atakmap.android"),插件运行时的上下文本身就属于ATAK主进程,直接显式指定组件即可正常启动。

  • 如果你确实需要使用JobService实现调度逻辑,请确保服务类继承android.app.job.JobService,并且使用JobScheduler系统服务来调度任务,不要直接用startForegroundService启动JobService。

内容的提问来源于stack exchange,提问作者Johnny Hughes

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 23:36:03