Android BLE开发: BLE Peripheral开发流程

2024-06-03 17:58

本文主要是介绍Android BLE开发: BLE Peripheral开发流程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Android从lolipop开始支持了BLE Peripheral开发。网上也有关于Framework的文章。真的关于应用开发的确不多,google官网也只给出了一个Central的Demo。之前做了一个BLE Peripheral的Demo,这里将Peripheral开发的一些流程简单整理一下。不多说,直接上代码。

初始化

//初始化BluetoothManager和BluetoothAdapter
if(mBluetoothManager == null)mBluetoothManager = (BluetoothManager) mActivity.getSystemService(Context.BLUETOOTH_SERVICE);if (mBluetoothManager != null && mBluetoothAdapter == null) {mBluetoothAdapter = mBluetoothManager.getAdapter();
}//打开蓝牙的套路
if ((mBluetoothAdapter == null) || (!mBluetoothAdapter.isEnabled())) {Toast.makeText(mActivity, R.string.bt_unavailable, Toast.LENGTH_SHORT).show();Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);mActivity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

开始广播

//获取BluetoothLeAdvertiser,BLE发送BLE广播用的一个API
if (mBluetoothAdvertiser == null) {mBluetoothAdvertiser = mBluetoothAdapter.getBluetoothLeAdvertiser();
}
//创建BluetoothGattServerCallback,
//MockServerCallBack这个类继承自BluetoothGattServerCallback
//后面会贴出MockServerCallBack这个类的代码
//BluetoothGattServerCallback这个回调类主要是一些BLE读写的接口
//关于BLE读写的操作都在这个Callback中完成
if (mBluetoothAdvertiser != null) {mMockServerCallBack = new MockServerCallBack(mActivity);//打开BluetoothGattServermGattServer = mBluetoothManager.openGattServer(mActivity, mMockServerCallBack);if(mGattServer == null){Log.d(TAG , "gatt is null");}try{mMockServerCallBack.setupServices(mGattServer);//创建BLE Adevertising并且广播mBluetoothAdvertiser.startAdvertising(createAdvSettings(true, 0), createFMPAdvertiseData(),mAdvCallback);}catch(InterruptedException e){Log.v(TAG, "Fail to setup BleService");}
}

创建Advertising

public static AdvertiseSettings createAdvSettings(boolean connectable, int timeoutMillis) {AdvertiseSettings.Builder builder = new AdvertiseSettings.Builder();//设置广播的模式,应该是跟功耗相关builder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_BALANCED);builder.setConnectable(connectable);builder.setTimeout(timeoutMillis);builder.setTxPowerLevel(AdvertiseSettings.ADVERTISE_TX_POWER_HIGH);return builder.build();
}//设置一下FMP广播数据
public static AdvertiseData createFMPAdvertiseData() {AdvertiseData.Builder builder = new AdvertiseData.Builder();builder.setIncludeDeviceName(true);AdvertiseData adv = builder.build();return adv;
}//发送广播的回调,onStartSuccess/onStartFailure很明显的两个Callback
private AdvertiseCallback mAdvCallback = new AdvertiseCallback() {public void onStartSuccess(android.bluetooth.le.AdvertiseSettings settingsInEffect) {if (settingsInEffect != null) {Log.d(TAG, "onStartSuccess TxPowerLv="+ settingsInEffect.getTxPowerLevel()+ " mode=" + settingsInEffect.getMode()+ " timeout=" + settingsInEffect.getTimeout());} else {Log.d(TAG, "onStartSuccess, settingInEffect is null");}}public void onStartFailure(int errorCode) {Log.d(TAG, "onStartFailure errorCode=" + errorCode);};
};

BLE需要的BluetoothGattServerCallback

