Android(安卓)蓝牙4.0 Ble 连接Ble模块
Android手机连接蓝牙模块,并与蓝牙模块之间进行实时通讯。那么Android 手机端必须实现,蓝牙开关、扫描BLE模块、请求与BLE模块连接以及与BLE模块之间的数据互换。至于其他的包括检查手机是否支持蓝牙4.0之类的也是应该考虑到的。
那么就从检查手机是否支持蓝牙4.0开始吧。
if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); finish();}
这段代码在网上很多,还有权限,自然也不能少。
<uses-permission android:name="android.permission.BLUETOOTH"/><uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/><uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
第一个权限是应用使用蓝牙的权限,第二个权限是扫描蓝牙设备或者操作蓝牙设置等等的权限,第三个是将required设置为true则强制应用只能再支持ble的设备上运行。
然后就是开启蓝牙了,这点和之前的蓝牙版本操作一样,利用BluetoothAdapter的enable()方法就可以了,当然也可以用调用系统服务的方式,请求开启蓝牙。这里有个重要的问题,就是BluetoothAdapter不能再用BluetoothAdapter.getDefaultAdapter()来获得了,而应该用一下方式获得:
bManager=(BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); bAdapter=bManager.getAdapter();
打开了蓝牙之后,想要连接Ble模块,当然的先找到它了。以前的方式是bAdapter.startDiscovery(),然后注册监听器监听广播,通过广播获得扫描结果,对于蓝牙4.0,Android采用bAdapter.startLeScan(LeScanCallback);
的方式,如果你使用的Android 5.0 的Library的话,你会发现,这个方法已经废弃了,在它的注释里面有这么一句@deprecated use {@link BluetoothLeScanner#startScan(List, ScanSettings, ScanCallback)} instead.
也就是说它被BluetoothLeScanner的startScan(List,ScanSettings,ScanCallback)
代替了。不过为了兼容低版本,还是用这个方法比较好。因为如果你是Android5.0以下的手机,使用BluetoothLeScanner这个类会报错。
ScanCallback是一个监听器接口,当搜索到ble设备时会主动调用它唯一的方法void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord);
只需要在这个方法中处理设备列表即可。比起蓝牙4.0以前的确方便了很多。
搜索到指定设备,停止搜索,避免一直搜索。停止搜索的方法为:bAdapter.stopLeScan(ScanCallback);
搜索到设备了,就该连接设备了。Android 蓝牙4.0的连接,和之前版本的连接区别就很大了。Android Ble连接方式为: BluetoothGatt connectGatt(Context context, boolean autoConnect,BluetoothGattCallback callback);
返回值是一个BluetoothGatt对象,去掉Bluetooth就是Gatt了,GATT就是Generic Attribute Profile。这个让我去翻译,还真是为难我这种英语学了十几年四级都没过的人了。反正大致就是一个通用属性规范之类的意思吧,且当个代称。
连接之后呢?Ble连接之后就不是像以前那样,建立个Socket通信,请求ServerSocket允许连接,然后就开始眉来眼去的相互收发数据了。在取得BluetoothGatt后,需要读取蓝牙模块提供的Service、Characteristic,选择需要的通道进行数据交换。也可以直接通过UUID获取通道来进行通信。
获取蓝牙模块提供的Service、Characteristic方法如下:
public void getGattService(List<BluetoothGattService> gattServices){ if(gattServices==null)return; Log.i("wuwang", "获得服务列表"); serviceList.clear(); characteristicList.clear(); String uuid; String default_service=getResources().getString(R.string.unknow_service); String default_characteristic=getResources().getString(R.string.unknow_characteric); for(BluetoothGattService gService:gattServices){ Log.i("wuwang", "发现一个服务"); HashMap<String, String> sData=new HashMap<String, String>(); uuid=gService.getUuid().toString(); sData.put("name",SampleGattAttributes.lookup(uuid,default_service)); sData.put("uuid", uuid); serviceList.add(sData); Log.e("wuwang", SampleGattAttributes.lookup(uuid,default_service)+":"+uuid); List<BluetoothGattCharacteristic> charaList=gService.getCharacteristics(); String cuuid; for(BluetoothGattCharacteristic chara:charaList){ HashMap<String, String> cData=new HashMap<String, String>(); cuuid=chara.getUuid().toString(); cData.put("cname", SampleGattAttributes.lookup(cuuid, default_characteristic)); cData.put("cuuid", cuuid); cData.put("puuid", uuid); characteristicList.add(cData); Log.d("wuwang", " "+SampleGattAttributes.lookup(cuuid, default_characteristic)+":"+cuuid); } } }
在之前的BluetoothGatt connectGatt(Context context, boolean autoConnect,BluetoothGattCallback callback)
方法中,第三个参数也是一个监听器接口,getGattService方法可以放在BluetoothGattCallback的onConnectionStateChange方法实现中。
获取指定的BluetoothGattCharacteristic后,剩下的事情就好办了。Android手机端给蓝牙模块发送数据,就是在需要发数据的时候调用bCharacteristic.setValue(value);
和bGatt.writeCharacteristic(bCharacteristic);
即可。其中bCharacteristic为指定的BluetoothGattCharacteristic,Value为需要发送的数据。bGatt为之前获得BluetoothGatt。
而读取蓝牙模块发送来的数据,只许设置Characteristic通知,即调用bGatt.setCharacteristicNotification(bCharacteristic, true);
然后再之前ConnectGatt()第三个参数使用的BluetoothGattCallback接口中实现onCharacteristicChanged方法,并在其中获取数据即可:
bGatt.readCharacteristic(bCharacteristic);final byte[] bytes=bCharacteristic.getValue();
大概就是这个样子了。
更多相关文章
- Android(安卓)4.2上调试RT3070 WiFi模块
- Afinal简介
- Android(安卓)Studio 一个module引用另一个模块module的方法
- android 源码之英语单词记忆程序源码
- Android极速开发框架One,只需59秒即可!
- Android基于MQTT实现发布消息与监听topic接收消息
- react-native调用Android的原生方法
- Android(安卓)JNI小实例
- Android(安卓)NDK 开发教程六: application.mk