杰理 SDK 文档中心
首页
首页
  • 快速开始

    • 环境要求与权限配置
    • 集成SDK依赖
    • 运行示例应用
  • 核心架构与协议

    • RCSP协议与数据通道
    • 蓝牙连接与设备管理
    • TWS双耳功能
    • 基础功能接口与自定义命令
  • 设备功能控制

    • 设备音乐控制与ID3信息
    • 文件浏览与传输
    • FM收音与发射
    • 灯光控制
    • 闹钟与时间管理
    • 查找设备与防丢
    • ANC与噪声处理
    • 按键功能设置
    • 彩屏仓控制
    • AI翻译
  • 音效与音频处理

    • 均衡器音效调节
    • 录音与语音控制
    • Line-in、SPDIF与声卡功能
    • 音频编解码库
  • 扩展功能库

    • OTA固件升级
    • 数据加密与解密
    • 图片与动图格式转换
  • 示例应用 btsmart

    • 应用架构与界面导航
    • 设备功能适配与数据层
    • 设备配置JSON与资源文件
  • 参考与版本

    • 错误码参考
    • 版本历史与更新日志
    • 开发文档中心导航

环境要求与权限配置

本文档说明 Jieli Bluetooth(杰理蓝牙)SDK 示例工程 PiHome_V1.13.0_SDK_V4.2.0 的构建/运行环境要求,以及蓝牙、定位、存储等运行时权限的声明与配置方式,帮助集成方快速完成工程接入前的环境准备。

Purpose and Scope

本页覆盖以下内容:

  • 编译构建环境要求(compileSdk / minSdk / targetSdk、JDK 版本、NDK ABI 支持)
  • AndroidManifest.xml 中声明的全部权限、uses-feature 硬件能力要求
  • Android 各版本(6.0 运行时权限、12+ 蓝牙细分权限、13+ 通知权限)的权限适配要点
  • build.gradle 中与权限、环境相关的配置项(applicationId、manifestPlaceholders、flavor 等)

与本页相邻但由其他页面覆盖的内容:SDK 的具体 API 调用、设备连接流程、固件升级流程等不在本页展开,参见相关页面。

Overview

Android 系统对蓝牙应用的权限要求随版本不断收紧。本示例工程作为杰理蓝牙 SDK 的完整参考实现,其权限声明覆盖了:

  1. 经典蓝牙 / BLE 通信:BLUETOOTH、BLUETOOTH_ADMIN(Android 12 以下)与 BLUETOOTH_SCAN、BLUETOOTH_CONNECT(Android 12+)。
  2. BLE 扫描所依赖的定位权限:ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION(Android 11 及以下扫描 BLE 必须)。
  3. 业务功能权限:相机(扫码配网)、录音、通知、外部存储、精确闹钟、悬浮窗、前台服务(含 connectedDevice / location 类型)等。
  4. 硬件能力声明:通过 uses-feature 声明 BLE 与摄像头为必需能力,过滤不支持设备。

工程侧(build.gradle)则通过 minSdk 21(Android 5.0)到 targetSdk 35(Android 15)的区间,覆盖了绝大多数存量设备,并通过 compileSdk 36 使用最新的编译 API。

Architecture

下图展示了环境要求与权限配置在工程中的整体结构:构建配置决定权限声明与 SDK 版本,清单文件声明静态权限与能力,系统运行时权限模型决定动态授权行为。