import android.app.Activity;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattServer;
import android.bluetooth.BluetoothGattServerCallback;
import android.bluetooth.BluetoothGattService;
import android.util.Log;public class MockServerCallBack extends BluetoothGattServerCallback {private static final String TAG = "BleServer";private byte[] mAlertLevel = new byte[] {(byte) 0x00};private Activity mActivity;private HomePager mHomepager;private boolean mIsPushStatic = false;private BluetoothGattServer mGattServer;private BluetoothGattCharacteristic mDateChar;private BluetoothDevice btClient;private BluetoothGattCharacteristic mHeartRateChar;private BluetoothGattCharacteristic mTemperatureChar;private BluetoothGattCharacteristic mBatteryChar;private BluetoothGattCharacteristic mManufacturerNameChar;private BluetoothGattCharacteristic mModuleNumberChar;private BluetoothGattCharacteristic mSerialNumberChar;public void setupServices(BluetoothGattServer gattServer) throws InterruptedException{if (gattServer == null) {throw new IllegalArgumentException("gattServer is null");}mGattServer = gattServer;// 设置一个GattService以及BluetoothGattCharacteristic { //immediate alertBluetoothGattService ias = new BluetoothGattService( UUID.fromString(IMXUuid.SERVICE_IMMEDIATE_ALERT),BluetoothGattService.SERVICE_TYPE_PRIMARY);//alert level char.BluetoothGattCharacteristic alc = new BluetoothGattCharacteristic(UUID.fromString(IMXUuid.CHAR_ALERT_LEVEL),BluetoothGattCharacteristic.PROPERTY_READ |BluetoothGattCharacteristic.PROPERTY_WRITE | BluetoothGattCharacteristic.PROPERTY_NOTIFY ,BluetoothGattCharacteristic.PERMISSION_READ |BluetoothGattCharacteristic.PERMISSION_WRITE);alc.setValue("");ias.addCharacteristic(alc);if(mGattServer!=null && ias!=null)mGattServer.addService(ias);}}//当添加一个GattService成功后会回调改接口。public void onServiceAdded(int status, BluetoothGattService service) {if (status == BluetoothGatt.GATT_SUCCESS) {Log.d(TAG, "onServiceAdded status=GATT_SUCCESS service=" + service.getUuid().toString());} else {Log.d(TAG, "onServiceAdded status!=GATT_SUCCESS");}}//BLE连接状态改变后回调的接口public void onConnectionStateChange(android.bluetooth.BluetoothDevice device, int status,int newState) {Log.d(TAG, "onConnectionStateChange status=" + status + "->" + newState);}//当有客户端来读数据时回调的接口public void onCharacteristicReadRequest(android.bluetooth.BluetoothDevice device,int requestId, int offset, BluetoothGattCharacteristic characteristic) {Log.d(TAG, "onCharacteristicReadRequest requestId=" + requestId + " offset=" + offset);mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset,characteristic.getValue());}//当有客户端来写数据时回调的接口@Overridepublic void onCharacteristicWriteRequest(android.bluetooth.BluetoothDevice device,int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite,boolean responseNeeded, int offset, byte[] value) {mGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, null);}//当有客户端来写Descriptor时回调的接口@Overridepublic void onDescriptorWriteRequest (BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {btClient = device;Log.d(TAG, "onDescriptorWriteRequest");// now tell the connected device that this was all successfullmGattServer.sendResponse(device, requestId, BluetoothGatt.GATT_SUCCESS, offset, value);}
}

至此,BLE Peripheral发送广播所需要的工作都完成了,并且当有Central设备读写该Peripheral设备时候也能通过BluetoothGattServerCallback回调到。

停止广播

//关闭BluetoothLeAdvertiser,BluetoothAdapter,BluetoothGattServer 
if (mBluetoothAdvertiser != null) {mBluetoothAdvertiser.stopAdvertising(mAdvCallback);mBluetoothAdvertiser = null;
}if(mBluetoothAdapter != null){mBluetoothAdapter = null;
}if (mGattServer != null) {mGattServer.clearServices();mGattServer.close();
}       

这样,Android设备就停止了BLE的广播,外部的Central设备就搜索不到该设备并且连接上它了。
BLE Peripheral的API乍一看有些多,其实仔细理一理非常简单,工作重点在于那个Callback的编写。

这篇关于Android BLE开发: BLE Peripheral开发流程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1027704

相关文章

Android Mainline基础简介

《AndroidMainline基础简介》AndroidMainline是通过模块化更新Android核心组件的框架,可能提高安全性,本文给大家介绍AndroidMainline基础简介,感兴趣的朋... 目录关键要点什么是 android Mainline?Android Mainline 的工作原理关键

如何解决idea的Module:‘:app‘platform‘android-32‘not found.问题

《如何解决idea的Module:‘:app‘platform‘android-32‘notfound.问题》:本文主要介绍如何解决idea的Module:‘:app‘platform‘andr... 目录idea的Module:‘:app‘pwww.chinasem.cnlatform‘android-32

使用Python开发一个带EPUB转换功能的Markdown编辑器

《使用Python开发一个带EPUB转换功能的Markdown编辑器》Markdown因其简单易用和强大的格式支持,成为了写作者、开发者及内容创作者的首选格式,本文将通过Python开发一个Markd... 目录应用概览代码结构与核心组件1. 初始化与布局 (__init__)2. 工具栏 (setup_t

Android实现打开本地pdf文件的两种方式

《Android实现打开本地pdf文件的两种方式》在现代应用中,PDF格式因其跨平台、稳定性好、展示内容一致等特点,在Android平台上,如何高效地打开本地PDF文件,不仅关系到用户体验,也直接影响... 目录一、项目概述二、相关知识2.1 PDF文件基本概述2.2 android 文件访问与存储权限2.

Spring Shell 命令行实现交互式Shell应用开发

《SpringShell命令行实现交互式Shell应用开发》本文主要介绍了SpringShell命令行实现交互式Shell应用开发,能够帮助开发者快速构建功能丰富的命令行应用程序,具有一定的参考价... 目录引言一、Spring Shell概述二、创建命令类三、命令参数处理四、命令分组与帮助系统五、自定义S

Android Studio 配置国内镜像源的实现步骤

《AndroidStudio配置国内镜像源的实现步骤》本文主要介绍了AndroidStudio配置国内镜像源的实现步骤,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,... 目录一、修改 hosts,解决 SDK 下载失败的问题二、修改 gradle 地址,解决 gradle

在Android平台上实现消息推送功能

《在Android平台上实现消息推送功能》随着移动互联网应用的飞速发展,消息推送已成为移动应用中不可或缺的功能,在Android平台上,实现消息推送涉及到服务端的消息发送、客户端的消息接收、通知渠道(... 目录一、项目概述二、相关知识介绍2.1 消息推送的基本原理2.2 Firebase Cloud Me

Python通过模块化开发优化代码的技巧分享

《Python通过模块化开发优化代码的技巧分享》模块化开发就是把代码拆成一个个“零件”,该封装封装,该拆分拆分,下面小编就来和大家简单聊聊python如何用模块化开发进行代码优化吧... 目录什么是模块化开发如何拆分代码改进版:拆分成模块让模块更强大:使用 __init__.py你一定会遇到的问题模www.

Spring Security基于数据库的ABAC属性权限模型实战开发教程

《SpringSecurity基于数据库的ABAC属性权限模型实战开发教程》:本文主要介绍SpringSecurity基于数据库的ABAC属性权限模型实战开发教程,本文给大家介绍的非常详细,对大... 目录1. 前言2. 权限决策依据RBACABAC综合对比3. 数据库表结构说明4. 实战开始5. MyBA

使用Python开发一个简单的本地图片服务器

《使用Python开发一个简单的本地图片服务器》本文介绍了如何结合wxPython构建的图形用户界面GUI和Python内建的Web服务器功能,在本地网络中搭建一个私人的,即开即用的网页相册,文中的示... 目录项目目标核心技术栈代码深度解析完整代码工作流程主要功能与优势潜在改进与思考运行结果总结你是否曾经