【Android】Android BLE开发

目录

1. 功能部分

1.1 BLE简介

1.2. 详细流程

1.3 几个注意点:

2. 界面部分

3. 遇到的坑:

4. 推荐学习资料



即将迈入新阶段,贼开心,总结下。如果有误,麻烦指出。

先看下最终效果(图中的“刷新”只是方便测试,表明从硬件接收到了新的数据包而已):

1. 功能部分

1.1 BLE简介

核心功能使用的是Android官方提供的BLE SDK。在BLE协议中,有两个角色——周边和中央。周边用来提供数据,中央用来使用数据。在我的应用中,周边即BLE模块,中央即安卓手机。

先介绍2个关键类:

(1)BluetoothGattServer作为周边来提供数据;BluetoothGattServerCallback返回周边的状态。

(2)BluetoothGatt作为中央来使用和处理数据;BluetoothGattCallback返回中央的状态和周边提供的数据。

我们要做的是什么呢?是拿到这个BluetoothGatt!拿到了它,调用API中提供的方法,就可以通过BluetoothGattCallback和周边BluetoothGattServer交互了。

协议、服务(Service)、特征(Characteristic)等基本概念参考

1.2. 详细流程

我把Android蓝牙开发分为3个大步骤:扫描、连接和交互。

(1).声明BLE相关权限。

        <uses-permission android:name="android.permission.BLUETOOTH" />
        <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

(2).判断设备是否支持BLE,若支持,则获取到设备的蓝牙适配器。

        //检查设备是否支持BLE
        if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)){
            Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
            finish();
        }

        //蓝牙管理器,主要用于获取蓝牙适配器和管理所有和蓝牙相关的东西。
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);

        //用蓝牙管理器获得蓝牙适配器,每一台支持蓝牙功能的手机都有一个蓝牙适配器。
        mBluetoothAdapter = bluetoothManager.getAdapter();

        //检查设备是否支持BLE
        if(mBluetoothAdapter == null){
            Toast.makeText(this, R.string.bluetooth_not_supported, Toast.LENGTH_SHORT).show();
            finish();
            return;
        }

        //andoird 6.0需要开启定位请求
        mayRequestLocation();

(3).判断当前手机是否已经开启了蓝牙功能,若未开启,提示用户开启蓝牙功能。(跟共享单车APP里的步骤一样一样的)

        //如果当前手机蓝牙未开启,弹出dialog提示用户开启。
        if(!mBluetoothAdapter.isEnabled()){
            if(!mBluetoothAdapter.isEnabled()){
                Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
            }
        }

(4).扫描周边BLE设备,获取扫描到的设备。

        mBluetoothAdapter.startLeScan(mLeScanCallback);//扫描很费电,要预设扫描周期,扫描一定周期就停止扫描
            //作为BLE扫描结果的接口,实现如下。
        private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                   ...
                }
            };

(5).调用连接到GATT服务端的方法;

            mBluetoothGatt = device.connectGatt(this, false, mGattCallBack);//这个mBluetoothGatt很关键,后面要调用这个类的方法。

到此为止,已经有了一个成果——已经拿到了BluetoothGatt!!!

(6).连接到GATT服务端成功后,发现服务;发现服务并成功获取服务后,获取特征值,得到属性为Write和Notify的特征值,获取到特征值即代表手机与蓝牙设备连接成功;然后使能属性为Noitfy的特征值,只有使能特征值之后,特征值发生改变,才会马上回调到onCharacteristicChanged()中。

        private final BluetoothGattCallback mGattCallBack = new BluetoothGattCallback() {
            @Override
            public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { //连接状态改变时候回调到此处
                if(newState == BluetoothProfile.STATE_CONNECTED){
                    //连接上之后发现服务
                    mBluetoothGatt.discoverServices();
                    ...
            }

            //发现到服务之后回调到此处
            @Override
            public void onServicesDiscovered(BluetoothGatt gatt, int status) {
                    //优先根据xxx蓝牙模块的服务UUID来查找服务
                    BluetoothGattService service = gatt.getService(UUID.fromString(BleGattAttributes.BLE_Service));
                    if(service != null){
                        //根据xxx蓝牙模块的特征值UUID来查找特征值
                        mWriteCharacteristic = service.getCharacteristic(UUID.fromString(BleGattAttributes.BLE_Write_Characteristic));
                        mNotifyCharacteristic = service.getCharacteristic(UUID.fromString(BleGattAttributes.BLE_Notify_Characteristic));
                    }
    
                    if(mNotifyCharacteristic != null){
                        //找到特征值才代表连接成功
                        //使能通知,使能属性为Notify的特征值之后,以后特征值改变时候,就会回调到onChracteristicChanged()中。
                        setCharacteristicNotification(mNotifyCharacteristic, true);
                    }
            }

            //读取特征值后回调到此处
            @Override
            public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                ...
            }

            //特征值发生改变时回调到此处
            @Override
            public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
                ...
            }

            //写入特征值后回调到此处
            @Override
            public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
                ...
            }

        };