flowchart TD
    subgraph sg_Build["构建环境 (build.gradle)"]
        CompileSdk["compileSdk 36"]
        MinSdk["minSdk 21"]
        TargetSdk["targetSdk 35"]
        JDK8["Java 8 兼容"]
        ABI["ABI: armeabi-v7a / arm64-v8a"]
    end

    subgraph sg_Manifest["清单声明 (AndroidManifest.xml)"]
        FeatureBLE["uses-feature bluetooth_le"]
        FeatureCam["uses-feature camera"]
        PermLegacy["BLUETOOTH / BLUETOOTH_ADMIN"]
        Perm12["BLUETOOTH_SCAN / BLUETOOTH_CONNECT"]
        PermLoc["ACCESS_COARSE/FINE_LOCATION"]
        PermBiz["相机/录音/存储/通知/前台服务等"]
        Services["FloatingViewService / APSService 等前台服务"]
    end

    subgraph sg_Runtime["系统运行时权限模型"]
        DangPerm["危险权限动态申请 (Android 6.0+)"]
        BT12["蓝牙细分权限 (Android 12+)"]
        Notify13["通知权限 (Android 13+)"]
        FGS14["前台服务类型 (Android 14+)"]
    end

    sg_Build -->|"决定 targetSdk 行为"| sg_Manifest
    sg_Manifest -->|"静态声明"| sg_Runtime
    PermLegacy --> BT12
    PermLoc --> DangPerm
    Perm12 --> DangPerm
    PermBiz --> DangPerm
    PermBiz --> Notify13
    Services --> FGS14

各层说明:

  • 构建环境层:build.gradle 中的 compileSdk、minSdk、targetSdk 直接决定权限语义——尤其是 targetSdk 切换 Android 12/13 后系统会采用新的蓝牙细分权限与通知权限模型,这是集成时最容易踩坑的地方。
  • 清单声明层:AndroidManifest.xml 集中声明全部静态权限、硬件能力与前台服务。所有权限在这里声明后,危险权限还需在运行时动态申请。
  • 系统运行时模型层:Android 系统按版本对权限进行分组(普通/危险/特殊),示例工程通过 targetSdk 35 触发新版权限行为,需要配套的运行时申请逻辑。

构建环境要求

以下配置摘自 btsmart/build.gradle:

android {

    namespace 'com.jieli.btsmart'
    compileSdk 36

    defaultConfig {
        applicationId "com.jieli.btsmart"
        minSdk 21
        targetSdk 35
        versionCode 113126
        versionName "1.13.0"
        testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        multiDexEnabled true
        ...
        ndk {
            // 设置支持的SO库架构
            abiFilters 'armeabi-v7a', 'arm64-v8a'
        }
    }
    ...
    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }
}

Source: btsmart/build.gradle

关键环境参数:

参数值说明
compileSdk36使用 Android 16 编译 API
minSdk21Android 5.0(Lollipop)起支持
targetSdk35Android 15,启用新版权限行为
Java1.8sourceCompatibility / targetCompatibility 均为 VERSION_1_8
abiFiltersarmeabi-v7a、arm64-v8a仅打包 32/64 位 ARM 架构的 SO 库
multiDexEnabledtrue方法数超过 64K,需开启 multidex

targetSdk 的权限语义

targetSdk 35 意味着在 Android 12+(API 31+)设备上,系统将应用视为面向新版权限模型:

  • Android 12+:BLUETOOTH_SCAN / BLUETOOTH_CONNECT 成为必需,旧权限 BLUETOOTH / BLUETOOTH_ADMIN 仅起到兼容作用。
  • Android 13+:POST_NOTIFICATIONS 作为危险权限需要动态申请;READ_MEDIA_AUDIO / READ_MEDIA_IMAGES 取代旧的存储权限读写媒体文件。
  • Android 14+:前台服务必须声明类型(foregroundServiceType),本工程声明了 connectedDevice 与 location。

NDK ABI 与硬件依赖

abiFilters 只保留 armeabi-v7a 与 arm64-v8a,将打包体积控制在最小且覆盖主流机型;因此运行环境必须是 ARM 架构 Android 设备(x86 模拟器上蓝牙相关 SO 库不可用,BLE 功能在模拟器上不可验证)。

权限清单详解

完整权限声明位于 AndroidManifest.xml 的 uses-feature 与 uses-permission 段,按用途分类如下。

硬件能力声明

<uses-feature
    android:name="android.hardware.bluetooth_le"
    android:required="true" />

<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />

Source: AndroidManifest.xml

