Android BLE 蓝牙学习总结(一):手机作为周边BluetoothGattServer的实现

来源:互联网 发布:知错改错不认错的人 编辑:程序博客网 时间:2024/04/30 15:48

低功耗蓝牙的基本概念:
在BLE协议中,有两个角色,周边(Periphery)和中央(Central)。周边是数据的提供者,中央是数据的使用和处理者。在Android SDK里面,Android4.3以后手机可以作为中央使用;Android5.0以后手机才可以作为周边使用,即此时的手机可以作为BLE设备(如可穿戴设备、手环、智能锁、心率测量仪等)来为中央提供数据。
一个中央可以同时连接多个周边,但一个周边某一时刻只能连接一个中央。
Android BLE SDK的四个关键类如下:
1、BluetoothGattServer作为周边来提供数据,BluetoothGattServerCallback返回周边的状态,更通俗的说,当中央有请求时,系统调用该抽象类的相应方法传递数据给周边。
2、BluetoothGatt作为中央来使用和处理数据,BluetoohGattCallback返回中央的状态和周边提供数据,即周边反馈的数据通过该抽象类的相应方法传递到中央。
该篇文章主要总结手机作为周边的实现
一、创建一个周边所需的类,如下图
这里写图片描述
说明:每个周边BluetoothGattServer包含多个服务,每个服务包含多个特征,每个特征又可以包含多个描述
1、new一个描述:descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,
BluetoothGattCharacteristic.PERMISSION_WRITE);
2、new 一个特征:characteristicRead=new BluetoothGattCharacteristic(
UUID_CHARREAD,
BluetoothGattCharacteristic.PROPERTY_READ,
3、把描述添加到特征:characteristicRead.addDescriptor(descriptor);
4、new 一个服务: service=new BluetoothGattService(UUID_SERVER,
BluetoothGattService.SERVICE_TYPE_PRIMARY);
5、把特征添加到服务:service.addCharacteristic(characteristicWrite);
6、获取BluetoothManager:mBluetoothManager=(BluetoothManager)
getSystemService(Context.BLUETOOTH_SERVICE);
7、获取周边:mBluetoothGattServer=mBluetoothManager.openGattServer(
context,bluetoothGattServerCallback);
8、把服务添加到周边: mBluetoothGattServer.addService(service);
9、将添加的服务广播出去,在本人实现的案例中,将initServices()在广播的回调方法中调用。

二、实现的程序讲解
手机作为外设:设置广播与服务主要涉及的类BluetoothLeAdvertiser与BluetoothGattServer
1、设置广播,主要操作是BluetoothLeAdvertiser
1.1、获取BluetoothLeAdvertiser实例:

 private void initialize(){        if(mBluetoothLeAdvertiser==null){           mBluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);            if(mBluetoothManager!=null){                BluetoothAdapter bluetoothAdapter=mBluetoothManager.getAdapter();                if(bluetoothAdapter!=null){                    mBluetoothLeAdvertiser=bluetoothAdapter.getBluetoothLeAdvertiser();                }else{                    Toast.makeText(this,"设备不支持蓝牙广播",Toast.LENGTH_SHORT).show();                }            }else{                Toast.makeText(this,"不支持蓝牙",Toast.LENGTH_SHORT).show();            }        }    }

1.2、开始广播,BluetoothLeAdvertiser.startAdvertising(settings,data,mAdvertiseCallback),开始广播之前需要准备三个参数
1) AdvertiseSettings:

    private AdvertiseSettings buildAdvertiseSettings(){        AdvertiseSettings.Builder settingsBuilder=new AdvertiseSettings.Builder();        settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER);        settingsBuilder.setTimeout(0);        return settingsBuilder.build();    }

2)AdvertiseData

    private AdvertiseData buildAdvertiseData(){        AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder();       dataBuilder.setIncludeDeviceName(true);        return dataBuilder.build();    }

