Android BLE控制端

来源:互联网 发布:手机淘宝购买运费险 编辑:程序博客网 时间:2024/06/06 10:55

简介

Android手机可以通过BLE的方式与设备进行通信,其中5.0以上的系统还可以模拟设备端,具体可以参见我的博客
http://blog.csdn.net/hbdatouerzi/article/details/74935869
对于BLE的控制端,大致的流程为:
打开蓝牙–搜索设备–连接–获取服务和特征值–对特征值进行读写

以下是我写的一个demo,可以搜索设备,点击设备可以进入到特征值的界面,然后对特征值进行读写。
这里写图片描述

这里写图片描述

开发步骤

1.初始化

获取蓝牙服务

bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);mBluetoothAdapter = bluetoothManager.getAdapter();

2.设置扫描设备的回调

leScanCallback只有一个回调函数,当扫描到设备之后就会调用onLeScan

    public interface LeScanCallback {        void onLeScan(BluetoothDevice var1, int var2, byte[] var3);    }

3.扫描设备

使用BluetoothAdapter的startLeScan方法扫描,当扫描到设备之后会自动调取LeScanCallback回调函数

    //扫描设备    @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)    public void scanLeDevice(final boolean enable) {        if(scanCallback == null){            LogUtil.getInstance().ilog(TAG,"扫描失败 scanCallback为空");            return;        }        if (enable) {            mScanning = true;            LogUtil.getInstance().ilog(TAG,"开始扫描设备");            mBluetoothAdapter.startLeScan(scanCallback);        } else {            mScanning = false;            LogUtil.getInstance().ilog(TAG,"停止扫描设备");            mBluetoothAdapter.stopLeScan(scanCallback);        }    }

4.ble操作的回调函数

当扫描到设备之后,便可以连接设备,获取设备的服务等操作,在这些操作之前,先要设置好操作的回调函数。
BluetoothGattCallback为ble操作的回调,是一个抽象类,我们可以继承它,然后复写感兴趣的回调就可以了。

//ble操作的回调public class BTControlCallBack extends BluetoothGattCallback {    private String tag = "BTControlCallBack";    private WifiConfigViewI configView;    private SendCallBack sendCallBack;//发送数据的回调    private int failedNum;// 发送失败的次数,超过容忍的次数,则这次交互失败    public BTControlCallBack(WifiConfigViewI configView){        this.configView = configView;        failedNum = 0;    }    public void setSendCallBack(SendCallBack sendCallBack){        this.sendCallBack = sendCallBack;    }    //连接状态改变    @Override    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {        super.onConnectionStateChange(gatt, status, newState);        if(newState == 2){            LogUtil.getInstance().ilog(tag,"已连接状态");            configView.connectState(true);            gatt.discoverServices();//搜索服务        }else{            LogUtil.getInstance().ilog(tag,"断开连接状态");            configView.connectState(false);        }    }    //发现服务    @Override    public void onServicesDiscovered(BluetoothGatt gatt, int status) {        super.onServicesDiscovered(gatt, status);        configView.onServiceFind(gatt);    }    //读回调    @Override    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {        super.onCharacteristicRead(gatt, characteristic, status);        LogUtil.getInstance().ilog(tag,"调用了读回调");    }    //写回调    @Override    public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {        super.onCharacteristicWrite(gatt, characteristic, status);        if(status == BluetoothGatt.GATT_SUCCESS) {            if(sendCallBack!=null){                sendCallBack.sendSuccess();                failedNum = 0;            }            LogUtil.getInstance().ilog(tag, "写成功 status="+status);        }else{            failedNum ++;            if(sendCallBack!=null){                if(failedNum >= Constant.MaxFailedNum){//整个失败                    sendCallBack.sendTotallyFailed();                }else {                    sendCallBack.sendFailed();//单条失败,重发                }            }            configView.configFailed();            LogUtil.getInstance().ilog(tag, "写失败 status="+status);        }    }}

5.连接设备

获取到设备之后,只需要一句代码就可以连接了。
连接成功之后,会返回一个BluetoothGatt对象,通过这个对象,可以对设备的特征值进行读写。
连接设备成功之后,需要在相应的回调函数里面去搜索服务。

    public void connect(final BluetoothDevice device){        //gattCallback为ble操作的回调        mBluetoothGatt = device.connectGatt(context, false, gattCallback);    }

6.发现服务和特征值

调用gatt.discoverServices()之后,发现了服务会去调用
onServicesDiscovered(BluetoothGatt gatt, int status)函数。
以下可以获取到服务列表以及对应的特征值。

List<BluetoothGattService> serviceList = gatt.getServices();//获取服务列表                for(BluetoothGattService service : serviceList) {//遍历服务                    List<BluetoothGattCharacteristic> charclist = service.getCharacteristics();//获取特征列表                    for(BluetoothGattCharacteristic charc : charclist) {//遍历特征                        String uuid = charc.getUuid().toString();                        String name = Attributes.getInstance().getAttribute(uuid);                        if(name!=null && name.equals(Attributes.CONFIG_CHARACTER)){                            configCharc = charc;                            LogUtil.getInstance().ilog(tag,"获取到配网服务");                        }                    }                }

7.对特征值进行读写

特征值必须要支持读写,才能够进行读写的操作。
判断特征值是否支持读写

//判断是否可写int charaProp = characteristic.getProperties();if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) < 0){                      LogUtil.getInstance().ilog("nihao","gattCharacteristic的属性为:  不可写");     return;}//判断是否可读if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) < 0) {LogUtil.getInstance().ilog("nihao","gattCharacteristic  的属性为:  不可读");     return;  }

写数据,值得注意的是,Android每条数据的长度最长为20byte,如果超过这个长度,就必须要分条进行发送。

byte[] bytes = tobeSend.get(0);characBeSend.setValue(bytes);                characBeSend.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT);boolean result =  mBluetoothGatt.writeCharacteristic(characBeSend);LogUtil.getInstance().ilog(TAG,"写的结果是:"+result);LogUtil.getInstance().ilog(TAG,"写数据:"+new String(bytes));

读数据

mBluetoothGatt.readCharacteristic(characteristic);

读写成功之后,会执行ble操作的回调函数。

总结

ble连接之后,总是容易断开,不知道是否是ble的特性;
Android设备上每条数据发送的最大长度为20byte,但是ios发送则没有这个限制;

原创粉丝点击