美文网首页
Android蓝牙4.0(BLE)

Android蓝牙4.0(BLE)

作者: Chenyangqi | 来源:发表于2019-03-25 23:47 被阅读0次

    概念

    • BLE (Bluetooth Low Energy),又叫蓝牙4.0
    • 传统经典蓝牙,蓝牙 3.0-
    • 单模 & 双模(同时支持BLE和传统蓝牙)

    基础概念

    • 设备角色
      1.中心设备(Centeal):中心设备相对比较强大,用来连接其他外围设备。例如:手机
      2.外围设备(Peripheral):一般是非常小的或者简单的低功耗设备,用来提供数据,并连接到一个更加相对强大的中心设备,例如小米手环,只能体温计,智能锁等
      3.理论上,一个蓝牙主端设备,可同时与7个蓝牙从端设备进行通讯
      4.一个从设备只能被一个主设备连接
      5.一旦从设备连接上主设备,就停止广播,断开连接则继续广播
      6.在任何时刻只能一个设备尝试建立连接

    • GATT
      1.GATT(Generic Attribute Profile):通用属性配置文件
      2.GATT定义了两个BLE设备通过Service和Characteristic进行通信的Profile
      3.中心设备和外设唯一的通信方式就是建立GATT连接
      4.GATT通信的双方是C/S关系
      5.GATT连接是独占的
      6.GATT规定一个智能设备能有一个或者多少个Service

    • Service
      Service是一个个独立的逻辑项,它包含一个或者多个Characteristic

    • Characteristic
      Characteristic是最小的逻辑数据单元,他包含一个关联的数据值

    • Descriptor
      Description是对Characteristic的描述,例如范围,计量单位等


      image.png
    //获取智能设备所有的服务Service
    List<BluetoothGattService> services=(BluetoothGatt)gatt.getServices();
    //获取智能设备某个服务的Service下所有的特征Characteristic
    List<BlueToolthGattCharacteristic> characteristics=(BluetoothGattService)service.getCharacteristic();
    //获取智能设备的摸个特征
    List<BluetoolthGattDescriptors> descriptors=(BluetoothGattCharacteristic)characteristic.getDescriptors();
    
    • UUID
      唯一标识码
      每一个Service和Characteristic和Descriptor都有一个唯一的标识UUID
      UUID可以用16bit和128bit标识。16bit收费,128bit免费,开发中常用128bit的UUID
    //获取指定的UUID的Service
    public BluetoothGattService getService(UUID uuid);
    //获取指定UUID的Characteristic
    public BluetoothGattCharacteristic getCharacteristic(UUID uuid);
    //获取指定的UUID的Descriptor
    public BluetoothGattDescriptor getDescriptor(UUID uuid);
    

    Gatt下有哪些Service,某个Service下有哪些Characteristic,某个Characteristic下有哪些Descriptor,以及他们的UUID都是固件工程师提供!

    BLE通信流程

    1.主设备APP扫描,搜索外围只能设备
    2.简历BLE蓝牙连接
    3.基于BLE蓝牙连接进行数据通信

    SDK版本前提

    • 主设备Android 4.3+(API Level>=18)
    • 请求权限 targetSdkVersion <= 22
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
    
    • 如果需要targetSdkVersion >=23
      需要获取如下两个权限,GPS定位和电信运营商基站定位权限
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    

    主设备打开蓝牙

    final BluetoothManager bluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
    BluetoothAdapter mBtAdapter = bluetoothManager.getAdapter();
    //未开启蓝牙
    if(mBtAdapter!=null&&!mBtAdapter.isEnable()){
          //一种方式是程序主动启动蓝牙
          mBtAdapter.enable();
          //一种方式是采用体统友好提示用户开启蓝牙
          Intent intent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
          startActivityForResult(intent,REQUEST_ENABLE_BT);
    }
    
    • 蓝牙的打开和关闭过程如下:
      BluetoothAdapter.STATE_OFF:蓝牙关闭状态
      BluetoothAdapter.STATE_TURNING_OFF:蓝牙正在关闭状态
      BluetoothAdapter.STATE_ON:蓝牙开启状态
      BluetoothAdapter.STATE_TURNING_ON:蓝牙正在开启状态

    下面通过一个小demo实现通过监听蓝牙状态变化的广播(luetoothAdapter.ACTION_STATE_CHANGED)获取四中蓝牙的状态
    1.注册权限

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

    2.编写一个生成128bit的UUID的工具类UUIDUtils.class

    
    public class UUIDUtil
    {
      private static final String base_uuid_regex = "0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb";
    
      public static boolean isBaseUUID(String uuid)
      {
        return uuid.toLowerCase().matches("0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb");
      }
    
      public static String UUID_128_to_16bit(String uuid, boolean lower_case)
      {
        if (uuid.length() == 36) {
          if (lower_case) {
            return uuid.substring(4, 8).toLowerCase();
          }
          return uuid.substring(4, 8).toUpperCase();
        }
    
        return null;
      }
    
      public static String UUID_16bit_128bit(String uuid, boolean lower_case)
      {
        if (lower_case) {
          return ("0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb".substring(0, 4) + uuid + "0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb".substring(38)).toLowerCase();
        }
        return ("0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb".substring(0, 4) + uuid + "0000([0-9a-f][0-9a-f][0-9a-f][0-9a-f])-0000-1000-8000-00805f9b34fb".substring(38)).toUpperCase();
      }
    }
    

    3.activity中广播监听蓝牙状态变化,设置一个按钮开启蓝牙

    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothManager;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.os.Bundle;
    import android.support.v7.app.AppCompatActivity;
    import android.util.Log;
    import android.view.View;
    
    public class MainActivity extends AppCompatActivity {
        private BluetoothAdapter mBtAdapter;
        private static final String TAG = "TAG";
        private String bleStateStr = "";
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            final BluetoothManager bluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
            mBtAdapter = bluetoothManager.getAdapter();
    
            IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
            registerReceiver(mBroadcastReceiver, intentFilter);
        }
    
        private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
                if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) {
                    int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
                    switch (state) {
                        case BluetoothAdapter.STATE_OFF:
                            bleStateStr = "STSTE_OFF 手机蓝牙已关闭";
                            break;
                        case BluetoothAdapter.STATE_TURNING_OFF:
                            bleStateStr = "STSTE_OFF 手机蓝牙正在关闭";
                            break;
                        case BluetoothAdapter.STATE_ON:
                            bleStateStr = "STSTE_OFF 手机蓝牙已开启";
                            break;
                        case BluetoothAdapter.STATE_TURNING_ON:
                            bleStateStr = "STSTE_OFF 手机蓝牙正在开启";
                            break;
                    }
                    Log.i(TAG, bleStateStr);
                }
    
            }
        };
    
        public void openBluetooth(View view) {
            if (!mBtAdapter.isEnabled()) {
                mBtAdapter.enable();
            } else {
                Log.i(TAG, "蓝牙已开启!");
            }
    
        }
    
        @Override
        protected void onDestroy() {
            super.onDestroy();
            unregisterReceiver(mBroadcastReceiver);
        }
    }
    java
    4.开启蓝牙关闭蓝牙是在Log中展示如下
    ![image.png](https://img.haomeiwen.com/i7312294/2af606e9d4155e5b.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    
    
          
    
    
    
    
    
    
    

    相关文章

      网友评论

          本文标题:Android蓝牙4.0(BLE)

          本文链接:https://www.haomeiwen.com/subject/yldivqtx.html