本文主要是介绍Anroid BLE蓝牙(手机分别作为中心设备和外围设备),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
蓝牙是一种短距的无线通讯技术,可实现固定设备、移动设备之间的数据交换。一般将蓝牙3.0之前的BR/EDR蓝牙称为传统蓝牙,而将蓝牙4.0规范下的LE蓝牙称为低功耗蓝牙。
BLE蓝牙模块主要应用领域
1、移动扩展设备
2、汽车电子设备
3、健康医疗用品:心跳带、血压计等
4、定位应用:室内定位、井下定位等
5、近距离数据采集:无线抄表、无线遥测等
6、数据传输:智能家居室内控制、蓝牙调光、打印机等
手机作为中心设备连接外围设备 蓝牙的操作流程
1.声明蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH" /> <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED" />
在 Android 6.0 及以上,还需要打开位置权限。如果应用没有位置权限,蓝牙扫描功能不能使用
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
2.判断设备是否支持BLE蓝牙
public boolean isSupportBle() {return mContext.getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE); }
3.初始化蓝牙
public BleBluetooth(Context context) {this.context = context = context.getApplicationContext(); bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); bluetoothAdapter = bluetoothManager.getAdapter(); }
4.是否开启蓝牙
public boolean isBlueEnable() {return bluetoothAdapter.isEnabled(); }
5.开启蓝牙
public void enableBluetooth() {bluetoothAdapter.enable(); }
6.扫描蓝牙
6.0以上要动态设置权限
public void scanDevice(BluetoothAdapter.LeScanCallback callback, Activity activity) {if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {// Android M Permission check if (activity.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) !=PackageManager.PERMISSION_GRANTED) {//TODO 权限适配 终止 activity.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_COARSE_LOCATION); } else {
mbluetoothAdapter.startLeScan(callBack);} } else {
mbluetoothAdapter.startLeScan(callBack);}} @Override public void onRequestPermissionsResult( int requestCode , String[] permissions , int[] grantResults) { super.onRequestPermissionsResult(requestCode , permissions , grantResults) ; switch (requestCode) { case PERMISSION_REQUEST_COARSE_LOCATION: if (grantResults[ 0] == PackageManager. PERMISSION_GRANTED) {
mbluetoothAdapter.startLeScan(callBack);} break; }}
mbluetoothAdapter.startLeScan(callBack);
BluetoothAdapter.LeScanCallback callBack = new BluetoothAdapter.LeScanCallback() {@Override public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {//TODO 处理扫描到的结果 Device = device; } };
6.连接蓝牙
7.寻找服务,并打开
Device.connectGatt(this,false,coreGattCallback);
BluetoothGattCallback connectCallback = new BluetoothGattCallback() {@Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {super.onConnectionStateChange(gatt, status, newState); //TODO 蓝牙连接状态的回调,在这里根据newState判断蓝牙是否连接成功 if (newState == BluetoothGatt.STATE_CONNECTED) {mbluetoothGatt = gatt; } else if (newState == BluetoothGatt.STATE_DISCONNECTED) {} else if (newState == BluetoothGatt.STATE_CONNECTING) {}}@Override public void onServicesDiscovered(BluetoothGatt gatt, int status) {super.onServicesDiscovered(gatt, status); //TODO 在发方法中找服务并找到可通知的特征值 BluetoothGattService bleService = gatt.getService(UUID.fromString("0000fee7-0000-1000-8000-00805f9b34fb")); List<BluetoothGattCharacteristic> characteristics = bleService.getCharacteristics(); for (BluetoothGattCharacteristic characteristic :characteristics) {int charaProp = characteristic.getProperties(); //找到可通知的特征 UUID_NOFITY = characteristic.getUuid(); if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {//使所有的描述可通知 for (BluetoothGattDescriptor descripter : characteristic.getDescriptors()){descripter.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); gatt.writeDescriptor(descripter); }}else if((charaProp & BluetoothGattCharacteristic.PROPERTY_INDICATE) > 0){//使所有的描述可通知 UUID_INDICATE = characteristic.getUuid(); for (BluetoothGattDescriptor descripter : characteristic.getDescriptors()){descripter.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); gatt.writeDescriptor(descripter); }}}//根据notify还是indicate来设置可写的描述 for (BluetoothGattCharacteristic characteristic :characteristics) {int charaProp = characteristic.getProperties(); if((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE) > 0 || (charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) > 0){UUID_WRITE = characteristic.getUuid(); //使所有的描述可通知 for (BluetoothGattDescriptor descripter : characteristic.getDescriptors()){if(UUID_NOFITY != null && UUID_INDICATE == null){descripter.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); }else if(UUID_INDICATE != null && UUID_NOFITY == null){descripter.setValue(BluetoothGattDescriptor.ENABLE_INDICATION_VALUE); }gatt.writeDescriptor(descripter); }}}}@Override public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {super.onCharacteristicRead(gatt, characteristic, status); }@Override public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {super.onCharacteristicWrite(gatt, characteristic, status); //TODO 在这里判断想设备是否写数据成功 }@Override public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {super.onCharacteristicChanged(gatt, characteristic); //TODO 接受设备上发是数据 }@Override public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {super.onDescriptorRead(gatt, descriptor, status); }@Override public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) {super.onDescriptorWrite(gatt, descriptor, status);} @Override public void onReliableWriteCompleted(BluetoothGatt gatt , int status) { super.onReliableWriteCompleted(gatt , status) ; } @Override public void onReadRemoteRssi(BluetoothGatt gatt , int rssi , int status) { super.onReadRemoteRssi(gatt , rssi , status) ; } @Override public void onMtuChanged(BluetoothGatt gatt , int mtu , int status) { super.onMtuChanged(gatt , mtu , status) ; }} ;
8.断开蓝牙
mbluetoothGatt.close();
手机作为外围设备,发送广播供中心设备连接
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(); }} }
2.设置参数
private AdvertiseSettings buildAdvertiseSettings(){AdvertiseSettings.Builder settingsBuilder=new AdvertiseSettings.Builder(); settingsBuilder.setAdvertiseMode(AdvertiseSettings.ADVERTISE_MODE_LOW_POWER); settingsBuilder.setTimeout(0); return settingsBuilder.build(); }
private AdvertiseData buildAdvertiseData(){AdvertiseData.Builder dataBuilder=new AdvertiseData.Builder(); dataBuilder.setIncludeDeviceName(true); return dataBuilder.build(); }3.开始广播
private void startAdvertising(){Log.d(TAG,"服务开始广播"); if(mAdertiseCallback==null){AdvertiseSettings settings=buildAdvertiseSettings(); AdvertiseData data=buildAdvertiseData(); mAdertiseCallback=new SampleAdvertiseCallback(); if(mBluetoothLeAdvertiser!=null){mBluetoothLeAdvertiser.startAdvertising(settings,data,mAdertiseCallback); }} }4.广播回调
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,"服务端的广播成功开启"); initServices(getContext());//该方法是添加一个服务,在此处调用即将服务广播出去 } }5. 为设备添加服务
private void initServices(Context context){ // 获取BluetoothGattServer的实例 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); service.addCharacteristic(characteristicRead); characteristicWrite=new BluetoothGattCharacteristic(UUID_CHARWRITE, BluetoothGattCharacteristic.PROPERTY_WRITE , BluetoothGattCharacteristic.PERMISSION_WRITE); service.addCharacteristic(characteristicWrite); characteristicIndicate = new BluetoothGattCharacteristic(UUID_INDICATE, BluetoothGattCharacteristic.PROPERTY_INDICATE, BluetoothGattCharacteristic.PERMISSION_WRITE); BluetoothGattDescriptor descriptor=new BluetoothGattDescriptor(UUID_DESCRIPTOR,BluetoothGattCharacteristic.PERMISSION_WRITE); characteristicIndicate.addDescriptor(descriptor); service.addCharacteristic(characteristicIndicate); mBluetoothGattServer.addService(service); }6.服务回调
//服务事件的回调 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()方法"); } };
参考连接
BLE源码1、蓝牙Bluetooth BR/EDR 和 Bluetooth Smart 必需要知道的十个不同点
2、BLE简介和Android BLE编程
3、BLE广播数据解析
4、BLE学习
5 Android Bluetooth api
这篇关于Anroid BLE蓝牙(手机分别作为中心设备和外围设备)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!