权限配置与示例运行
本页介绍 Android-JL_Health 示例工程(宜动健康 HealthAide)在 AndroidManifest.xml 中声明的全部权限及其用途、Android 版本适配要点,以及如何运行仓库内置的示例应用(宜动健康 App 与手表测试工具)。
Purpose and Scope
本页覆盖以下内容:
- 示例应用
HealthAide主工程AndroidManifest.xml中声明的 29 项权限,按功能分组说明其用途与设计意图; - 蓝牙、定位、存储等权限随 Android 版本演进的适配策略(Android 5.1 ~ 13+);
- Manifest 中与权限配套的关键声明(
queries包可见性、uses-feature、前台服务、FileProvider 等); - 如何编译并运行仓库中的两个示例应用(宜动健康 / 手表测试工具)。
以下内容属于其他 Wiki 页面,不在本页展开:
- SDK 依赖库(AAR)的接入方式与
build.gradle配置 → 参见"快速开始/依赖接入"相关页面; - RCSP 协议、蓝牙连接库、OTA 库的具体 API → 参见各自的协议与库文档页面;
- 具体业务功能(AI 表盘、消息通知、健康数据)→ 参见对应功能页面。
Overview
Android-JL_Health 是珠海杰理科技为蓝牙穿戴类产品提供的健康数据与设备管理开发平台,基于 RCSP(远程控制系统)协议。示例工程 HealthAide(包名 com.jieli.healthaide)是一个完整的参考实现:它既要驱动 BLE 穿戴设备的连接、OTA、健康数据同步,又要集成高德定位、支付宝支付、NFC 配网、AI 云服务等外部能力,因此其权限声明覆盖了网络、蓝牙、定位、存储、多媒体、NFC、通知、前台服务等多个维度。
权限配置是整个 SDK 能够正常工作的前置条件:BLE 扫描与连接在 Android 12+ 需要 BLUETOOTH_SCAN / BLUETOOTH_CONNECT,蓝牙扫描还依赖位置权限;前台连接设备服务需要 FOREGROUND_SERVICE_CONNECTED_DEVICE;文件传输与头像选择需要存储/媒体权限。Manifest 中每一行权限注释都标明了它对应的业务用途,这为二次开发裁剪权限提供了直接依据。
Architecture
flowchart TD
subgraph sg_App["HealthAide 示例应用 (com.jieli.healthaide)"]
subgraph sg_Manifest["AndroidManifest.xml"]
P_Network["INTERNET / ACCESS_NETWORK_STATE<br/>CHANGE_NETWORK_STATE / ACCESS_WIFI_STATE / CHANGE_WIFI_STATE"]
P_Bluetooth["BLUETOOTH / BLUETOOTH_ADMIN<br/>BLUETOOTH_SCAN / BLUETOOTH_CONNECT"]
P_Location["ACCESS_COARSE_LOCATION<br/>ACCESS_FINE_LOCATION / ACCESS_LOCATION_EXTRA_COMMANDS"]
P_Storage["READ/WRITE_EXTERNAL_STORAGE<br/>READ_MEDIA_IMAGES / AUDIO / VIDEO"]
P_Device["READ_PHONE_STATE / CAMERA / NFC<br/>WAKE_LOCK / READ_CONTACTS / WRITE_SETTINGS"]
P_Fg["FOREGROUND_SERVICE<br/>FOREGROUND_SERVICE_CONNECTED_DEVICE<br/>POST_NOTIFICATIONS / DISABLE_KEYGUARD"]
end
subgraph sg_Components["组件"]
LauncherActivity["LauncherActivity (入口)"]
HealthService["HealthService (前台服务 connectedDevice)"]
QRCodeScanActivity["QRCodeScanActivity (扫码)"]
NFCActivity["NFCActivity (NFC 配网)"]
end
end
subgraph sg_External["外部能力"]
JLSDK["JL_Watch SDK / RCSP 蓝牙库"]
AMap["高德定位 (APSService)"]
Alipay["支付宝 (AlipayResultActivity)"]
end
P_Network --> JLSDK
P_Bluetooth --> JLSDK
P_Location --> AMap
P_Bluetooth --> HealthService
P_Fg --> HealthService
P_Device --> QRCodeScanActivity
P_Device --> NFCActivity
LauncherActivity --> HealthService
LauncherActivity --> NFCActivity
图注:Manifest 中的权限分组与组件一一对应——蓝牙/网络/位置权限服务于 RCSP SDK 与高德定位,前台服务相关权限保障 HealthService(foregroundServiceType="connectedDevice")在后台持续运行,CAMERA/NFC 分别支撑扫码配网与 NFC 配网入口。权限声明的粒度直接决定了示例工程可运行的 Android 版本范围(Android 5.1+)以及各业务模块的可裁剪性。
权限清单详解
示例工程主 AndroidManifest.xml 位于 code/app/HealthAide_V1.1.0_SDK_V1.14.0/app/src/main/AndroidManifest.xml,共声明 29 项权限。按功能分组如下:
1. 网络与 WiFi 权限(5 项)
| 权限 | 用途(Manifest 注释) |
|---|---|
INTERNET | 网络定位;实现定位"小蓝点"功能时必选 |
ACCESS_NETWORK_STATE | 获取 WiFi 状态改变,用于网络定位 |
CHANGE_NETWORK_STATE | 读设备等信息,用于问题排查 |
ACCESS_WIFI_STATE | 写入扩展存储,用于搜索结果缓存(无此权限则写私有目录) |
CHANGE_WIFI_STATE | 修改 WiFi 状态 |
这些权限支撑健康数据上传、OTA 固件下载、AI 云服务(HTTP 通信)以及高德网络定位。注意 Manifest 注释与权限实际语义存在历史错位(注释为复制粘贴产生),二次开发时应以权限真实用途为准。
2. 蓝牙权限(4 项)
| 权限 | 适用版本 | 说明 |
|---|---|---|
BLUETOOTH | Android 5.1 ~ 11 | 传统蓝牙连接/通信 |
BLUETOOTH_ADMIN | Android 5.1 ~ 11 | 蓝牙扫描与开关控制 |
BLUETOOTH_SCAN | Android 12+ | 替代 BLUETOOTH_ADMIN 的扫描权限(运行时权限) |
BLUETOOTH_CONNECT | Android 12+ | 替代 BLUETOOTH 的连接权限(运行时权限) |
同时声明新旧两套蓝牙权限是兼容 Android 5.1 ~ 13+ 的关键设计:旧权限在新系统上被忽略,新权限在老系统上被忽略,系统会根据 targetSdkVersion 与设备版本自动选择生效项。
3. 定位权限(3 项)
| 权限 | 用途 |
|---|---|
ACCESS_COARSE_LOCATION | 粗略定位;Android 官方要求使用蓝牙或网络开发时必须声明位置信息 |
ACCESS_FINE_LOCATION | 精确定位,驱动高德地图定位"小蓝点" |
ACCESS_LOCATION_EXTRA_COMMANDS | 额外的定位命令支持 |
设计意图:Android 的 BLE 扫描结果会关联地理位置信息(用于 Wi-Fi/蓝牙辅助定位),因此系统强制蓝牙扫描应用声明位置权限。即便 App 本身不需要地图功能,只要进行 BLE 扫描就必须申请定位权限。
4. 存储与媒体权限(5 项)
| 权限 | 适用版本 | 用途 |
|---|---|---|
READ_EXTERNAL_STORAGE | ≤ Android 12 | 读取外部存储(头像选择、文件导入) |
WRITE_EXTERNAL_STORAGE | ≤ Android 12 | 写入扩展存储,缓存搜索结果 |
READ_MEDIA_IMAGES | Android 13+ | 读取图片 |
READ_MEDIA_AUDIO | Android 13+ | 读取音频 |
READ_MEDIA_VIDEO | Android 13+ | 读取视频 |
版本演进:Android 13 将存储权限拆分为 READ_MEDIA_IMAGES/AUDIO/VIDEO,示例工程同时声明新旧两组权限以覆盖 Android 5.1 ~ 13+。此外 application 节点设置了 android:requestLegacyExternalStorage="false",表示 targetSdk 30+ 下遵循分区存储(scoped storage)规则;Manifest 注释亦说明"若无此权限则写到私有目录",即权限被拒绝时功能自动降级。
5. 设备与硬件权限(7 项)
| 权限 | 用途 |
|---|---|
READ_PHONE_STATE | 读取设备信息,用于问题排查 |
CAMERA | 扫码添加设备(QRCodeScanActivity) |
NFC | NFC 配网(NFCActivity) |
WAKE_LOCK | 保持 CPU 唤醒,写设备缓存 |
READ_CONTACTS | 读取联系人信息 |
WRITE_SETTINGS | 操作蓝牙搜索功能(tools:ignore="ProtectedPermissions",系统设置类权限) |
DISABLE_KEYGUARD | 操作蓝牙连接功能(锁屏场景) |
其中 WRITE_SETTINGS 与 DISABLE_KEYGUARD 属于 signature/protected 级别权限,需通过 tools:ignore="ProtectedPermissions" 抑制 Lint 告警;WRITE_SETTINGS 还需在运行时引导用户进入系统设置页单独授权。
6. 通知与前台服务权限(4 项)
| 权限 | 用途 |
|---|---|
POST_NOTIFICATIONS | Android 13+ 通知推送权限 |
FOREGROUND_SERVICE | 允许启动前台服务(保活) |
FOREGROUND_SERVICE_CONNECTED_DEVICE | Android 14+ 指定 connectedDevice 类型前台服务必须声明 |
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS | 请求忽略电池优化,保障后台连接稳定 |
与权限配套,Manifest 声明了 HealthService:
<service
android:name=".ui.service.HealthService"
android:enabled="true"
android:exported="true"
android:foregroundServiceType="connectedDevice"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" />
</intent-filter>
</service>
Source: AndroidManifest.xml
设计意图:穿戴设备消息推送依赖通知监听,因此 HealthService 同时具备通知监听器(NotificationListenerService)与前台 connectedDevice 服务双重身份——前者读取系统通知并转发给手表,后者保证进程不被系统回收。connectedDevice 是 Android 14 为穿戴/车机场景新增的前台服务类型,必须在 Manifest 中显式声明并搭配 FOREGROUND_SERVICE_CONNECTED_DEVICE 权限。
7. 包可见性与硬件特性声明
除权限外,Manifest 还包含两处与权限行为密切相关的声明:
<queries> 包可见性(Android 11+ 应用可见性机制):显式声明支付宝 SDK 需要探测的包,使 targetSdkVersion ≥ 30 时仍能感知设备是否安装支付宝 App:
<queries>
<package android:name="com.eg.android.AlipayGphone" /> <!-- 支付宝 -->
<package android:name="hk.alipay.wallet" /> <!-- AlipayHK -->
</queries>
Source: AndroidManifest.xml
<uses-feature> NFC 硬件要求:
<uses-feature
android:name="android.hardware.nfc"
android:required="true" />
Source: AndroidManifest.xml
required="true" 意味着在无 NFC 硬件的设备上,应用无法从应用商店安装——这与 NFCActivity 作为配网入口的产品定位一致。若希望降级支持无 NFC 设备,可将 required 改为 false 并在运行时检测。
示例应用运行
仓库提供两个可直接编译运行的示例工程(位于 code/ 目录),对应 apk/ 目录下的测试 APK:
宜动健康(HealthAide)
- 工程路径:
code/app/HealthAide_V1.1.0_SDK_V1.14.0/ - 定位:完整健康 SDK 功能演示(连接、健康数据、OTA、AI 表盘、消息通知等)
- 启动入口:
LauncherActivity(android.intent.action.MAIN+LAUNCHER),随后可进入HomeActivity、LoginActivity、ContentActivity - 运行前置条件:Android 5.1+ 且支持 BLE 的设备;推荐使用支持 RCSP 的杰理穿戴硬件(AC701N、AC707N、AC695N 等)
手表测试工具(WatchTestTool)
- 工程路径:
code/tool/WatchTestTool_V0.9.0_SDK_V1.14.0/ - 定位:用于逐项测试手表功能的工具应用(其
app/src/main/AndroidManifest.xml独立声明自身所需权限)
运行步骤
- 使用 Android Studio 打开
code/目录下的目标工程(对应 README 3.2 节"导入项目到 Android Studio"); - 确认工程
libs/目录已包含JL_Watch_Vxxx-release.aar、jl_bluetooth_connect_Vxxx-release.aar、jl_rcsp_Vxxx-release.aar等核心库(xxx 为版本号); - 同步 Gradle 后,选择已开启开发者模式并打开蓝牙/定位的真机(穿戴 SDK 依赖真机 BLE 硬件,模拟器无法验证);
- 首次启动时按系统提示授予位置、蓝牙(Android 12+)、通知(Android 13+)等运行时权限。
说明:BLE 与穿戴设备交互必须在真机验证;若设备无 GPS 但仍需定位"小蓝点",
INTERNET、ACCESS_NETWORK_STATE、ACCESS_WIFI_STATE等网络定位权限为必选(见 Manifest 注释)。
核心流程:示例应用启动与权限请求
示例应用从启动到设备连接,权限按"Manifest 静态声明 → 系统安装期授权 → 运行时动态请求 → 功能降级"的链路生效:
sequenceDiagram
participant U as 用户
participant OS as Android 系统
participant App as HealthAide App
participant HW as 杰理穿戴设备
U->>OS: 安装/启动 App (LauncherActivity)
OS->>OS: 校验 Manifest 静态权限<br/>(安装期授权 normal 权限)
OS->>App: 授予 normal 权限
App->>App: 检查运行时权限<br/>(BLUETOOTH_SCAN/CONNECT、位置、通知等)
alt 权限未授予
App->>OS: 发起运行时权限请求 (Activity 弹窗)
OS-->>U: 显示授权对话框
U-->>OS: 授予/拒绝
end
App->>HW: BLE 扫描/连接 (依赖蓝牙+位置权限)
HW-->>App: RCSP 连接建立
App->>App: 启动 HealthService<br/>(foregroundServiceType=connectedDevice)
OS-->>App: 通知栏常驻前台服务
流程要点:
- 安装期:
normal级别权限(INTERNET、ACCESS_NETWORK_STATE、WAKE_LOCK、FOREGROUND_SERVICE等)由系统自动授予,用户无感知; - 运行时:危险权限(位置、蓝牙扫描/连接、存储、通知)需在代码中通过运行时权限 API 请求,用户可随时在设置中撤销;
- 服务保活:连接建立后启动
HealthService前台服务,配合WAKE_LOCK与电池优化豁免(REQUEST_IGNORE_BATTERY_OPTIMIZATIONS)保证长连接稳定; - 降级路径:部分权限缺失时功能自动降级——如无存储权限则缓存写入私有目录(Manifest 注释明示),无 GPS 时退化为网络定位。
配置选项
AndroidManifest 权限声明速查
以下为示例工程声明的高风险/版本敏感权限,接入 SDK 时按需拷贝(完整清单见上方分组表):
| 权限 | 类型 | 最低版本 | 说明 |
|---|---|---|---|
BLUETOOTH_SCAN | 运行时 | Android 12 | 声明 neverForLocation 需谨慎:若用于 BLE 扫描定位,不可设置 |
BLUETOOTH_CONNECT | 运行时 | Android 12 | 连接已配对设备必需 |
ACCESS_FINE_LOCATION | 运行时 | Android 6.0 | BLE 扫描前置条件(系统级强制) |
ACCESS_COARSE_LOCATION | 运行时 | Android 6.0 | 可单独授予以节省定位精度 |
READ_MEDIA_IMAGES | 运行时 | Android 13 | 替代 READ_EXTERNAL_STORAGE |
POST_NOTIFICATIONS | 运行时 | Android 13 | 通知推送必需 |
FOREGROUND_SERVICE_CONNECTED_DEVICE | normal | Android 14 | 声明 connectedDevice 前台服务必需 |
WRITE_SETTINGS | special | 全部 | 需引导用户到系统设置页单独授权 |
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS | normal | 全部 | 需引导用户到电池优化页确认 |
Application 节点关键配置
| 属性 | 值 | 说明 |
|---|---|---|
android:name | .HealthApplication | 应用级初始化(SDK 上下文) |
android:allowBackup | false | 禁用数据备份,保护设备凭据 |
android:requestLegacyExternalStorage | false | 遵循分区存储(scoped storage) |
android:usesCleartextTraffic | true | 允许明文 HTTP(开发期 SDK/服务器通信) |
android:networkSecurityConfig | @xml/network_security_config | 网络安全配置覆盖 |
失败模式、边界情况与并发注意
以下问题场景均能从 Manifest/README 中找到对应设计依据:
- Android 12+ 蓝牙崩溃:若运行时未请求
BLUETOOTH_CONNECT便调用蓝牙 API,系统抛出SecurityException。新旧权限并存声明正是为了在不同版本上覆盖此场景;Android 12 首次启动务必在授权流程中包含蓝牙权限。 - BLE 扫描无结果:最常见原因是位置权限缺失或被撤销(Android 强制关联),以及位置服务(GPS/Wi-Fi 扫描)未开启——这是
ACCESS_COARSE_LOCATION/ACCESS_FINE_LOCATION同时声明的原因。 - Android 14 前台服务崩溃:
connectedDevice类型前台服务若未声明FOREGROUND_SERVICE_CONNECTED_DEVICE权限或未设置foregroundServiceType,启动时抛出ForegroundServiceStartNotAllowedException/SecurityException。 - Android 13 存储行为差异:
READ_MEDIA_*未授予时,读取图片/音视频返回空集而非异常;READ_EXTERNAL_STORAGE在新版本上不再授予。工程同时声明新旧权限以覆盖全部版本,但运行时需按Build.VERSION.SDK_INT分支请求。 - WRITE_SETTINGS 特殊性:该权限不属于运行时权限弹窗体系,被拒绝后必须跳转
Settings.ACTION_MANAGE_WRITE_SETTINGS由用户手动开启,否则蓝牙搜索功能不可用(Manifest 中以tools:ignore="ProtectedPermissions"标注)。 - 包可见性缺失:
targetSdkVersion ≥ 30且未声明<queries>时,支付宝 SDK 无法探测 App 是否安装,导致支付跳转静默失败;AlipayResultActivity的intent-filter与 scheme__lsalipaysdk__也是支付回跳的必要配置。 - 并发/后台限制:
HealthService同时作为通知监听器与前台服务运行,Android 12+ 对前台服务启动存在后台限制(BackgroundServiceStartNotAllowedException),连接建立后需立即startForeground()避免被杀;WAKE_LOCK用于在数据同步期间保持 CPU 唤醒,需成对 acquire/release 防止耗电异常。 - 模拟器限制:BLE、NFC 依赖真机硬件,模拟器上权限可授予但功能不可用,示例运行应在真机验证。
使用示例
最小权限配置(SDK 接入场景)
官方 README 给出接入 SDK 时的最小权限集合——只需蓝牙与定位权限即可支撑核心穿戴连接功能,其余权限按业务模块按需添加(区别于示例工程的全量声明):
<-- 使用蓝牙权限 --!>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<-- 定位权限,官方要求使用蓝牙或网络开发,需要位置信息 --!>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<-- Android 12+ 需要增加蓝牙连接权限 --!>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
Source: README.md
对应英文版说明(新增 BLUETOOTH_SCAN):
<!-- Bluetooth permissions -->
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<!-- Required for newer Android versions -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!-- Location permission, required by Android for Bluetooth/network development -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Source: README_en.md
设计对比:官方最小集合仅 6 项权限,而示例工程声明 29 项——这正是"按需申请"原则的体现:示例工程聚合了支付、地图、扫码、NFC、通知转发等全部能力,因此权限面最大;接入方应只保留自身业务对应的权限,减少隐私合规风险与应用商店审核问题。
依赖库接入(示例运行前置条件)
运行示例工程前,需将核心 AAR 库放入模块 libs/ 目录并在 build.gradle 声明依赖:
dependencies {
//1.将上面的aar文件放入工程目录中的对应moudle的lib文件夹下
//2.在moudlu的build.gradle中添加
implementation fileTree(include: ['*.aar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.13.1'
}
Source: README.md
仓库结构定位
示例工程与权限/运行相关的目录布局:
Android-JL_Health/
├── apk/ # 测试APK文件夹
│ ├── app # 宜动健康测试APK,建议在应用商店下载
│ └── tool # 手表测试工具,用于测试手表功能
├── code/ # 参考源码工程文件夹
│ ├── app # 宜动健康开放源码
│ └── tool # 手表测试工具开放源码
└── libs/ # 核心库文件夹(AAR 依赖)
Source: README.md
扩展点与运维建议
- 权限裁剪:按业务模块移除 Manifest 中的无关权限。例如不接支付宝可删除
<queries>中两个支付宝包声明与AlipayResultActivity;不做扫码可移除CAMERA与QRCodeScanActivity;不需要 NFC 配网可将uses-feature的required改为false以扩大可安装设备范围。 - 位置权限豁免:若设备目标用户群体不涉及位置服务,可在
BLUETOOTH_SCAN上声明android:usesPermissionFlags="neverForLocation"并在 Manifest 中说明不使用蓝牙扫描结果推导位置,从而在部分市场免于申请位置权限——但需确认与 SDK 定位能力的取舍。 - 调试建议:遇到连接类问题,优先按"权限 → 位置服务开关 → 电池优化 → 通知监听授权"顺序排查;
HealthService的通知监听授权(NotificationListenerService)无法通过运行时权限 API 请求,需引导用户在系统设置中手动开启"通知使用权"。 - 版本升级提醒:每次提升
compileSdk/targetSdkVersion时,对照本节权限速查表检查新版本引入的权限拆分(如 Android 13 媒体权限、Android 14 前台服务类型),避免高版本设备上功能静默失效。
相关链接
- README.md — 权限配置(3.4)与运行示例应用(3.5)
- README_en.md — Permission Configuration
- HealthAide 主 AndroidManifest.xml
- WatchTestTool AndroidManifest.xml
- 工程结构与依赖库说明 → README.md — 工程结构
- SDK 接入与 AAR 依赖 → 参见"快速开始"相关页面
- RCSP 协议与蓝牙连接库 → 参见协议与连接库文档页面