深入了解Android蓝牙Bluetooth ——《总结篇》

在我的上两篇博文中讲解了有关android蓝牙的认识以及API的相关的介绍,蓝牙BLE的搜索,连接以及读取。

没有了解的童鞋们请参考:

  1. 深入了解Android蓝牙Bluetooth——《基础篇》
  2. 深入了解Android蓝牙Bluetooth——《进阶篇》

目前项目中的效果图:

接下来我们就对蓝牙BLE4.0进行一下总结。

蓝牙API

Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的哦

1. BluetoothGatt

继承BluetoothProfile,通过BluetoothGatt可以连接设备(connect),发现服务(discoverServices),并把相应地属性返回到BluetoothGattCallback

2. BluetoothGattCharacteristic

 相当于一个数据类型,它包括一个value和0~n个value的描述(BluetoothGattDescriptor)

3. BluetoothGattDescriptor

描述符,对Characteristic的描述,包括范围、计量单位等
  1. BluetoothGattService

    服务,Characteristic的集合。

  2. BluetoothProfile

    一个通用的规范,按照这个规范来收发数据。

  3. BluetoothManager

    通过BluetoothManager来获取BluetoothAdapter

    BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
  4. BluetoothAdapter

    一个Android系统只有一个BluetoothAdapter ,通过BluetoothManager 获取

    BluetoothAdapter mBluetoothAdapter = bluetoothManager.getAdapter();
    1.8 BluetoothGattCallback

    已经连接上设备,对设备的某些操作后返回的结果。这里必须提醒下,已经连接上设备后的才可以返回,没有返回的认真看看有没有连接上设备。

    private BluetoothGattCallback GattCallback = new BluetoothGattCallback() {
        // 这里有9个要实现的方法,看情况要实现那些,用到那些就实现那些
        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState){};
        public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status){};
    };
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
    BluetoothGatt gatt = device.connectGatt(this, false, mGattCallback);
  5. notification对应onCharacteristicChanged
    gatt.setCharacteristicNotification(characteristic, true);
  6. readCharacteristic对应onCharacteristicRead
    gatt.readCharacteristic(characteristic);
  7. writeCharacteristic对应onCharacteristicWrite

    gatt.wirteCharacteristic(mCurrentcharacteristic);

  8. 连接蓝牙或者断开蓝牙 对应 onConnectionStateChange
  9. readDescriptor对应onDescriptorRead;
  10. writeDescriptor对应onDescriptorWrite;
    gatt.writeDescriptor(descriptor);
  11. readRemoteRssi对应onReadRemoteRssi

    gatt.readRemoteRssi()

  12. executeReliableWrite对应onReliableWriteCompleted;
  13. discoverServices对应onServicesDiscovered
    gatt.discoverServices()
  14. BluetoothDevice

    扫描后发现可连接的设备,获取已经连接的设备

二、开启蓝牙权限

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

Android ble 蓝牙4.0,也就是说API level >= 18,且支持蓝牙4.0的手机才可以使用,如果手机系统版本API level < 18,也是用不了蓝牙4.0的

if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
    Toast.makeText(this, "设备不支持蓝牙4.0", Toast.LENGTH_SHORT).show();
    finish();
}

或者是

