Android(安卓)BLE开发入门教程
关于BLE开发,网上相关的资料其实也不少,大多数资料介绍的还是很不错,不过我这边资料,主要侧重代码方便的介绍及使用。
1 我的这边是基于Android6.0以上版本开发的所以首先就得获取授权:
//请求蓝牙权限if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (this.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, 1); }}
2 从系统这边获取BluetoothManager服务:
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
拿到BluetoothManager服务后获取适配器
BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
3 通过BluetoothAdapter我们可以做接下来的扫描蓝牙的操作
mBluetoothAdapter.startLeScan(mLeScanCallback);
在这个startLeScan()方法里面是有一个扫描后的结果回调的,扫描结果的返回就在这个LeScanCallBack里面:
// Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) { runOnUiThread(new Runnable() { @Override public void run() { if (!TextUtils.isEmpty(device.getName()) && device.getName().contains("AAA")){ mLeDeviceListAdapter.addDevice(device); } Log.d(TAG, " rssi = " + rssi + "addr = " + device.getAddress()); if(device.getUuids() == null) Log.d(TAG, "uuid = null rssi = " + rssi); else Log.d(TAG, "uuid = " + device.getUuids().toString() + " rssi = " + rssi); mLeDeviceListAdapter.notifyDataSetChanged(); } }); } };
onLeScan()这个函数的回调注意下,是在子线程里面,我这边操作用到了UI,所以我的线程就得切换到UI线程,主要用到了列表展示搜索到蓝牙名称。到这里我们基本蓝牙的搜索就走完了,接下来就得看看如何通过蓝牙建立连接传输数据。
4 建立连接:这个步骤需要一个核心的BluetoothDevice 类,这个类怎么来的,细心的同学估计看到了,就在onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord)回调函数里面,我这边是用一个listview展示,点击某一个蓝牙的建立连接,接下来就看他的核心方法。
BluetoothGatt bluetoothGatt = mDevice.connectGatt(this, false, mGattCallback);
通过BluetoothDevice.connectGatt()建立连接,里面有三个参数,第一参数是上下文环境,第二个参数是第一连接失败后,是否接着连接,第三个参数是建立连接后回调。而传输数据这块就跟这个回调有着千丝万缕的联系。细看这个回调函数:
// 参数连接状态回调 private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { //连接状态改变的回调 @Override public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { if (newState == BluetoothProfile.STATE_CONNECTED) { // 连接成功后启动服务发现 bluetoothGatt.discoverServices(); } }; //发现服务的回调 public void onServicesDiscovered(BluetoothGatt gatt, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { Log.e(TAG, "成功发现服务"); List list = gatt.getServices(); for (int i = 0; i < list.size(); i++) { Log.e("--->",list.get(i).toString()); BluetoothGattService service = list.get(i); Log.e("1-->Service UUID",service.getUuid()+""); List data = list.get(i).getCharacteristics(); for (int j = 0; j < data.size(); j++) { BluetoothGattCharacteristic bluetoothGattCharacteristic = data.get(j);// bluetoothGattCharacteristic.getValue(); Log.e("2-->Characteristic UUID",bluetoothGattCharacteristic.getUuid()+""); Log.e("--->",data.get(j).toString()); } } } else { Log.e(TAG, "服务发现失败,错误码为:" + status); } }; //写操作的回调 public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { String s = new String(characteristic.getValue()); Log.e(TAG, "写入成功" + characteristic.getUuid().toString() +"length ="+ characteristic.getValue().length +"content=" + s); } }; //读操作的回调 public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { if (status == BluetoothGatt.GATT_SUCCESS) { String s = new String(characteristic.getValue()); Log.e(TAG, "读取成功" + characteristic.getValue().toString() +"length =="+ characteristic.getValue().length + s ); } } //数据返回的回调(此处接收BLE设备返回数据) public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { Log.e(TAG,"--->onCharacteristicChanged"); }; };
这个BluetoothGattCallback连接参数状态的回调是很有重要性的,当与设备建立连接的时候会在onConnectionStateChange()回调,然后在这个回调里面进行bluetoothGatt.discoverServices();这个是发现服务的核心启动方法,然后在onServicesDiscovered()回调出来,这个时候在这里进行BluetoothGattService获取以及BluetoothGattCharacteristic获取,这样蓝牙的真正的链路打算打通,后面两个回调也是很重要的,bluetoothGatt进行读写操作的回调,这个是跟业务层有着重要联系,在这一层可以很好的掌控读写。其实BluetoothGattCallback回调里面不止这些的,还有其他的回调,比如很重要的一个回调的就是设置MTU的回调,这是蓝牙读写开始限制是20个字节,设置mtu后最大可支持到512的字节。但这个设置需要在onConnectionStateChange()里面进行操作。前提条件是:AndroidAPI要在21以上。
boolean mtu = bluetoothGatt.requestMtu(512);
@Overridepublic void onMtuChanged(BluetoothGatt gatt, int mtu, int status) { super.onMtuChanged(gatt, mtu, status); Log.e(TAG, "启动服务发现:" + service); Log.e("-->onMtuChanged","长度:"+mtu);}
5.传输数据
传输数据这块其实就是很简单的,这里面我就直接上代码了
读的操作:
characteristic.getValue();bluetoothGatt.readCharacteristic(characteristic);
写的操作:
characteristic.setValue("要写入的内容");bluetoothGatt.writeCharacteristic(characteristic);
这里主要注意的一点就是characteristic 不要被我传入所迷惑,characteristic就是BluetoothGattCharacteristic,每个蓝牙都有能读写的characteristic这个获取就是onServicesDiscovered回调里获取的,心细的同学估计都看到了,我在这个函数回调里进行了打印,其实这就是需要处理的,我这是和我的嵌入式同事协定好用一个协定的服务。
从获取授权,拿到系统服务,扫描蓝牙,建立连接,传输数据这一整个蓝牙开发流程就走了,如有不对的地方欢迎指教,谢谢!
更多相关文章
- ADB源码分析(一)
- Android(安卓)Socket通信
- Unity Android真机调试
- Android(安卓)Wear 报错:cannot connect to localhost:4444: 由于
- android 解析JSON
- Android(安卓)bluetooth介绍(一):基本概念及硬件接口
- android 调试技巧
- Android(安卓)Bluetooth 总结
- android webview用法小结2 java与javascript的交互