# bd_demo **Repository Path**: wxiot/bd_demo ## Basic Information - **Project Name**: bd_demo - **Description**: 北斗2.1标准协议SDK使用demo - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 6 - **Created**: 2026-02-17 - **Last Updated**: 2026-02-17 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 北斗通用协议库使用说明 ## 框架 ![](./img/1.png) > 1. 核心库负责从硬件端(蓝牙、串口等)接收数据,并处理接收数据,将数据解析成协议实体类Bean。同时负责将需要发送的指令转换成ByteArray,并向硬件端发送。当发送的指令带有回复指令监听,则在处理数据时将实体类Bean从监听中回传。 > 2. 硬件端,只需要继承HLBDClient,复写发送方法send,以及将收到的数据,传递给父类的handlerReceive方法即可,核心库将会自动对数据进行组包和解析。 > 3. 协议库负责定义各种各样的协议指令,可以直接使用注解标注,来快速定义数据解析方式,如果已有的解析方法不够符合使用,还能自定义解析规则。 ## 添加依赖 1. 首先将app/libs文件夹中的`HLBDCore-1.0.jar`、`BDProto2p1-1.0.jar`、`HLBluetoothLib-release-1.1(1).aar`添加您的项目的同样位置。 2. 在根目录的`build.gradle`中添加以下代码: ```groovy buildscript { dependencies { classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31" } } allprojects { repositories { google() mavenCentral() // 添加jitpack仓库 maven { url 'https://jitpack.io' } } } ``` Kts: ```kotlin buildscript { dependencies { classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.5.31") } } allprojects { repositories { google() mavenCentral() // 添加jitpack仓库 maven("https://jitpack.io") } } ``` 3. 在工程的`build.gradle`中添加以下代码: ```groovy plugins { id 'com.android.application' id 'kotlin-android' id 'kotlin-parcelize' id 'kotlin-kapt' } android { defaultConfig { multiDexEnabled true } compileOptions { coreLibraryDesugaringEnabled true sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } } dependencies { implementation fileTree(dir: "libs", include: ["*.jar"]) // Coroutines implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2' // 协程封装工具 implementation 'com.github.D10NGYANG:DLCoroutinesUtil:0.2' // 北斗协议解析核心库 implementation files('libs/HLBDCore-1.0.jar') // 标准2.1协议(必须搭配核心库使用) implementation files('libs/BDProto2p1-1.0.jar') // 北斗通讯蓝牙库(必须搭配核心库使用) implementation files('libs/HLBluetoothLib-release-1.1(1).aar') // 日期工具 implementation 'com.github.D10NGYANG:DLDateUtil:1.3' // 日期工具兼容Android8.0以下设备 coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' // 经纬度工具 implementation 'com.github.D10NGYANG:DLLatLngUtil:1.2' // 字符串字节数据工具 implementation 'com.github.D10NGYANG:DLStringUtil:1.12' } ``` kts: ```kotlin plugins { id("com.android.application") id("kotlin-android") id("kotlin-kapt") id("kotlin-parcelize") } android { defaultConfig { multiDexEnabled = true } compileOptions { isCoreLibraryDesugaringEnabled = true sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } } dependencies { implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar")))) // 北斗协议解析核心库 implementation(files("libs/HLBDCore-1.0.jar")) // 标准2.1协议(必须搭配核心库使用) implementation(files("libs/BDProto2p1-1.0.jar")) // 北斗通讯蓝牙库(必须搭配核心库使用) implementation(files("libs/HLBluetoothLib-release-1.1(1).aar")) // Coroutines implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.2") implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.5.2") // 协程封装工具 implementation("com.github.D10NGYANG:DLCoroutinesUtil:0.2") // 日期工具 implementation("com.github.D10NGYANG:DLDateUtil:1.3") // 日期工具兼容Android8.0以下设备 coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:1.1.5") // 字符串字节数据工具 implementation("com.github.D10NGYANG:DLStringUtil:1.12") // 经纬度工具 implementation("com.github.D10NGYANG:DLLatLngUtil:1.2") } ``` ## 蓝牙 > 蓝牙扫描必须条件如下: > > 1. 打开手机蓝牙; > 2. 打开位置信息开关; > 3. 授权定位权限; ### 打开手机蓝牙 1. 通过`BleManager.getInstance().isBlueEnable`返回的Boolean值确定手机蓝牙开关状态; ```java BleManager.getInstance().isBlueEnable(); ``` 2. 使用`BleManager.getInstance().enableBluetooth()`请求打开蓝牙; ```java BleManager.getInstance().enableBluetooth(); ``` ### 打开位置信息开关 1. 通过以下方法检查手机位置信息开关状态; kotlin: ```kotlin /** * 判断手机位置信息是否打开 * @return [Boolean] true:已打开; false:未打开; */ fun Context.isLocationServerEnabled(): Boolean { return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { val locationMode = Settings.Secure.getInt( contentResolver, Settings.Secure.LOCATION_MODE ) locationMode != Settings.Secure.LOCATION_MODE_OFF } else { val locationProviders = Settings.Secure.getString( contentResolver, Settings.Secure.LOCATION_PROVIDERS_ALLOWED ) !TextUtils.isEmpty(locationProviders) } } ``` java: ```java /** * 判断手机位置信息是否打开 * @param c * @return [Boolean] true:已打开; false:未打开; */ public boolean isLocationServerEnabled(Context c) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) { int locationMode = 0; try { locationMode = Settings.Secure.getInt(c.getContentResolver(), Settings.Secure.LOCATION_MODE); } catch (Settings.SettingNotFoundException e) { e.printStackTrace(); return false; } return locationMode != Settings.Secure.LOCATION_MODE_OFF; } else { String locationProviders = Settings.Secure.getString(c.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED); return !locationProviders.isEmpty(); } } ``` 1. 提示用户跳转到设置页面打开; ### 蓝牙模块初始化 相当于获取单例 kotlin: ```kotlin val ble: HLBleManager = HLBleManager.instance(application) ``` java: ```java HLBleManager ble = HLBleManager.instance(application); ``` ### 获取蓝牙状态 kotlin: ```kotlin val status: MutableLiveData = HLBleManager.instance(application).bleStatusLive ``` java: ```java MutableLiveData status = HLBleManager.instance(application).bleStatusLive; // 监听状态改变 status.observeForever(bleStatus -> { // 蓝牙状态更新 switch (bleStatus) { case CONNECTED: // 已连接 break; case CONNECTING: // 正在连接 break; case DISCONNECT: // 已断开连接 break; case DISABLE: // 已关闭 break; } }); // 获取当前状态 status.getValue(); ``` ### 设置打印开关 设置打印开关,打开将影响性能,推荐在正式打包时关闭 kotlin: ```kotlin ble.setLogEnable(true) ``` java: ```java ble.setLogEnable(true); ``` ### 判断蓝牙是否连接 是否已连接任意一个设备 kotlin: ```kotlin ble.isBleConnected() ``` java: ```java ble.isBleConnected(); ``` ### 扫描蓝牙设备 kotlin: ```kotlin /** * 扫描设备 * @return List */ suspend fun scanDevice(): List ``` java: ```java // 扫描蓝牙设备 ble.scanDevice(new Continuation>() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 List list = (List) o; } }); ``` ### 获取已经扫描到的设备列表 kotlin: ```kotlin val devices: MutableLiveData> = HLBleManager.instance(application).scanDeviceListLive ``` java: ```java MutableLiveData> devicesLive = ble.getScanDeviceListLive(); ``` ### 获取已经连接的蓝牙设备列表 kotlin: ```kotlin val devices: MutableLiveData> = HLBleManager.instance(application).connectedDeviceListLive ``` java: ```java MutableLiveData> devices = ble.getConnectedDeviceListLive(); ``` ### 连接蓝牙设备 1. 通过BleDevice连接: kotlin: ```kotlin /** * 连接设备 * @param device BleDevice * @return Boolean */ suspend fun connectDevice(device: BleDevice): Boolean ``` java: ```java ble.connectDevice(device, new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 boolean isSuccess = (boolean)o; } }); ``` 2. 通过蓝牙Mac地址连接: kotlin: ```kotlin /** * 连接设备 * @param mac String * @return Boolean */ suspend fun connectDevice(mac: String): Boolean ``` java: ```java ble.connectDevice("11:22:33:44", new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 boolean isSuccess = (boolean)o; } }); ``` ### 打开设备通知特征 这个方法需要在连接蓝牙设备后调用,也必须调用,否则会收到设备上报数据,只能下发数据。 kotlin: ```kotlin /** * 开启通知 * @param bleDevice BleDevice * @return Boolean */ suspend fun startNotify(bleDevice: BleDevice): Boolean ``` java: ```java ble.startNotify(scanList.getValue().get(0), new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 boolean isSuccess = (boolean)o; } }); ``` ### 连接设备完整流程 调用`connectDevice()`接口,连接`BleDevice`终端,连接成功后,需要调用`startNotify()`打开通知,完成这两部分就算连接成功了 kotlin: ```kotlin launchIO { val ble = HLBleManager.instance(application) // 连接终端 if (!ble.connectDevice(bleDevice)){ // 连接失败 return@launch } // 打开通知 if (!ble.startNotify(bleDevice)) { // 打开通知失败 return@launch } // 完全连接成功 ... } ``` java: ```java /** * 连接设备完整流程 * @param device */ public static void connectBleDevice(BleDevice device) { HLBleManager ble = HLBleManager.instance(MyApp.Companion.instance()); ble.connectDevice(device, getNewBoolContinuation(isSuccess -> { if (isSuccess) { // 连接成功,打开通知 ble.startNotify(device, getNewBoolContinuation(isNotifySuccess -> { if (isNotifySuccess) { // 完全连接成功 // todo } else { // 打开通知失败 } })); } else { // 连接失败 } })); } private static Continuation getNewBoolContinuation(ContinuationResume listener) { return new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { listener.resume((boolean)o); } }; } public interface ContinuationResume { void resume(T o); } ``` ### 更多蓝牙接口 参考文档:[https://github.com/Jasonchenlijian/FastBle/wiki](https://github.com/Jasonchenlijian/FastBle/wiki) ## 北斗标准2.1协议 > ble 为蓝牙实例 HLBleManager.instance(application) > > mac 为连接蓝牙设备的mac地址 ### 协议初始化 必须执行,建议在Application.onCreate中执行 kotlin: ```kotlin BDProto2p1.init() ``` java: ```java BDProto2p1.INSTANCE.init(); ``` ### CCICA- BDICI 读取北斗设备的加密模块信息 kotlin: ```kotlin launchIO { val bean: BDICI_Bean = BasicWorker2p1.ccica(ble, mac, CCICA_Bean( // 类型:读取本机 type = ICA_Type.READ_LOCAL )) } ``` java: ```java BasicWorker2p1.INSTANCE.ccica(ble, mac, new CCICA_Bean(), new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 BDICI_Bean bean = (BDICI_Bean) o; } }); ``` ### CCRMO 指令输出控制 kotlin: ```kotlin launchIO { val bean: BaseOutBean = BasicWorker2p1.ccrmo(ble, mac, CCRMO_Bean( // 参数标记 cmd = "BSI", // 模式 action = RMO_Action.OPEN, // CLOSE,CLOSE_ALL,OPEN_ALL // 输出频度(秒) frequency = 10 )) } ``` java: ```java BasicWorker2p1.INSTANCE.ccrmo(ble, mac, new CCRMO_Bean(), new Continuation() { @NonNull @Override public CoroutineContext getContext() { // 在IO线程进行 return Dispatchers.getIO(); } @Override public void resumeWith(@NonNull Object o) { // 得到结果 BaseOutBean bean = (BaseOutBean) o; // 判断是否发送成功 bean.isSuccess(); // 获取发送失败错误码 bean.getErrorType(); } }); ``` ### CCTXA-BDFKI 外设控制北斗设备向其他卡号的北斗设备发出通讯申请 kotlin: ```kotlin launchIO { val bean: BDFKI_Bean = BasicWorker2p1.cctxa(ble, mac, CCTXA_Bean( // 接收方地址 receiverAddress = "0240168", // 通讯类别 level = TXA_Level.NORMAL, // QUICK // 传输方式 type = TXA_Type.CODE, // CHINESE,MIX // 发送内容 content = "1234567890" )) } ``` java: 与`CCICA- BDICI 读取北斗设备的加密模块信息`类似,不再重复; ### CCDWA-BDFKI 外设控制北斗设备发送定位申请 kotlin: ```kotlin launchIO { val bean: BDFKI_Bean = BasicWorker2p1.ccdwA(ble, mac, CCDWA_Bean( // 接收方地址 receiverAddress = "0240168", // 定位模式 locationMode = DWA_LocationMode.NORMAL, // QUICK // 测高方式 type = DWA_Type.WITH_ALTITUDE, // NO_ALTITUDE,TYPE_1,TYPE_2 // 高程指示 heightMode = DWA_HeightMode.LOW, // HEIGHT // 高程数据(米) heightValue = 10.0, // 天线高度(米) antennaeHeight = 0.2, // 气压(帕) pressure = 1024.0, // 温度(度) temperature = 21.2, // 申请频度(秒) frequency = 10 )) } ``` java: 与`CCICA- BDICI 读取北斗设备的加密模块信息`类似,不再重复; ### 更多发送指令可以通过输入`BasicWorker2p1.(指令头)`尝试 ### 监听 【接收、发送】 协议指令 在任意一个class中注册监听器 kotlin: ```kotlin // 注册协议监听器 HLBDCore.register(this) ``` java: ```java HLBDCore.INSTANCE.register(this); ``` 记得在不需要使用后反注册,避免内存泄漏 kotlin: ```kotlin // 反注册 HLBDCore.unRegister(this) ``` 接着在同一个class中编写方法: kotlin: ```kotlin /** * 监听发出的指令 * @param client HLBDClient 发送指令的客户端 * @param device String 发出指令的设备,如果是蓝牙设备,则是蓝牙设备的mac地址 * @param raw ByteArray 发送的数据 * @param isCanAnalysis Boolean 是否能够解析 * @param proto BaseBDProto 解析出来的协议类型 * @param bean BaseInBean 解析出来的协议实体 */ @HLBDSend fun onHLSend( client: HLBDClient, device: String, raw: ByteArray, isCanAnalysis: Boolean, proto: BaseBDProto, bean: BaseInBean ) { when(proto) { Proto2p1Basic.TXA -> { // 发送TXA bean as CCTXA_Bean } } } /** * 监听接收的指令 * @param client HLBDClient 接收指令的客户端 * @param device String 发出指令的设备,如果是蓝牙设备,则是蓝牙设备的mac地址 * @param raw ByteArray 接收的数据 * @param isCanAnalysis Boolean 是否能够解析 * @param proto BaseBDProto 解析出来的协议类型 * @param bean BaseOutBean 解析出来的协议实体 */ @HLBDReceive fun onHLReceive( client: HLBDClient, device: String, raw: ByteArray, isCanAnalysis: Boolean, proto: BaseBDProto, bean: BaseOutBean ) { when(proto) { Proto2p1Basic.TXR -> { // 接收北斗短报文消息 bean as BDTXR_Bean } Proto2p1Basic.BSI -> { // 信号状态 bean as BDBSI_Bean } } } ``` java: ```java @HLBDSend public void onHLSend( HLBDClient client, String device, byte[] raw, boolean isCanAnalysis, BaseBDProto proto, BaseInBean bean ) { if (Proto2p1Basic.TXA == proto) { // 发送TXA CCTXA_Bean cctxa = (CCTXA_Bean) bean; } } @HLBDReceive public void onHLReceive( HLBDClient client, String device, byte[] raw, boolean isCanAnalysis, BaseBDProto proto, BaseOutBean bean ) { if (Proto2p1Basic.TXR == proto) { // 接收北斗短报文消息 BDTXR_Bean bdtxr = (BDTXR_Bean) bean; } else if (Proto2p1Basic.BSI == proto) { // 信号状态 BDBSI_Bean bdbsi = (BDBSI_Bean) bean; } } ```