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);
@Override
public 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回调里获取的,心细的同学估计都看到了,我在这个函数回调里进行了打印,其实这就是需要处理的,我这是和我的嵌入式同事协定好用一个协定的服务。

从获取授权,拿到系统服务,扫描蓝牙,建立连接,传输数据这一整个蓝牙开发流程就走了,如有不对的地方欢迎指教,谢谢!

 

 

你可能感兴趣的:(Android)