(7).接下来手机就可与蓝牙模块交互了。即调用发送函数,向蓝牙模块发送数据包;有数据包返回时候,会回调到onCharactericChanged()中。

        //向蓝牙设备发送数据          
        mWriteCharacteristic.setValue(data);
        mBluetoothGatt.writeCharacteristic(mWriteCharacteristic);

(8).按照协议对收到的数据帧进行解析并显示。我的处理是把解析出来的数据存放到全局变量中,便于在Fragment中使用,然后适配器负责把这些数据与界面联接起来。

(9).数据需要定时更新的情况下,按照一定的周期重复步骤7、8。

1.3 几个注意点:

(1)BLE要求每包数据最多20字节,如果数据量大于20字节,难免要分包发送再拼接下,拼接后再处理。所以BLE更适合小数据量的应用,用来传递音视频的话,可能心会比较累……
(2)我是对拼接后的数据包处理了一下,判断了下拼接后的数据包的正误才处理的(不知道是否必要,不过加了更安全),有空贴出来我的写法。

2. 界面部分

整体采用界面效果跟微信相似,底部导航栏+ViewPager实现了滑动切换Fragment的效果,某些需要显示信息量大的页面采用ListView。

ListView的使用:其中第3、4个页面用的是列表,以第3个页面为例说明ListView的用法。第3个页面中的ListView中要装入的是单体电压数据,但是数组cellVoltage中的数据是无法直接传给ListView的,需要借助适配器来实现。我选择的适配器是ArrayAdapter(因为它可以通过泛型来指定要适配的数据类型),在构造适配器对象时候,将要用的列表样式和数据源作为参数传递进去。然后,将实例化出来的列表对象和构造出来的适配器关联在一起。Ok啦。

ViewPager的使用:ViewPager是一个页面切换的组件,可以往里面填充多个View,通过触摸屏左右滑动来切换不同的View。和ListView一样,需要一个适配器(适配器的作用:将复杂的数据填充在指定视图界上,数据源多种多样,而ListView等组件显示数据的格式是有要求的,适配器就是桥梁),将要显示的View和我们的ViewPager进行绑定,而ViewPager有自己特定的Adapter—PagerAdapter。ViewPager实现

3. 遇到的坑:

  1. 功能部分,上下位机数据交互时候(上位机指手机,下位机指带有BLE模块的硬件系统),读到的数据比较混乱,没有按照请求的包的顺序来收发。经过debug单步调试,找到了原因:在上下位机数据交互时,数据的载体是一个叫做“特征值”的东西(基本概念的介绍有空再加上),上下发送数据时候,都会改动这个特征值,两方同时操作一个特征值,不出现混乱才奇怪呢。解决方法是:当收到了下位机回复的第i包数据时候,上再向下要第i+1包数据,具体来说是这样的顺序:(假设一次数据更新分为了5包数据)上向下发送命令包1——>下向上回复数据包1——>上向下发送命令包2——>下向上回复数据包2——>…——>上向下发送命令包5——>下向上回复数据包5。严格控制这样的顺序,保证了每个时刻,上位机和下位机只有一个在操作特征值。
  2. 界面部分,左右滑动来切换页面的功能最初用了一个库,但是实验过程中发现,当数据刷新频率很快且左右滑动频率很快时候,边缘的页面(最靠右边的或者倒数第二个)就会崩溃。原因我认为在于库中对ViewPager的缓存机制用得不好。(ViewPager的缓存机制:ViewPager不仅会缓存当前页、还会缓存前一页和后一页,比如当前位于第2页,就会缓存第1、2、3页;比如当前位于第4页时候,缓存的是3和4)。后来我就索性自己实现了下这个功能。

4. 推荐学习资料

Android:

《第一行代码》郭霖,适合安卓新手学习。pdf下载

 

BLE:

https://blog.csdn.net/jimoduwu/article/details/21604215

https://www.jianshu.com/p/c7bb4e8f9fe6

https://developer.android.com/guide/topics/connectivity/bluetooth-le#terms //Andoid BLE开发官方文档

