zoukankan      html  css  js  c++  java
  • Android低功耗蓝牙(蓝牙4.0)——BLE开发(上)

    段时间,公司项目用到了手机APP和蓝牙设备的通讯开发,这里也正好对低功耗蓝牙(蓝牙4.0及以后标准)的开发,做一个总结。

    蓝牙技术联盟在2010年6月30号公布了蓝牙4.0标准,4.0标准在蓝牙3.0+HS标准的基础上增加了对低功耗蓝牙(BLE)的支持。相比原有的普通蓝牙和高速蓝牙,BLE最大的特点就是低功耗,低延时,快速的搜索和连接速度,但数据传输速度相比传统蓝牙低。接下去将从BLE的概念以及代码两个方面介绍Android下的BLE。

    先来说说基本概念:

    1.BLE相关概念

    1.1 GATT、Service、Characteristic、Descriptor

    BLE开发,经常会与四个概念发生关系:GATT、Service、Characteristic、Descriptor

    • GATT:是蓝牙4.0特有的Profile通用规范,BLE应用的Profile均基于GATT。Gatt定义了一个服务框架规范,该框架包括对蓝牙服务(Service)和服务特性(Characteristic)的定义和规范,和其中读写、通知的特性等。可以将GATT理解成BLE框架,我们在GATT上面实现BLE功能。
    • Service:是完成一个特定功能的数据和行为集合。在Gatt中,一个Service可能包含Service引用以及强制或者可选的Characteristic。
    • Characteristic:也叫特征值,一个Characteristic的定义包含了Characteristic本身,数值以及描述(Descriptor)的声明。Characteristic是完成BLE具体功能的基本单位。
    • DescriptorDescriptor定义了Characteristic中数据的具体含义。

      总的来说,一个蓝牙4.0的终端可以包含多个Service,一个Service可以包含多个Characteristic,一个Characteristic包含一个Value和多个Descriptor,一个Descriptor包含一个Value

     

    1.2 中央(Central)与周边(Periphery)

    在BLE协议中,有两个角色,周边(Periphery)和中央(Central):

    周边是数据提供者,中央是数据使用/处理者;在iOS SDK里面,可以把一个iOS设备作为一个周边,也可以作为一个中央;但是在Android SDK里面,Android手机只能作为中央来使用和处理数据;那数据从哪儿来?从BLE设备来,现在的很多可穿戴设备都是用BLE来提供数据的。

    一个中央可以同时连接多个周边,但是一个周边某一时刻只能连接一个中央。

    那么问题来了,如何定义周边和中央?

    关于周边和中央,涉及到四个类:

    • BluetoothGattServer:作为周边来提供数据
    • BluetoothGattServerCallback:返回周边的状态
    • BluetoothGatt:作为中央来使用和处理数据
    • BluetoothGattCallback:返回中央的状态和周边提供的数据。、

    关系如图下:

    2. 开发Ble

    了解了那些基础概念后,我们就正式开始开发ble。

    Ble的Android开发,主要是以下的几个步骤:

    1、添加权限

    2、扫描Ble设备

    3、连接Ble设备

    4、数据通讯

     那么现在,开始一步步来完成。

    2.1 添加权限:

    在AndroidManifest.xml中添加Ble需要的权限,其实就两个:

    <!-- 应用使用蓝牙的权限 -->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <!-- 扫描蓝牙设备或者操作蓝牙设置 -->
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

    2.2 检查是否设备是否支持蓝牙,并打开蓝牙

    检查设备是否支持蓝牙

         /**
         * 检查该设备是否支持蓝牙
         */
        public void isBle(Context context) {
            //手机硬件支持蓝牙
            if (!context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
                ViewUtils.getInstance().showToast("该设备不支持BLE,即将离开改页面");
            }
        }

    打开手机蓝牙开关

        private BluetoothAdapter mBluetoothAdapter;//蓝牙适配器
    
    
        //打开蓝牙权限
        if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
             Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
             startActivityForResult(enableBtIntent, What.Bluetooth.bluetoothEnable);
       }

    2.3 扫描设备

     开始扫描和停止扫描,只需要调用对应的startLeScan()和stopLeScan()即可,但是需要将LeScanCallBack作为参数:

        // 超时时间
        private static final long SCAN_PERIOD = 10000;
        ...
        private void scanLeDevice(final boolean enable) {
            if (enable) {
                // 达到超时时间,停止扫描
                mHandler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        mScanning = false;
                        mBluetoothAdapter.stopLeScan(mLeScanCallback);
                    }
                }, SCAN_PERIOD);
                //开始扫描
                mBluetoothAdapter.startLeScan(mLeScanCallback);
            } else {
                //停止扫描
                mBluetoothAdapter.stopLeScan(mLeScanCallback);
            }
            ...
        }

    LeScanCallBack的实现:

    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
        @Override
        public void onLeScan(final BluetoothDevice device, int rssi,
                byte[] scanRecord) {
            runOnUiThread(new Runnable() {
               @Override
               public void run() {
                   // TODO: 2017/9/18  
               }
           });
       }
    };

    上面的代码中:

    • SCAN_PERIOD:扫描时长,毫秒数,需要注意的是,蓝牙设备扫描很耗电,这个时间不易设置太长,在扫描成功后就要停止设备扫描。
    • BluetoothDevice:蓝牙设备的相关类,通过他,可以获取蓝牙设备的很多信息

     如果只想扫描指定类型的外围设备,你可以调用startLeScan(UUID[], BluetoothAdapter.LeScanCallback),提供一个指定了你app支持的GATT服务的UUID数组对象。

     2.3 连接GATT服务端

    与BLE设备通讯的前提就是连接GATT服务端,GATT概念之前已经讲过了,调用connectGatt()就可以了,不过需要三个参数:这个方法需要三个参数,一个Context对象,autoConnect(一个指示是否自动连接到BLE设备--当它一旦可用的时候--的布尔值),和一个 BluetoothGattCallback的引用:

    mBluetoothGatt = device.connectGatt(this, false, mGattCallback);

    这个方法会返回一个BluetoothGatt,用它可以对GATT进行操作。

    具体怎么操作呢?下篇博客再说。


    这是我的个人微信公众号:感兴趣的可以关注一下,里面分享一些搞机视频,程序员嘛!学会骚,很重要:

  • 相关阅读:
    mysql json 嵌套数组查询
    Centos 部署 mysql
    Mysql8.0 导出数据库文档
    MySQL常用Json函数
    java Dateutil 操作类
    雪花算法生成的ID,前端无法使用
    Mysql 一个字段匹配多个字符
    EntityManager 获取 List<T>
    高级软件工程第二次作业:随机生成N个不重复的已解答完毕的数独棋盘
    调研《构建之法》指导下的全国高校优秀实践作品三篇
  • 原文地址:https://www.cnblogs.com/YaoJianXun/p/7495855.html
Copyright © 2011-2022 走看看