Quantcast
Channel: CSDN博客移动开发推荐文章
Viewing all articles
Browse latest Browse all 5930

Android 低功耗蓝牙的多设备连接与数据接收,简单实现

$
0
0

不知不觉,通宵加班已经快两个星期了,快两年没这么干活了。

起因就是项目的一个功能,蓝牙多连接。应用同时连接多个设备,等待接收数据,处理后显示图表。

在这之前我没有搞过蓝牙方面的东西,只能从基础开始边看边干。


最开始不知道,看的是传统蓝牙的连接与传输,几天过后,发现与低功耗蓝牙不一样啊,又针对低功耗蓝牙开始找资料。


低功耗蓝牙支持的api最低是18。

基本思路:低功耗蓝牙连接分两种,一种是作为周边设备,一种是作为中心设备。因为需求是多连接,那我们就按照创建一个中心设备的做法来处理。


下面先记录一下,一个低功耗蓝牙的连接:

注:因为程序与硬件是一套设备,所以我不需要扫瞄附近的设备,然后选择连接,直接拿地址进行连接。


蓝牙需要的权限:

 <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"/>


接下来在activity中,不管周边设备还是中心设备,我们都需要拿到:BluetoothManager和BluetoohAdapter:

//获取BluetoothManager
        BluetoothManager mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        //获取BluetoothAdapter
        BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();

        //如果蓝牙没有打开 打开蓝牙
        if (!mBluetoothAdapter.isEnabled()) {
            mBluetoothAdapter.enable();
        }


然后就是通过上面拿到的adapter得到BluetoothDevice对象:

BluetoothDevice bluetoothDeviceOne = mBluetoothAdapter.getRemoteDevice("D8:B0:4C:BC:C0:83");

注:1.传入的参数就是你蓝牙的地址。

2.假如你需要多连接,那么这里就要获得多个BluetoothDevice对象,通过不同的地址。


然后就是BluetoothGatt对象:

private BluetoothGatt mBluetoothGattOne;

在拿到上面两个对象后,先校验gatt对象是否在运行:

//如果Gatt在运行,将其关闭
        if (mBluetoothGattOne != null) {
            mBluetoothGattOne.close();
            mBluetoothGattOne = null;
        }

然后就是连接设备,并设置连接的回调:

//连接蓝牙设备并获取Gatt对象
        mBluetoothGattOne = bluetoothDeviceOne.connectGatt(MainActivity.this, true, bluetoothGattCallbackOne);

其中,bluetoothGattCallbackOne就是回调:

/**
     * 第一个设备  蓝牙返回数据函数
     */
    private BluetoothGattCallback bluetoothGattCallbackOne = new BluetoothGattCallback() {
        @Override
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
            if (status == BluetoothGatt.GATT_SUCCESS) {
                if (newState == BluetoothProfile.STATE_CONNECTED) {
                    setText("设备一连接成功");

                    //搜索Service
                    gatt.discoverServices();
                } else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
                    setText("设备一连接断开");
                }
            }
            super.onConnectionStateChange(gatt, status, newState);
        }

        @Override
        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
            //根据UUID获取Service中的Characteristic,并传入Gatt中
            BluetoothGattService bluetoothGattService = gatt.getService(UUID_SERVICE);
            BluetoothGattCharacteristic bluetoothGattCharacteristic = bluetoothGattService.getCharacteristic(UUID_NOTIFY);

            boolean isConnect = gatt.setCharacteristicNotification(bluetoothGattCharacteristic, true);
            if (isConnect){

            }else {
                Log.i("geanwen", "onServicesDiscovered: 设备一连接notify失败");
            }
            super.onServicesDiscovered(gatt, status);
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {//数据改变
            super.onCharacteristicChanged(gatt, characteristic);
            String data = new String(characteristic.getValue());
            Log.i("geanwen", "onCharacteristicChanged: " + data);
        }
    };

注:1.我的需求就是接收是蓝牙发送过来的数据,假如你需要写入数据,或者其他的功能,在上面的callback中,可以复写对应的方法。

2.上面onConectionStateChange方法就是连接状态改变时回调的方法,在其中判断连接是否成功。

3.上面onServicesDiscovered方法就是在onConectionStateChange连接成功之后,发现该蓝牙的服务。

在这里你可以设置你需要的服务,每个蓝牙连接中会有不同的服务,设置你需要的即可。

4.上面我设置了接收数据的服务,其中传入的几个常量就是我们低功耗蓝牙的服务的固定码,下面贴个例子:

//蓝牙设备的Service的UUID
    public final static UUID UUID_SERVICE = UUID.fromString("0003cdd0-0000-1000-8000-00805f9b0131");

    //蓝牙设备的notify的UUID
    public final static UUID UUID_NOTIFY = UUID.fromString("0003cdd1-0000-1000-8000-00805f9b0131");

大家仔细看好,两个码是不一样的,一开始我以为是一样的,结果调了好久。

因为我这个需求是不能先搜索,在连接,然后选择对应服务的,所以我将这些这些操作都省略,即我提前拿到了这几个服务的码。

5.上面回调方法onCharacteristicChanged方法就是来数据了,接收的方法。

连接一个低功耗蓝牙并接收数据上面就介绍完了,下面说下连接两个或者多个。

首先上面提到了BluetoothDevice对象,连接两个时候,需要创建第二个:

 BluetoothDevice bluetoothDeviceOne = mBluetoothAdapter.getRemoteDevice("D8:B0:4C:BC:C0:83");
        BluetoothDevice bluetoothDeviceTwo = mBluetoothAdapter.getRemoteDevice("D8:B0:4C:BA:D5:9D");

下一步就是gatt对象了:

private BluetoothGatt mBluetoothGattOne;
    private BluetoothGatt mBluetoothGattTwo;

//连接蓝牙设备并获取Gatt对象
        mBluetoothGattOne = bluetoothDeviceOne.connectGatt(MainActivity.this, true, bluetoothGattCallbackOne);
        mBluetoothGattTwo = bluetoothDeviceTwo.connectGatt(MainActivity.this, true, bluetoothGattCallbackTwo);

接下来就是在回调中等着了,同上面的callback没啥区别。


注:

1.上面说的方法,我同时连接了四个设备,可以同时接收到数据。

2.应用关闭后,在开启,有时会接收不到数据,具体问题时硬件还是软件正在调查。重启手机的蓝牙,过一会就好了。

3.上面的程序在华为手机上应该是不能成功,华为平板也不能。(蛋疼,目前我测试的手机是三星note2)

4.上述程序没有针对6.0及以上版本进行权限申请。

5.这篇文章是这几天找资料,东拼西凑试出来的,可能还有哪里有问题,欢迎童鞋们踊跃来指导,感激不尽。




作者:geanwen 发表于2017/6/23 15:52:28 原文链接
阅读:89 评论:0 查看评论

Viewing all articles
Browse latest Browse all 5930

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>