Android中使用BluetoothKit

最近接触到了和硬件之间的蓝牙交互,有一套Google给的代码,总来的说使用起来太过冗长,封装过程略微复杂。找到一个三方的框架BluetoothKit.

这个蓝牙框架使用起来较为简单。使用方法也较为简洁明了。但是BluetoothKit不能用在经典蓝牙身上,它只支持经典蓝牙的SPP搜索,并不能支持经典蓝牙的连接。而它只支持BLE设备的操作。

  • GATT协议

    在Android4.3(API 18)以上的设备几乎都是BLE。BLE的协议是GATT协议,关于GATT协议,我们需要了解几个关键的词汇:

    ①Profile:一个标准的通信协议,存在于从机中,蓝牙有一些规范的Profile,如:HID(人机交互设备),OVER(基于蓝牙的IPV6组网方式),心率计等。每个Profile中会包含多个Service,每个Service代表从机的一个能力。

    ②Service:在Ble从机中,有很多服务,比如:电量信息服务,系统信息服务等。一个service包含多个characteristic特征值。获取的信息值存放在从机的Profile的Characteristic。然后主机通过characteristic来获取信息数据。所以说,通信最主要的还是Characteristic。

    ③Characteristic:特征。读写内容都是通过Characteristic来进行的。

    ④UUID:统一标识码,Service和Characteristic都有自己的唯一UUID。

    蓝牙协议图大致如下:

  • BluetoothKit框架的一些介绍和使用方法

       BluetoothKit提供:连接,读写,通知等接口。

       会自动断开不活跃的蓝牙设备。

       BluetoothKit的使用方法:

1.添加依赖  两种方式: ①在gradle中添加compile 'com.inuker.bluetooth:library:1.3.8'   ②导入依赖Library模块

2.添加蓝牙权限

<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" />

3.扫描蓝牙

private void searchDevice() {
        SearchRequest request = new SearchRequest.Builder().searchBluetoothLeDevice(5000,2).searchBluetoothLeDevice(5000).build();
        ClientManager.getClient().search(request, mSearchResponse);
    }

    private final SearchResponse mSearchResponse = new SearchResponse() {
        @Override
        public void onSearchStarted() {
                 //开始扫描,可以在此加入一些状态设置。以及一些数据清空处理。
                 mDevices.clear();
        }

        @Override
        public void onDeviceFounded(SearchResult device) {
            //监测扫描出的设备是否已经包含在设备数组里
            if (!mDevices.contains(device)) {
                mDevices.add(device);
                //给设备Adapter设值
                mAdapter.setDataList(mDevices);
            }

            if (mDevices.size() > 0) {
                mRefreshLayout.showState(AppConstants.LIST);
            }
        }

        @Override
        public void onSearchStopped() {
            BluetoothLog.w("MainActivity.onSearchStopped");
            mListView.onRefreshComplete(true);
            mRefreshLayout.showState(AppConstants.LIST);
        }

        @Override
        public void onSearchCanceled() {
            BluetoothLog.w("MainActivity.onSearchCanceled");
            mListView.onRefreshComplete(true);
            mRefreshLayout.showState(AppConstants.LIST);
        }
    };

4.连接蓝牙

 private void connectDevice() {
        BleConnectOptions options = new BleConnectOptions.Builder()
                .setConnectRetry(3)//重试3次
                .setConnectTimeout(5000)//5s后为连接超时
                .setServiceDiscoverRetry(3)//连接Service重试3次
                .setServiceDiscoverTimeout(5000)//5s后连接'服务'超时
                .build();
        //此处单例出BluetoothClient对象来进行连接操作
        ClientManager.getClient().connect(mMac, options, new BleConnectResponse() {
            @Override
            public void onResponse(int code, BleGattProfile profile) {
                //如果连接没有成功,则重试。
                if (code == REQUEST_SUCCESS) {
                    setGattProfile(profile);
                }else{
                    //检测是否需要连接设备(如果已经连接,则不需要再去连接)
                    connectDeviceIfNeeded();
                }
            }
        });
 }

//获取属性
public void setGattProfile(BleGattProfile profile) {
        List<DetailItem> items = new ArrayList<DetailItem>();
        List<BleGattService> services = profile.getServices();

        for (BleGattService service : services) {
            items.add(new DetailItem(DetailItem.TYPE_SERVICE, service.getUUID(), service.getUUID()));
            List<BleGattCharacter> characters = service.getCharacters();
            for (BleGattCharacter character : characters) {
                items.add(new DetailItem(DetailItem.TYPE_CHARACTER, character.getUuid(), service.getUUID()));
            }
        }
        //将得到的items传递到需要发送信息的位置。DetailItem是service和character的实体。
        //上面我们就提到过,蓝牙间的消息传递获取是根据service的character来做到的。
}

//蓝牙的状态监听
ClientManager.getClient().registerConnectStatusListener(macAddress, mBleConnectStatusListener);
private final BleConnectStatusListener mBleConnectStatusListener = new BleConnectStatusListener() {
    @Override
    public void onConnectStatusChanged(String macAddress, int status) {

        if (status == STATUS_CONNECTED) {
        //蓝牙设备处于连接状态
        } else if (status == STATUS_DISCONNECTED) {
        //蓝牙设备断开
        }

    }
};

//注销蓝牙状态监听
ClientManager.getClient().unregisterConnectStatusListener(macAddress, mBleConnectStatusListener);

5.蓝牙硬件通信

private List<DetailItem> mDeviceDetailDataList = new ArrayList<>();
public void setDeviceDetailDataList(List<DetailItem> datas) {
        mDeviceDetailDataList.clear();
        //加入最新的service和character数据
        mDeviceDetailDataList.addAll(datas);
        BaseLoginBean baseLoginBean=loginCheck(mDeviceDetailDataList);
        mService=baseLoginBean.getmService();
        mCharacter=baseLoginBean.getmCharacter();
        //写数据到蓝牙设备。需要得知要操作设备的mac,要操作的service和character,
        //以及要传输给蓝牙设备的信息。以及传输回调。
        ClientManager.getClient().write(macAddress, mService, mCharacter, baseLoginBean.getmBytes(), mWriteRsp);
        //将蓝牙设备传递给我们的信息进行提示返回。需要得知要操作设备的mac,
        //要操作的service和character,以及返回的信息回调。
        ClientManager.getClient().notify(mMac, mService, mCharacter, mNotifyRsp);
}

在读取的时候还有一种read方法。read方法和notify有什么不一样的呢?

notify:有点类似于推送的意思,不管自己去不去读取蓝牙返回给我们的信息。始终都会得到蓝牙返回给的信息。

unnotify:不获取返回信息。

read:用户自己去获取数据,自己要获取的时候才去获取数据。

除此writeNoRsp:凡是带有WRITE_TYPE_NO_RESPONSE标识的,速率比write快2~3倍。建议用于固件升级。

writeDescriptor:对Characteristic的描述,如:范围,计量单位等。同理readDescriptor则是读取。

indicate:和notify类似。 unindicate则是不获取返回信息。

readRssi:读取蓝牙强度。                                              

 6.断开蓝牙

ClientManager.getClient().disconnect(macAddress);

Tips:

1.在某个蓝牙设备disconnect()后,再去调用该蓝牙的disconnect。依然会执行到蓝牙状态回调去。

2.使用notify的时候最好不要在一个界面去复用多次,可能会出现重复调用情况,导致notify回调逻辑混乱。

猜你喜欢

转载自blog.csdn.net/sweet_smile5/article/details/81631439