// 检查当前手机是否支持blue 蓝牙,如果不支持退出程序
        if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
            showToast("不支持蓝牙4.0通讯");
            return;
        }
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

        final BluetoothManager bluetoothManager =
                (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
        mBluetoothAdapter = bluetoothManager.getAdapter();
        // 检查设备上是否支持蓝牙
        if (mBluetoothAdapter == null) {
            showToast("没有发现蓝牙模块");
            return;
        }

三、对蓝牙的启动关闭操作

  • isEnabled()

    如果本地蓝牙处在可用状态(例如手机蓝牙开启)就返回true

  • getState()

    获得蓝牙状态 一般有BluetoothAdapter.STATE_BLE_ON ,STATE_BLE_TURNING_ON ,STATE_BLE_TURNING_OFF ,STATE_OFF

  • enable()

    打开蓝牙设备,这种方式不友好,建议使用下面方法

    Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

    startActivityForResult(intent,OPEN_REQUEST_CODE);

    这样会有个弹窗提示用户是否开启蓝牙

  • disable()

    关闭所有的蓝牙连接后关闭本地蓝牙服务

  • getAddress()

    获得蓝牙mac地址

  • getName()

    获得蓝牙名称,也就收我们经常设置的蓝牙名称

  • setName()

    设置蓝牙名称

  • startDiscovery()

    开始发现设备(注意是设备,例如另外一个手机,而不是蓝牙耳机之类的)

  • getBondedDevices()

    获取绑定(配对)的设备,测试发现只有手动取消绑定才管用,否则即使关闭蓝牙,间隔一会再打开,这些仍然是绑定的.

    同时一些绑定的设备(例如手环)用这个方法并没有返回对应的device

  • startLeScan(LeScanCallback)

    开始对Bluetooth LE devices设备(蓝牙耳机,手环,电子称等)的扫描.回调函数会把扫描到的设备返回,

    注意设备会重复被扫描到,最好去掉重复,去重时可以用mac地址,也可以用名称,但是扫描到的Device第一次没有把

    名称带回,所以获取名称时最好做非空判断

  • stopLeScan(LeScanCallback)

    停止扫描

  • >利用系统默认开启蓝牙对话框
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

Android蓝牙服务的相关类简介之BluetoothGatt

Generic Attribute Profile (GATT)—The GATT profile is a general specification for sending and receiving short

pieces of data known as “attributes” over a BLE link. All current Low Energy application profiles are based on

GATT.主从设备都维护了GATT 分别是client 和 server

  • 获得方法,创建连接时返回

    mConnGatt = bleDevie.connectGatt(this, false, mGattcallback);
    

回调

    public abstract class BluetoothGattCallback {

    public void onConnectionStateChange(BluetoothGatt gatt, int status,
                                        int newState) {
    }

    public void onServicesDiscovered(BluetoothGatt gatt, int status) {
    }

    public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,
                                     int status) {

    public void onCharacteristicWrite(BluetoothGatt gatt,
                                      BluetoothGattCharacteristic characteristic, int status) {
    }

    public void onCharacteristicChanged(BluetoothGatt gatt,
                                        BluetoothGattCharacteristic characteristic) {
    }

设置通知

    public boolean setCharacteristicNotification(UUID serviceUuid, UUID characteristicUuid, boolean enable) {
    BluetoothGattCharacteristic characteristic = mConnGatt.getService(serviceUuid).getCharacteristic(characteristicUuid);
    mConnGatt.setCharacteristicNotification(characteristic, enable);
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(CHARACTERISTIC_UPDATE_NOTIFICATION_DESCRIPTOR_UUID);
    descriptor.setValue(enable ? BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE : new byte[]{0x00, 0x00});
    return mConnGatt.writeDescriptor(descriptor); // descriptor write
}

曾经遇到的坑

  • 蓝牙接连时超时

    解决方法:

    在广播中相应的方法里进行重新连接

    private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
    
            @Override
            public void onReceive(Context context, Intent intent) {
                final String action = intent.getAction();
                if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {//蓝牙已连接
                    tvBluetooth.setText("(已连接)");
                } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {
                    showToast("蓝牙连接断开,请重试");
                    //这里重新连接蓝牙
                    hideLoading();
                } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {//发现蓝牙,设置命令
                    ......
                } else if(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { //接收到数据
                   ......
                }
            }
        };
  • 蓝牙搜索进行匹配不来BLE设备

    有些手性能比较低端,这里可以重启蓝牙,进行重新连接

  • ##### 连接成功后断开
    1. 保证BLE小设备没有被其他连接
    2. 先停止扫描—》重新扫描—》重新连接
  • 读取过程中蓝牙断开

    首先要保证连接蓝牙之前,上一次断开连接时的操作:

    1. 断开连接
    2. 断开(关闭)service
    3. 关闭蓝牙

    然后执行:

    先停止扫描—》重新扫描—》重新连接

  • ##### 上传数据失败

    把读取到的数据解析后进行保存在本地,下次上传的时候一起上传。上传成功后记得进行本低数据的清空

注意:BLE蓝牙连接小设备时一般属于主从模块,其中主模块蓝牙可以同时连接多个设备,但读取时只能读取一个。
有关项目下载地址: http://download.csdn.net/detail/lqw770737185/8116019
GitHub下载链接:https://github.com/androidstarjack/Bluetooth_4.3-master

接下来推荐两个关于Android蓝牙BLE的学习网址:

详细解析BluetoothAdapter的详细api

http://www.open-open.com/lib/view/open1390879771695.html

Android:蓝牙4.0-BLE-小结=1.0

http://www.itnose.net/detail/6095842.html

如果你觉得此文对您有所帮助,欢迎入群 QQ交流群 :232203809 ??

微信公众号:终端研发部

(欢迎关注学习和交流)

时间: 2024-08-04 20:57:34

深入了解Android蓝牙Bluetooth ——《总结篇》的相关文章

深入了解Android蓝牙Bluetooth——《进阶篇》

在 [深入了解Android蓝牙Bluetooth--<基础篇>](http://blog.csdn.net/androidstarjack/article/details/60468468)一篇中我们对蓝牙的各个版本的有了一个认识,蓝牙版本的历程及其优劣式介绍.那么接下来咱们就深入一点继续开车进入BLE的进及篇章. 蓝牙BLE4.x BLE分为三部分: Service Characteristic Descriptor 这三部分都用UUID作为唯一标识符.UUID为这种格式:0000ffe1

android -- 蓝牙 bluetooth (五)接电话与听音乐

前段时间似乎所有的事情都赶在一起,回家.集体出游.出差,折腾了近一个月,终于算暂时清静了,但清静只是暂时,估计马上又要出差了,所以赶紧把蓝牙这一部分的文章了结下,按之前提到的目录,本文是关于蓝牙接打电话和听音乐的流程分析,对应蓝牙HFP/A2DP的profile,由于这部分也算是蓝牙的经典功能,所以代码流程并不是很复杂,当然不复杂仅是对于代码调用流程而言,对于HFP/A2DP协议相关的东东还没有精力去看,其难易程序也无法评价.下面从两个点HFP与A2DP来展开本文的代码跟踪: 正文开始之前,先说

android -- 蓝牙 bluetooth (三)搜索蓝牙

接上篇打开蓝牙继续,来一起看下蓝牙搜索的流程,触发蓝牙搜索的条件形式上有两种,一是在蓝牙设置界面开启蓝牙会直接开始搜索,另一个是先打开蓝牙开关在进入蓝牙设置界面也会触发搜索,也可能还有其它触发方式,但最后都要来到BluetoothSettngs.java的startScanning(),我们分析的起点也从这里开始,起步代码如下 [cpp] view plaincopy private void updateContent(int bluetoothState, boolean scanState

android -- 蓝牙 bluetooth (四)OPP文件传输

在前面android -- 蓝牙 bluetooth (一) 入门文章结尾中提到了会按四个方面来写这系列的文章,前面已写了蓝牙打开和蓝牙搜索,这次一起来看下蓝牙文件分享的流程,也就是蓝牙应用opp目录下的代码,作为蓝牙最基本的一个功能,这部分的代码在之前的版本中就已经有了,新旧版本代码对比很多类名都是一样的,这一部分新东西不多,写在这里帮助大家梳理下流程吧. 有没有这种感觉,智能手机的普及让我们提高了一点对蓝牙的关注,手机间使用蓝牙互传文件应该是最常用的应用之一,手机与电脑也可以通过蓝牙做同样的

Android应用开发进阶篇-场景文字识别

由于研究生毕业项目需要完成一个基于移动终端的场景文字识别系统,虽然离毕业尚早,但出于兴趣的缘故,近一段抽时间完成了这样一套系统.基本的架构如下: 客户端:Android应用实现拍摄场景图片,大致划出感兴趣文字区域,通过socket通信上传服务器端识别; 服务器端:Python server进行socket通信监听,连通后调用文字识别引擎(exe可执行程序),将识别结果返回; 下面是系统运行示例图: 1. 客户端 包含两个Activity,: MainActivity主界面如上图左1,选择拍摄后调

深入了解Android蓝牙Bluetooth——《基础篇》

什么是蓝牙? ??也可以说是蓝牙技术.所谓蓝牙(Bluetooth)技术,实际上是一种短距离无线电技术,是由爱立信公司公司发明的.利用"蓝牙"技术,能够有效地简化掌上电脑.笔记本电脑和移动电话手机等移动通信终端设备之间的通信,也能够成功地简化以上这些设备与因特网Internet之间的通信,从而使这些现代通信设备与因特网之间的数据传输变得更加迅速高效,为无线通信拓宽道路. 蓝牙版本的介绍 ??蓝牙发展至今经历了8个版本的更新.1.1.1.2.2.0.2.1.3.0.4.0.4.1.4.2

android -- 蓝牙 bluetooth (一) 入门

前段时间在 网上看了一些关于android蓝牙的文章,发现大部分是基于老版本(4.1以前含4.1)的源码,虽然无碍了解蓝牙的基本原理和工作流程,但对着4.2.2的代码看起来总是有些遗憾.所以针对4.2.2版本代码整理下相关知识,当然蓝牙工作的主干流程是没有变的,上电.加载驱动这些动作少不了的,只是这些功能的实现代码位置变了不少.希望本文可以让大家对android4.2的蓝牙部分代码有一个初步的了解.         正文开始前,先明确代码版本:android  jellyBean 4.2.2,后

android -- 蓝牙 bluetooth (二) 打开蓝牙

4.2的蓝牙打开流程这一部分还是有些变化的,从界面上看蓝牙开关就是设置settings里那个switch开关,widget开关当然也可以,起点不同而已,后续的流程是一样的.先来看systemServer.java的代码,蓝牙服务开启的地方,最后一个else分支是我们关心的,前两个是模拟器的一个测试模式的. [java] view plaincopy if (SystemProperties.get("ro.kernel.qemu").equals("1")) { S

Android 蓝牙(Bluetooth)(二)

Android4.3 规范了BLE的API,但是直到目前的4.4,还有些功能不完善. 在BLE协议中,有两个角色,周边(Periphery)和中央(Central):周边是数据提供者,中央是数据使用/处理者:在iOS SDK里面,可以把一个iOS设备作为一个周边,也可以作为一个中央:但是在Android SDK里面,直到目前最新的Android4.4.2,Android手机只能作为中央来使用和处理数据:那数据从哪儿来?从BLE设备来,现在的很多可穿戴设备都是用BLE来提供数据的. 一个中央可以同