3)mAdvertiseCallback=new SampleAdvertiseCallback,即广播成功或者失败的系统回调

    private class SampleAdvertiseCallback extends AdvertiseCallback{    @Override    public void onStartFailure(int errorCode){        super.onStartFailure(errorCode);        Log.d(TAG,"广播失败");        sendFailureIntent(errorCode);        stopSelf();    }    @Override    public void onStartSuccess(AdvertiseSettings settingsInEffect){        super.onStartSuccess(settingsInEffect);        Log.d(TAG,"服务端的广播成功开启");        Log.d(TAG,"BLE服务的广播启动成功后:TxPowerLv="+settingsInEffect.getTxPowerLevel()+";mode="+settingsInEffect.getMode()+";timeout="+settingsInEffect.getTimeout());        initServices(getContext());//该方法是添加一个服务    }}

1.3、关闭广播

 private void stopAdvertising(){        Log.d(TAG,"服务停止广播");        if(mBluetoothLeAdvertiser!=null){            mBluetoothLeAdvertiser.stopAdvertising(mAdertiseCallback);            mAdertiseCallback=null;        }    }

2、设置服务,
2.1、首先先实现服务的回调:bluetoohtGattServerCallback,该实例将作为参数

//服务事件的回调private BluetoothGattServerCallback bluetoothGattServerCallback=new BluetoothGattServerCallback() {    //1、首先是连接状态的回调    @Override    public void onConnectionStateChange(BluetoothDevice device, int status, int newState) {        super.onConnectionStateChange(device, status, newState);        Log.e(TAG,"连接状态发生改变,安卓系统回调onConnectionStateChange:device name="+device.getName()+"address="+device.getAddress()+"status="+status+"newstate="+newState);    }    @Override    public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {        super.onCharacteristicReadRequest(device, requestId, offset, characteristic);        Log.e(TAG,"客户端有读的请求,安卓系统回调该onCharacteristicReadRequest()方法");        mBluetoothGattServer.sendResponse(device,requestId, BluetoothGatt.GATT_SUCCESS,offset,characteristic.getValue());    }    //接受具体字节,当有特征被写入时,回调该方法,写入的数据为参数中的value    @Override    public void onCharacteristicWriteRequest(BluetoothDevice device, int requestId, BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {        super.onCharacteristicWriteRequest(device, requestId, characteristic, preparedWrite, responseNeeded, offset, value);        Log.e(TAG,"客户端有写的请求,安卓系统回调该onCharacteristicWriteRequest()方法");        //特征被读取,在该回调方法中回复客户端响应成功        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);        //处理响应内容        //value:客户端发送过来的数据        onResponseToClient(value,device,requestId,characteristic);    }    //特征被读取。当回复相应成功后,客户端胡读取然后触发本方法    @Override    public void onDescriptorReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattDescriptor descriptor) {        super.onDescriptorReadRequest(device, requestId, offset, descriptor);        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,null);    }    //2、其次,当有描述请求被写入时,回调该方法,    @Override    public void onDescriptorWriteRequest(BluetoothDevice device, int requestId, BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value) {        super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite, responseNeeded, offset, value);        mBluetoothGattServer.sendResponse(device,requestId,BluetoothGatt.GATT_SUCCESS,offset,value);       // onResponseToClient(value,device,requestId,descriptor.getCharacteristic());    }    @Override    public void onServiceAdded(int status,BluetoothGattService service){        super.onServiceAdded(status,service);        Log.e(TAG,"添加服务成功,安卓系统回调该onServiceAdded()方法");    }};

2.2、获取BluetoothGattServer的实例

   mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);

2.3、为设备添加服务:

     //添加一个服务,该服务有一个读特征、该特征有一个描述;一个写特征。//用BluetoothGattServer添加服务,并实现该类的回调接口private void initServices(Context context){    mBluetoothGattServer=mBluetoothManager.openGattServer(context,bluetoothGattServerCallback);    BluetoothGattService service=new BluetoothGattService(UUID_SERVER,BluetoothGattService.SERVICE_TYPE_PRIMARY);    characteristicRead=new BluetoothGattCharacteristic(UUID_CHARREAD,BluetoothGattCharacteristic.PROPERTY_READ,BluetoothGattCharacteristic.PERMISSION_READ);    BluetoothGattDescriptor descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,BluetoothGattCharacteristic.PERMISSION_WRITE);    characteristicRead.addDescriptor(descriptor);    service.addCharacteristic(characteristicRead);    BluetoothGattCharacteristic characteristicWrite=new BluetoothGattCharacteristic(UUID_CHARWRITE,            BluetoothGattCharacteristic.PROPERTY_WRITE |BluetoothGattCharacteristic.PROPERTY_READ|BluetoothGattCharacteristic.PROPERTY_NOTIFY,            BluetoothGattCharacteristic.PERMISSION_WRITE);    service.addCharacteristic(characteristicWrite);    mBluetoothGattServer.addService(service);    Log.d(TAG,"初始化服务成功:initServices ok");}

案例代码地址:https://github.com/lihongandroid/BleServer

阅读全文
0 0
原创粉丝点击