zoukankan      html  css  js  c++  java
  • 蓝牙4.0 BLE入门

      在BLE协议中有两个角色,一个是周边(Periphery),另外一个是中央(Central)。一个中央可以同时连接多个周边,但一个周边某一时刻只能连接一个中央。但是不管periphery还是central都是可以实现GATT server和GATT client去传输数据,但是无法同时都是。

      先来讲一下相关术语和概念:

      GATT:Generic Attribute Profile,GATT配置文件是一个通用的规范,用于在BLE链路上发送和接收被称为"属性"的数据块。目前所有的BLE应用都基于GATT。 蓝牙SIG规定了许多低功耗设备的配置文件。配置文件是设备如何在特定的应用程序中工作的规格说明。注意一个设备可以实现多个配置文件。例如,一个设备可能包括心率监测仪和电量检测。

      ATT:Attribute Protocol,GATT在ATT协议基础上建立,也被称为GATT/ATT。ATT对在BLE设备上运行进行了优化,为此,它使用了尽可能少的字节。每个属性通过一个唯一的的统一标识符(UUID)来标识,每个String类型UUID使用128bit标准格式。属性通过ATT被格式化为characteristics和services。

      Characteristic:一个characteristic包括一个单一的value(变量)和0-n个用来描述characteristic变量的descriptor,characteristic可以被认为是一个类型,类似于类

      Descriptor:用来描述characteristic变量的属性。例如。一二descriptor可以规定一个可读的描述,或者一个characteristic变量可接受的范围,或者一个characteristic变量特定的测量单位

      Service:是characteristic的集合。例如,你可能有一个叫“Heart Rate Monitor(心率监测仪)”的service,它包括了很多characteristics,如“heart rate measurement(心率测量)”等。你可以在bluetooth.org 找到一个目前支持的基于GATT的配置文件和服务列表。

      以下是Android设备与BLE设备交互时的角色和责任:

        中央 vs 外围设备。 适用于BLE连接本身。中央设备扫描,寻找广播;外围设备发出广播。

        GATT服务端 vs GATT客户端。决定了两个设备在建立连接后如何互相交流。

      系统权限

      <uses-permission android:name="android.permission.BLUETOOTH"/> 使用这个权限去执行蓝牙通讯,如请求连接,接受连接和传输数据。

      <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>使用这个权限让你的app启用设备发现或者操纵蓝牙设置。
      <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>声明你的app只为具有BLE的设备提供。
      但是如果想让你的app提供给那些不支持BLE的设备,需要在manifest中包括上面代码并设置required="false",然后在运行时可以通过使用PackageManager.hasSystemFeature()确定BLE的可用性。
    if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
      Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
      finish();
    }
      设置BLE
      如果设备支持BLE但是被禁用的话,你可以无需离开程序而要求用户启用蓝牙:
    1、获取BluetoothAdapter
    所有的蓝牙活动都需要蓝牙适配器。整个系统只有一个蓝牙适配器,而且你的app使用它与系统交互。

    BluetoothManager bluetoothManager=(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);mBluetoothAdapter= bluetoothManager.getAdapter();

    2、开启蓝牙

    你需要确认蓝牙是否开启。调用isEnabled()去检测蓝牙当前是否开启。如果该方法返回false,则蓝牙被禁用,需要显示错误提示用户去设置开启蓝牙

    if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {

      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
      startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
    }
     
      发现BLE设备
    为了发现BLE设备,使用startLeScan()方法,这个方法需要一个参数BluetoothAdapter.LeScanCallback。你必须实现他的回调函数,那就是返回的扫描结果。因为扫描非常耗电,所以应当准守一下准则:
    1、找到所需设备,立即停止扫描
    2、不要在循环里面扫描,并且对扫描设置时间限制。以前可用的设备可能已经移出范围,继续扫描消耗电池电量

    private BluetoothAdapter mBluetoothAdapter;
    private Boolean mScanning;
    private Handler mHandler;

    private static final Long SCAN_PERIOD = 10000L;

    private LeScanCallback mLeScanCallback = new LeScanCallback() {
      @Override
      public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
        Log.i("TAG", device.toString());
      }
    };

    public void scanLeDevice(final boolean enable) {
      if (enable) {
        mHandler.postDelayed(new Runnable() {
          @Override
          public void run() {
            mScanning = false;
            mBluetoothAdapter.stopLeScan(mLeScanCallback);
          }
        }, SCAN_PERIOD);
        mScanning = true;
        mBluetoothAdapter.startLeScan(mLeScanCallback);
      } else {
        mScanning = false;
        mBluetoothAdapter.stopLeScan(mLeScanCallback);
      }
    }

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

    注意:只能扫描BLE设备或者扫描传统蓝牙设备,不能同时扫描BLE和传统蓝牙设备。

       连接到GATT服务端

    与一个BLE设备交互的第一步就是连接它,也就是连接BLE设备上的GATT服务端:

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

    第一个参数是Context对象,第二个是自动连接(表示BLE设备可用是否自动连接到它),第三个是BluetoothGattCallback调用。连接到GATT服务端时,由BLE设备做主机,并返回一个BluetoothGatt实例,然后你可以使用这个实例来进行GATT客户端操作

       读取BLE变量
    uuid = gattService.getUuid().toString();
    List<BluetoothGattCharacteristic> gattCharacteristics gattService.getCharacteristics();
    uuid = gattCharacteristic.getUuid().toString();
      接收GATT通知
    当设备上的特性发生改变时候会通知BLE应用程序。这段代码显示了如何使用setCharacteristication()给一个特性设置通知:
    mBluetoothGatt.setCharacteristicNotification(characteristic, enable);
    BluetoothGattDescriptor descriptor = characteristic.getDescriptor(UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
    descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
    mBluetoothGatt.writeDescriptor(descriptor);
    如果对一个特性启用通知,当远程蓝牙设备特性发送变化,回调函数onCharacteristicChanged( )被触发。
      关闭客户端APP
    当你的app完成BLE设备的使用后,应该调用close(),系统可以合理释放占用的资源
    public void close() {
      if (null == mBluetoothGatt) {
        return;
      }
      mBluetoothGatt.close();
      mBluetoothGatt = null;
    }
  • 相关阅读:
    SVN客户端服务器搭建与使用(一)
    MyEclipse下XFire开发WebService实例
    SVN客户端服务器搭建与使用(三)
    MyEclipse中Svn插件
    Spring整合MyBatis
    MyEclipse中Properties文件中文编辑插件
    WebService的原理及概念
    字符集和字符编码(Charset & Encoding)(转)
    Android 4.0系统七大新功能(转)
    加密算法小知识
  • 原文地址:https://www.cnblogs.com/ijavanese/p/4998000.html
Copyright © 2011-2022 走看看