您当前的位置:首页 > 互联网教程

安卓BLE知识及EasyBle的使用

发布时间:2025-05-17 07:30:54    发布人:远客网络

安卓BLE知识及EasyBle的使用

一、安卓BLE知识及EasyBle的使用

BLE(Bluetooth low energy)蓝牙低功耗是蓝牙4.0新增的子规范,其具有低能耗、低成本、低延迟、传输距离长等特点,自安卓4.3(api level 18)起,安卓开始支持BLE。BLE与经典蓝牙对比如下图():

在讲链接参数之前,需要先了解连接事件Connection Events

1)Conection Events(连接事件)

蓝牙设备建立连接后,所有信息的交换都是通过Connetion Events进行的,主设备在Connection Events开始起发送数据包,从属设备在Connection Events期间回复。Connection Events是周期性出现的且时间间隔很短,在一个Connection Events中,器件最大电流为十几mA,平均电流1uA,这便是BLE功耗较低的原因。Connection Events如下图()

在两个蓝牙设备建立连接进入连接状态前,蓝牙设备需要设置一系列的链接参数,链接参数是在中心设备向外围设备发起连接请求时传递的:

当外围设备认为中心设备请求的链接参数不合适时,外围设备可在连接期间发送一个 Connetion Parameter UpdateRequest请求中心设备更改链接参数。当中心设备收到请求时可接受或拒绝外围设备的链接参数更新请求

GATT层级图如下(图片来自蓝牙官网)

MTU(Maximum Transmission Unit):即数据的最大传输单元。具体是指一个Chracteristic一次性可传输的数据大小。

蓝牙核心规范(core spec)中定义了ATT的默认MTU为23byte,除去ATT的opcode一个字节以及ATT的handle2个字节之后,剩下的20个字节便是留给GATT的了。由于ATT的最大长度为512byte,故一般认为MTU的最大长度为512个byte。

注:core spec规定每一个设备都必须支持MTU为23。

用系统api开发参见安卓BLE开发官方文档

这里介绍使用第三方库 EasyBle快速开发BLE

1)判断设备是否支持BLE并打开蓝牙

安卓版本不小于6.0的,扫描必须要有定位权限,若版本为Android10及以上,则需精确定位权限(即 Manifest.permission.ACCESS_FINE_LOCATION)

当需要结束扫描时用以下方法结束扫描,建议在扫描到目标设备后停止扫描

当需要断开与设备的连接时可使用以下任一方法断开设备连接

notify和indicate都使用以下方法

当需要取消notify或indicate时调用以下方法

如果一次性写入的数据长度大于MTU即最大传输单元(默认是20字节),则可以使用下列方法进行分批写入

当结束BLE通信时不要忘了调用destroy

二、为什么安卓6.0需要开启定位才能搜索蓝牙ble设备

Android6.0以后,权限进行了改动。

在Android 6.0,原来的蓝牙功能,发现扫描蓝牙设备时,无法获取到蓝牙设备;因为在6.0后,蓝牙这块增加一个动态权限;需要在程序中动态申请。

6.0及后续版本,使用蓝牙扫描,来需要添加如下的权限,且该权限还需要在使用时动态申请:

<!-- Android6.0蓝牙扫描才需要-->

<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION"/>

if(ContextCompat.checkSelfPermission(this,

Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){

ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},

MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);

//判断是否需要向用户解释,为什么要申请该权限

if(ActivityCompat.shouldShowRequestPermissionRationale(this,

Manifest.permission.READ_CONTACTS)){

Toast.makeText(this,"shouldShowRequestPermissionRationale", Toast.LENGTH_SHORT).show();

public void onRequestPermissionsResult(int requestCode,@NonNull String[] permissions,@NonNull int[]

super.onRequestPermissionsResult(requestCode, permissions, grantResults);

三、安卓开发怎么获取在内置存储文件的创建者

首先定义一个路径变量(这里我直接赋值为后面的方法):

privateStringsdcardDir=getSDCardPath();

然后写一个获取获取路径的方法:

然后写一个获取获取路径的方法:

FilesdcardDir=null;//判断SDCard是否存在

booleansdcardExist=Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED);if(sdcardExist){

sdcardDir=Environment.getExternalStorageDirectory();

}

2.获取SDCard中文件的路径

①在上方已有方法的基础上,定义一个变量:

privateStringfilePath=getSDCardPath()+"/"+"file/test.ble/";

这里的file是文件所在文件夹的名字,test.ble为文件名。

这里的file是文件所在文件夹的名字,test.ble为文件名。

或者,也可以直接定义文件路径,然后写get方法,但是我在测试时,有时会报出异常,目前还没有分析出是不是这样写的问题,还是别的地方的代码出了问题…