required="true" 表示这两个能力是 App 运行的必要条件:没有 BLE 的设备(或 ROM 关闭了 BLE)将无法安装应用;摄像头用于扫码配网,同样是强依赖。

权限分组表

权限类型用途
INTERNET普通网络通信、OTA 资源下载
BLUETOOTH / BLUETOOTH_ADMIN普通(≤ Android 11)经典蓝牙连接与扫描(旧版模型)
BLUETOOTH_SCAN危险(Android 12+)扫描 BLE 设备
BLUETOOTH_CONNECT危险(Android 12+)连接已配对的蓝牙设备
ACCESS_COARSE_LOCATION / ACCESS_FINE_LOCATION危险Android 11 及以下 BLE 扫描必须;高德定位
CAMERA危险二维码扫码配网
RECORD_AUDIO危险录音功能
READ_PHONE_STATE危险读取设备信息,用于问题排查
READ/WRITE_EXTERNAL_STORAGE危险(≤ Android 12)旧版外部存储读写
READ_MEDIA_AUDIO / READ_MEDIA_IMAGES危险(Android 13+)新版媒体读取
POST_NOTIFICATIONS危险(Android 13+)发送通知
FOREGROUND_SERVICE普通启动前台服务
FOREGROUND_SERVICE_LOCATION危险定位型前台服务(高德 APSService)
FOREGROUND_SERVICE_CONNECTED_DEVICE普通连接设备型前台服务(FloatingViewService 等)
WAKE_LOCK普通保持屏幕/CPU 唤醒
VIBRATE普通振动提醒
CHANGE_WIFI_STATE / CHANGE_NETWORK_STATE / ACCESS_WIFI_STATE / ACCESS_NETWORK_STATE普通Wi-Fi 配网与网络状态监听
GET_TASKS / REORDER_TASKS普通任务栈管理(Launcher 场景)
SYSTEM_ALERT_WINDOW特殊悬浮窗(设备弹窗、FloatingViewService)
SCHEDULE_EXACT_ALARM特殊精确闹钟调度
HIGH_SAMPLING_RATE_SENSORS普通高采样率传感器(手势识别)

应用级配置与前台服务声明

Application 级属性

AndroidManifest.xml 的 <application> 标签声明了多个与运行环境相关的属性:

<application
    android:name=".MainApplication"
    android:allowBackup="true"
    android:allowNativeHeapPointerTagging="false"
    android:icon="@mipmap/ic_btsmart_logo"
    android:label="@string/app_name"
    android:requestLegacyExternalStorage="true"
    android:roundIcon="@mipmap/ic_btsmart_logo"
    android:supportsRtl="true"
    android:theme="@style/AppTheme"
    android:usesCleartextTraffic="true"
    tools:ignore="GoogleAppIndexingWarning"
    tools:replace="android:allowBackup">

Source: AndroidManifest.xml

