Android BLE低功耗蓝牙开发(下) BLE客户端(中央设备)与GATT服务的通讯

之前的文章简单实现了使用传统蓝牙进行通讯的DEMO,说是最简单其实只是夸张的写法~毕竟标题党横行,我们也得学学点~至少没有UC震惊部那么夸张。

然后,本来是要写Android开发之BlueTooth--最简单的Andorid低功耗(BLE)蓝牙通讯Demo的,写了一半发现BLE简单不起来,所以分两篇来写BLE相关的应用。因此大家可能发现,你下篇的编写时间别上篇还早?这只是假象~CSDN的发布时间是建立草稿的时间,我也是醉了。实际发布时间比上一篇迟将近一周...

上一篇已经简单的写了一下关于GATT服务端的一些知识以及搭建。毕竟这个部分很少要我们做的,所以网络上这方面的资源相对较少。通常外围设备都是有固定产品的,用不着我们开发,例如心率器,血压器等等各种感应器,直接把相关数据格式以及UUID给我们在手机上进行就可以了。但是了解一下也没什么坏处。那么这篇就是简单实现如何用手机连接这些产品获取到对应数据了。

 

服务端

上一篇文章我们写了一个服务端,这篇就是基于那个服务端程序来建立的连接。所以大家有必要先看一下上一篇,否则这里对应数据的UUID怎么来都不知道。还需要说明的一点是,上一篇我们仅仅成功开启了服务,但是数据更新的逻辑没写。假如他是一个心率传感器,那么我们心率改变时,理应要更新数据,并通知客户端,所以上一篇还缺少了一段代码:

 

 //4.模拟数据更新
    private void updateCharacteristic() {
        if (mBluetoothGattServer == null) {
            return;
        }
        final Handler updateHandler = new Handler();
        updateHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                for (BluetoothDevice d : mRegisteredDevices) {
                    BluetoothGattCharacteristic newCharacteristic = mBluetoothGattServer
                            .getService(TIME_SERVICE)
                            .getCharacteristic(CURRENT_TIME);
                    byte[] data = ("数据更新" + System.currentTimeMillis()).getBytes();
                    newCharacteristic.setValue(data);
                    mBluetoothGattServer.notifyCharacteristicChanged(d, newCharacteristic, false);
                }
                updateHandler.postDelayed(this, 5000);

            }
        }, 5000);//5s更新一次
        outputLog("数据模拟更新启动",MSG_TYPE_NORMAL);

    }


当广播成功后就启动这个数据更新的函数就行了。接下来开始编写客户端了。编写之前先说明几点:

 

 

BLE客户端和传统蓝牙代码上的差异

1.获取适配器

传统蓝牙是这么获取适配器的:

 

if (mBluetoothAdapter == null) {
            mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        }

BLE蓝牙是这样的:

 

 

if (mBluetoothAdapter == null) {
            /**这里和传统的蓝牙有什么区别呢?*/
            final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
            mBluetoothAdapter = bluetoothManager.getAdapter();
          
        }

 

到底这算不算区别?反正官方文档这么写,其实这两个互换没感觉到有什么变化,反正都是获取到适配器。具体有没有影响,我还没得测试。有兴趣的试试看,然后告诉我哈~

 

2.搜索回调

传统蓝牙是需要通过广播来获取搜索结果的:

 

 private void registerRec() {
        //3.注册蓝牙广播
        mReceiver = new BlueToothStateReceiver();
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);//搜索到蓝牙
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
        registerReceiver(mReceiver, filter);
    }

 class BlueToothStateReceiver extends BroadcastReceiver {
        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(MainActivity.this, "触发广播", Toast.LENGTH_SHORT).show();
            String action = intent.getAction();
            switch (action) {
                case BluetoothDevice.ACTION_FOUND:
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                    Toast.makeText(MainActivity.this, "找到设备" + device.getName(), Toast.LENGTH_SHORT).show();
                    if (mRvAdapter != null) {
                        mRvAdapter.addDevice(device);
                    }
                    break;
                case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
                    mMessageAdapter.addMessage("搜索结束");
                    break;
            }
        }
    }


BLE蓝牙是直接以回调方法进行监听的:

 

 

 private MyLeScanCallback1 mLeScanCallback1 = new MyLeScanCallback1();

