Android BLE核心库使用

一、添加蓝牙库依赖

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
}

九、结语

蓝牙的基本操作,库里都有了,应付开发已经足够。

点击查看源码

猜你喜欢

转载自blog.csdn.net/fszeng2011/article/details/80999342