值得注意的设计意图:

  • android:requestLegacyExternalStorage="true":在 Android 10/11 上继续使用旧的外部存储模型,配合 READ/WRITE_EXTERNAL_STORAGE 权限读写共享存储;Android 13+ 则改由 READ_MEDIA_* 权限接管媒体文件。
  • android:usesCleartextTraffic="true":允许明文 HTTP 流量,用于局域网设备通信与 OTA 资源服务器(https://cam.jieliapp.com 等),集成方应评估安全策略。
  • android:allowNativeHeapPointerTagging="false":关闭 Native 堆指针标签,兼容部分老型号 SoC 的蓝牙协议栈。

前台服务与系统组件

工程声明了若干系统组件,均与蓝牙/定位业务强相关:

<service
    android:name=".ui.widget.product_dialog.FloatingViewService"
    android:enabled="true"
    android:exported="true"
    android:foregroundServiceType="connectedDevice" /> <!-- 定位需要的服务 使用2.0的定位需要加上这个 -->
<service
    android:name="com.amap.api.location.APSService"
    android:enabled="true"
    android:exported="true"
    android:foregroundServiceType="location" />
<service
    android:name=".ui.widget.DevicePopDialog.DevicePopDialog"
    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

  • FloatingViewService 与 DevicePopDialog 声明为 connectedDevice 类型前台服务,保持与已连接蓝牙设备的常驻通道,同时满足 Android 14+ 对前台服务类型的强制要求。
  • APSService(高德定位)声明为 location 类型,因此需要 FOREGROUND_SERVICE_LOCATION 权限。
  • DevicePopDialog 还是通知监听服务(NotificationListenerService),需要用户在系统设置中手动授权"通知使用权"——这是系统特殊授权,无法通过运行时权限弹窗获取。
  • FileProvider(${applicationId}.provider)用于跨应用共享文件(如扫码后的图片裁剪),grantUriPermissions="true" 配合 provider_paths 控制可共享路径。

运行时权限申请流程

清单声明只是第一步;危险权限必须在运行时申请。下图描述了 BLE 场景下的典型权限流转:

sequenceDiagram
    participant U as 用户
    participant A as LauncherActivity/CommonActivity
    participant S as Android 系统
    participant BT as 蓝牙协议栈

    A->>S: 检查 targetSdk 对应权限模型
    alt Android 12+ (API 31+)
        A->>S: 申请 BLUETOOTH_SCAN + BLUETOOTH_CONNECT
    else Android 6~11 (API 23-30)
        A->>S: 申请 ACCESS_FINE_LOCATION
    end
    S-->>A: 弹出授权对话框
    U->>S: 授权/拒绝
    S-->>A: onRequestPermissionsResult
    alt 已授权
        A->>BT: 开启扫描/连接设备
    else 被拒绝
        A->>U: 提示引导去设置页手动开启
    end

设计意图说明:

  1. 版本分叉:Android 12 起系统将蓝牙权限从定位权限中剥离。若应用仍只申请定位权限,在 Android 12+ 上将无法扫描/连接;反之,在 Android 11 及以下系统只认定位权限。因此兼容区间(minSdk 21 → targetSdk 35)的集成方必须同时声明两组权限并做运行时分支。
  2. 位置开关:即使定位权限已授权,Android 11 及以下还要求系统"位置服务"总开关打开,否则 BLE 扫描静默失败——这是最常见的中文 ROM 排查点。
  3. 特殊权限:SYSTEM_ALERT_WINDOW(悬浮窗)与通知使用权需要跳转系统设置页由用户手动开启,代码中只能通过 Settings.canDrawOverlays() 等 API 检查状态后引导。

Usage Examples

示例一:声明蓝牙与定位权限(清单文件)

<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" /> <!-- Dangerous Permissions -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Source: AndroidManifest.xml

注意 BLUETOOTH_SCAN 与 BLUETOOTH_CONNECT 注释为 "Dangerous Permissions"——它们必须在运行时动态申请,单纯声明无法在 Android 12+ 上获得授权。

示例二:多 flavor 构建注入密钥占位符

productFlavors {
    btsmart {
        ...
        addManifestPlaceholders([amap_key: "8a5a32e0e1b72bd104a68ceb976688d4"])
    }
    pilink {
        ...
        addManifestPlaceholders([amap_key: "7b12da60620e2fee98dfb00404f2825d"])
    }
}

Source: btsmart/build.gradle

清单中对应使用 ${amap_key} 占位符(高德地图 Key):

<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="${amap_key}" />

Source: AndroidManifest.xml

这种"占位符 + flavor 注入"的模式让同一套代码通过不同 applicationId、隐私政策 URL、地图 Key 打包成多个品牌应用,权限声明与业务代码完全复用。

Configuration Options

下表汇总本主题涉及的全部可配置项(来自 build.gradle 与 AndroidManifest.xml):

配置项类型默认值说明
compileSdkint36编译所用 SDK 版本,需 AGP 与 Android Studio 支持
minSdkint21最低支持 Android 5.0
targetSdkint35决定新版权限/前台服务行为
versionCodeint113126版本号(btsmart flavor)
versionNamestring"1.13.0"版本名
applicationIdstringcom.jieli.btsmart(pilink: com.jieli.pilink)包名,随 flavor 切换
multiDexEnabledbooleantrue开启 multidex,支撑 64K+ 方法数
abiFilterslistarmeabi-v7a, arm64-v8aSO 库架构过滤
sourceCompatibility / targetCompatibilityenumVERSION_1_8Java 8 语言特性
amap_key(manifestPlaceholder)stringflavor 各自注入高德地图 Key
user_agreement_url / app_privacy_policystring reshttps://cam.jieliapp.com/...用户协议/隐私政策 URL
update_resource_versionstring res113000OTA 资源版本号
OPEN_LAUNCHER_ANIM(BuildConfig)booleanbtsmart: true / pilink: false启动动画开关
requestLegacyExternalStoragebooleantrueAndroid 10/11 旧外部存储模式
usesCleartextTrafficbooleantrue允许明文 HTTP
foregroundServiceTypeenumconnectedDevice / location前台服务类型声明

Failure Modes、Edge Cases 与并发注意

典型失败场景

场景现象根因与对策
Android 12+ 无法扫描设备扫描回调无结果或 SecurityException未动态申请 BLUETOOTH_SCAN;需在运行时按版本分支申请
Android 11 及以下扫描无结果扫描静默失败定位权限未授权或系统"位置服务"开关关闭
Android 13+ 收不到推送通知通知不显示POST_NOTIFICATIONS 未动态申请
Android 14+ 前台服务崩溃ForegroundServiceStartNotAllowedException / SecurityException缺少对应 FOREGROUND_SERVICE_* 权限或未在清单声明 foregroundServiceType
悬浮窗不显示设备弹窗无法弹出SYSTEM_ALERT_WINDOW 为特殊权限,需跳设置页手动开启
通知栏设备弹窗无数据通知使用权未授权DevicePopDialog 是 NotificationListenerService,需用户手动开启"通知使用权"
x86 模拟器崩溃so 库加载失败abiFilters 不含 x86,需在 ARM 真机验证
安装被拒"设备不兼容"设备缺少 BLE/摄像头硬件能力(uses-feature required=true)

边界与一致性注意

  • 权限持久化:危险权限授权状态可被用户随时在设置中撤销,且 Android 11+ 存在"仅此一次"授权模式;应用应在每次执行扫描/连接前检查权限,而非假设一次申请终身有效。
  • 请求并发:系统同一时间只允许一个权限请求对话框,多个页面同时触发 requestPermissions 会导致部分请求被系统丢弃。建议在 MainApplication 或单例的权限管理器中串行化请求。
  • 多 flavor 一致性:btsmart 与 pilink 共用同一份 AndroidManifest.xml,但注入不同的 amap_key 与隐私政策地址;集成方新增 flavor 时必须同步注入占位符,否则清单合并失败。
  • tools:replace="android:allowBackup":通过 tools 命名空间强制覆盖依赖库中的同名属性,说明工程存在依赖冲突时清单合并的仲裁策略,修改时需谨慎。

扩展点与集成建议

  • 权限模型扩展:如集成方需要新增功能(如 BLUETOOTH_ADVERTISE 广播、NEARBY_WIFI_DEVICES 附近 Wi-Fi 设备),只需在 uses-permission 追加声明并在运行时申请,targetSdk 35 的框架已就绪。
  • flavor 扩展:参照 btsmart / pilink 结构新增 flavor,用 addManifestPlaceholders 注入各自的 applicationId、amap_key 与隐私政策链接即可复用全部权限与代码。
  • 国内 ROM 适配:小米/华为等 ROM 有额外的自启动、后台定位、省电策略限制,建议在权限引导之外增加"电池优化白名单"引导(REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 为可选扩展,当前工程未声明)。

Related Links

  • AndroidManifest.xml(完整权限清单)
  • btsmart/build.gradle(构建环境配置)
  • Android 官方文档:蓝牙权限
  • Android 官方文档:运行时权限
Next
集成SDK依赖