private void scanBleDevices1(boolean enable) {
        if (enable) {
            outputLog("正在搜索设备");
            outputLog("当前搜索回调:callback 1");
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    mBluetoothAdapter.stopLeScan(mLeScanCallback1);
                    outputLog("停止搜索");
                }
            }, 10000);//设置10秒超时
            mScanning = true;
            mBluetoothAdapter.startLeScan(mLeScanCallback1);
        } else {
            outputLog("停止搜索");
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback1);
        }
    }

class MyLeScanCallback1 implements BluetoothAdapter.LeScanCallback {
        @Override
        public void onLeScan(BluetoothDevice bluetoothDevice, int i, byte[] bytes) {
            mDeviceAdapter.addDevice(bluetoothDevice);
        }
    }

 

 

3.连接方式

传统蓝牙连接别的设备:

 

 public void run() {
            if (mDevice != null) {
                try {
                    //获取套接字
                    BluetoothSocket temp = mDevice.createInsecureRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));
                    //mDevice.createRfcommSocketToServiceRecord(UUID.fromString(BT_UUID));//sdk 2.3以下使用
                    mSocket = temp;
                    //发起连接请求
                    if (mSocket != null) {
                        mSocket.connect();
                    }
                    sendHandlerMsg("连接 " + mDevice.getName() + "成功!");
                    //获取输入输出流
                    btIs = mSocket.getInputStream();
                    btOs = mSocket.getOutputStream();

                    //通讯-接收消息
                    BufferedReader reader = new BufferedReader(new InputStreamReader(btIs, "UTF-8"));
                    String content = null;
                    while (canRecv) {
                        content = reader.readLine();
                        sendHandlerMsg("收到消息:" + content);
                    }


                } catch (IOException e) {
                    e.printStackTrace();
                    sendHandlerMsg("错误:" + e.getMessage());
                } finally {
                    try {
                        if (mSocket != null) {
                            mSocket.close();
                        }
                        //btIs.close();//两个输出流都依赖socket,关闭socket即可
                        //btOs.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                        sendHandlerMsg("错误:" + e.getMessage());
                    }
                }
            }
        }


BLE连接服务端:

 

 

private void connectGatt(BluetoothDevice device) {
        outputLog("正在连接到:"+device.getName());
        //新建一个链接
        mBluetoothGatt = device.connectGatt(BleMainActivity.this, false, mBluetoothGattCallback);
        //mBluetoothGatt.connect();//如果是断开重连
        //mBluetoothGatt.disconnect();//断开当前连接
    }

然后在回调里处理连接成功或者失败的逻辑。

 

 

4.通讯方式

传统蓝牙是获取到socket只有以类似于TCP的方式进行通讯。

BLE蓝牙则是通过读写特性来进行通讯。

 

5.其他

代码上的区别我目前也就总结了这几点,至于其他只能在更详细的开发中慢慢发现了。

 

 

搜索回调的方式居然过时了?

相信不少人在按照谷歌文档或者其他翻译文档的博客来写demo得时候发现:



 

不对啊!我明明按照官方的来,怎么会过时!这官方文档到底自己没有进行更新我就不知道了࿰

  • 9
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
BLE低功耗蓝牙)是一种通过蓝牙无线技术进行低功耗通信的协议。它是在传统蓝牙(Classic Bluetooth)的基础上发展而来,主要用于物联网、智能家居和健康追踪等领域。 BLE主要特点有以下几个方面: 1. 低功耗BLE采用了一种优化的通信方式,使设备在通信过程中的功耗大大降低,从而延长了设备的电池寿命,这对于需要长时间运行的设备非常重要。 2. 简化传输:BLE使用了一种称为GATT(通用属性)的协议,将数据分为服务和特征,通过读、写或订阅操作来传输数据,这种简化了传输过程,减少了额外的开销。 3. 快速连接:BLE的连接速度比传统蓝牙更快,可以在几十毫秒内建立连接,这对于移动设备和传感器等需要快速响应的设备非常重要。 4. 多设备连接:BLE支持同时连接多个设备,可以通过同一个移动设备与多个BLE设备进行通信,提高了系统的灵活性和可扩展性。 Android提供了一套完整的BLE开发API,开发者可以使用这些API来实现BLE通信功能。在Android中,开发BLE应用涉及到四个主要组件:BLE设备扫描、设备连接、数据传输和GATT服务管理。 开发者可以使用AndroidBluetoothAdapter类来进行设备扫描和连接操作,可以通过BluetoothGatt类来进行GATT服务的操作,包括读、写、订阅等。 总之,BLE作为一种低功耗蓝牙通信协议,在物联网和智能设备领域应用广泛。在Android平台上进行BLE开发,可以借助Android提供的API,快速实现BLE通信功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值