https://blog.csdn.net/shb2058/article/details/51279731 //Andoid BLE开发官方文档中文翻译

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: Android BLE开发是指在Android平台上使用蓝牙低功耗BLE)技术进行应用程序开发BLE是一种省电的蓝牙通信技术,被广泛应用于智能穿戴设备、医疗设备、家居设备等领域。 Android平台提供了一套完整的API来支持BLE开发开发者可以使用这些API来搜索和连接BLE设备、发送和接收数据、读取和写入BLE特征值等等。 首先,开发者需要在AndroidManifest.xml文件中添加必要的权限,如蓝牙蓝牙管理器权限。然后,在代码中实例化一个BluetoothManager对象来获取BluetoothAdapter(蓝牙适配器)实例。 接下来,开发者可以使用BluetoothAdapter的方法来搜索和连接BLE设备。搜索时,可以通过实现BluetoothAdapter.LeScanCallback接口来获取搜索到的设备信息。连接时,可以通过实现BluetoothGattCallback接口来处理与设备的通信。 一旦成功连接到BLE设备,开发者可以使用BluetoothGatt对象来发送和接收数据。通过BluetoothGatt对象,可以发现服务和特征值,读取和写入特征值等等操作。同时,开发者也可以监控设备发出的通知和指示。 在开发过程中,开发者还需要注意BLE通信的一些特点。例如,BLE是基于事件驱动的,所以开发者需要处理相关的回调方法;BLE设备的连接是一种异步过程,所以开发者需要在连接过程中处理各种状态;BLE通信是基于GATT协议,开发者需要熟悉相关的概念和操作等。 总而言之,Android BLE开发提供了一种在Android平台上与BLE设备进行通信的方式。通过使用AndroidBLE API,开发者可以方便地实现与BLE设备的连接和数据传输,为开发各种BLE应用程序提供了便利。 ### 回答2: Android BLE开发是指在Android设备上使用BLE蓝牙低功耗)技术进行应用开发的过程。BLE是一种蓝牙技术,相比传统的蓝牙技术具有低功耗、简单、成本低等优势,适用于低功耗设备之间的通信。 在Android BLE开发中,首先需要通过在AndroidManifest.xml文件中声明蓝牙权限来获取蓝牙访问权限。然后,需要使用BluetoothAdapter类来获取蓝牙适配器,并检查设备是否支持BLE功能。 接下来,在开发中需要使用BluetoothGatt类来建立与远程BLE设备的连接和通信。使用BluetoothGattCallback类可以监听到连接状态的改变,以及接收到的数据。 在与BLE设备通信时,需要使用GATT(通用属性配置配置文件)协议来发送和接收数据。GATT协议通过将数据分为服务(Service)和特征(Characteristic)进行管理。服务代表一个特定的功能,而特征代表服务的具体属性。 在开发过程中,还可以使用BluetoothLeScanner类进行扫描周围的BLE设备。当发现设备后,可以通过BluetoothDevice类来获取设备的详细信息,如设备名称、MAC地址等。 总结来说,Android BLE开发需要了解蓝牙低功耗技术以及相关API的使用。通过建立连接、发送数据、接收数据等操作,可以实现与BLE设备的通信。开发人员需要注意处理连接状态、数据解析等问题,以确保应用的可靠性和稳定性。 ### 回答3: Android BLE开发是指基于Android系统的蓝牙低功耗(Bluetooth Low Energy,以下简称BLE)技术进行应用开发的过程。 在Android BLE开发中,首先需要进行设备扫描。通过使用与蓝牙相关的API,我们可以搜索附近的BLE设备并获取设备的相关信息,例如设备名称、信号强度、MAC地址等。扫描到设备后,可以使用设备的唯一标识符(UUID)进行连接。 连接设备后,可以进行数据通信。BLE通信主要通过GATT(通用属性配置文件)协议进行,该协议规定了BLE设备和Android应用之间的数据传输格式和规则。开发者可以通过GATT API访问BLE设备的服务和特征,读取和写入相应的属性值。 在数据通信过程中,也可以进行数据处理。开发者可以对从BLE设备接收到的数据进行解析、处理和展示。例如,对传感器采集的数据进行分析、计算和展示,或者根据接收到的数据进行特定的操作和控制。 在开发过程中,还需要注意一些注意事项。例如,保持正确的扫描周期,避免频繁的连接和断开操作,合理处理设备不可用的情况等等。此外,对于BLE通信的兼容性,开发者应考虑不同设备的支持情况,以确保应用在各种Android设备上的正常运行。 总结来说,Android BLE开发是在Android平台上利用BLE技术进行应用开发的过程。通过设备扫描、连接和数据通信,开发者可以实现与BLE设备之间的无线数据交互。通过合理的数据处理和注意事项的考虑,可以提高应用的稳定性和可靠性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值