一、添加蓝牙库依赖
dependencies {
implementation 'com.github.fszeng2011:blecore:2.3.0'
implementation 'org.greenrobot:eventbus:3.1.1'
}
二、AndroidManifest.xml配置权限
在Android6.0后需要定位权限,否则搜索不到蓝牙设备,关于6.0动态申请权限,这里就不再写了,自行百度吧。
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
三、配置
Ble.getInstance().configuration.setPackageSize(20)//分包大小
.setBondController { device ->
//连接时配对控制
device.name.startsWith("zfs")
}
.setConnectTimeoutMillis(8000)//连接超时时间
.setDiscoverServicesDelayMillis(500)//连接成功后延时执行发现服务操作的时间
.setScanHandler { device, scanRecord ->
//扫描过滤器,符合规则的才会在扫描回调中
device.name.startsWith("zfs")
}
.setTryReconnectTimes(3)//尝试重连的次数,默认无限重连
.setScanPeriodMillis(10000)//扫描周期
.setUseBluetoothLeScanner(true)//是否使用新版api的扫描器
.setWaitWriteResult(true)//写入时是否等待写入回调后再写下一包
.setPackageWriteDelayMillis(10)//每包的写入延时
.setRequestWriteDelayMillis(10)//第个请求延时
四、初始化蓝牙库(必须先初始化,否则无法进行其他操作!)
//初始化蓝牙
Ble.getInstance().initialize(context, new BleInitCallback());
private class BleInitCallback implements InitCallback {
@Override
public void onSuccess() {
//初始化成功,在此作后续操作,如搜索
}
@Override
public void onFail(int errorCode) {
switch (errorCode) {
case ERROR_NOT_SUPPORT_BLE: //不支持BLE
break;
case ERROR_INIT_FAIL: //BluetoothManager初始化失败
break;
case ERROR_LACK_PERMISSION: //缺少相应权限,如定位
break;
}
}
}
当不再使用蓝牙库了,可以释放,释放后需要再次重新初始化!
Ble.getInstance().release(context);
五、搜索设备
设置搜索结果回调:
//回调结果均在主线程
Ble.getInstance().addScanListener(new ScanListener() {
@Override
public void onScanStart() {//扫描开始
}
@Override
public void onScanStop() {//扫描结束
}
@Override
public void onScanResult(@NonNull Device device) {//扫描结果
}
});
开始搜索:
Ble.getInstance().startScan(context);
停止搜索:
Ble.getInstance().stopScan();
六、数据传递说明
蓝牙库使用了EventBus框架,数据通过此框架传输,因此各种状态及数据的接收需要订阅相应的事件。
注册订阅者,在实例中调用如下方法(如:Activity的onCreate方法中):
Ble.getInstance().registerSubscriber(this);
取消订阅,在注册时的实例中调用如下方法(如:Activity的onDestroy方法中):
Ble.getInstance().unregisterSubscriber(this);
订阅事件,在相应方法上加上@Subscribe注解,事件回调线程可通过@Subscribe(threadMode = ThreadMode.MAIN)中的threadMode 控制。线程模式说明:
ThreadMode.MAIN:UI线程,不加入队列
ThreadMode.MAIN_ORDERED:UI线程,加入队列
ThreadMode.POSTING:事件发布的线程
ThreadMode.BACKGROUND:后台线程。如果事件发布在子线程,则直接回调,如果事件发布在UI线程,则使用线程池执行回调
ThreadMode.ASYNC:异步线程,既不在发布线程,也不在UI线程。直接使用线程池回调
七、连接
建立连接:
//第一个参数:上下文;第二个参数:搜索到的设备;第三个参数:是否自动重连
Ble.getInstance().connect(context, device, true, listener);
断开连接:
//仍在蓝牙库的集合中,可手动重连
Ble.getInstance().disconnectConnection(device);
释放连接:
//已从蓝牙库集合中移除,必须重新建立连接
Ble.getInstance().releaseConnection(device);
连接状态监听:
@Subscribe(threadMode = ThreadMode.MAIN)
public void onConnectionStateChanged(Events.ConnectionStateChanged event) {
switch (event.state) {
case Connection.STATE_DISCONNECTED://连接断开
break;
case Connection.STATE_CONNECTING://连接中...
break;
case Connection.STATE_RECONNECTING://正在重连...
break;
case Connection.STATE_CONNECTED://连接成功,未搜索服务
break;
case Connection.STATE_SERVICE_DISCORVERING://连接成功,正在搜索服务...
break;
case Connection.STATE_SERVICE_DISCORVERED://连接成功,并搜索到服务
break;
case Connection.STATE_RELEASED://连接已释放
break;
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onConnectTimeout(Events.ConnectTimeout event) {
switch (event.type) {
case Connection.TIMEOUT_TYPE_CANNOT_DISCOVER_DEVICE://搜索不到设备
break;
case Connection.TIMEOUT_TYPE_CANNOT_CONNECT://连接不上
break;
case Connection.TIMEOUT_TYPE_CANNOT_DISCOVER_SERVICES://发现不了服务
break;
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onConnectFailed(Events.ConnectFailed event) {
//连接失败,event.type失败类型
}
八、操作
获取当前连接:
Connection connection = Ble.getInstance().getConnection(device);
//or
Connection connection = Ble.getInstance().getConnection(addr);
读特征值:
connection.readCharacteristic(requestId, serviceUuid, characteristicUuid);
写特征值:
connection.writeCharacteristic(requestId, serviceUuid, characteristicUuid, bytes);
开关notifycation
connection.toggleNotification(requestId, serviceUuid, characteristicUuid, true);//开
connection.toggleNotification(requestId, serviceUuid, characteristicUuid, false);//关
各请求结果监听
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRequestFialed(Events.RequestFailed event) {
//请求失败
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onCharacteristicRead(Events.CharacteristicRead event) {
//读到特征值
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onNotificationChanged(Events.NotificationChanged event) {
//notification开启或关闭成功
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onCharacteristicChanged(Events.CharacteristicChanged event) {
//notification数据
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDescriptorRead(Events.DescriptorRead event) {
//读取到descriptor
}
@Subscribe(threadMode = ThreadMode.BACKGROUND)
public void onCharacteristicWrite(Events.CharacteristicWrite event) {
//写入成功
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onMtuChanged(Events.MtuChanged event) {
//MTU修改成功
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onRemoteRssiRead(Events.RemoteRssiRead event) {
//读取到rssi
}
九、结语
蓝牙的基本操作,库里都有了,应付开发已经足够。