随着物联网的越来越火,使用蓝牙方式进行设备间的通信也越来越多。而传统蓝牙协议(蓝牙2.0),由于其高功耗、连接速度慢及距离短等限制阻碍了蓝牙的推广应用。而12年推出来的蓝牙4.0 ble低功耗协议满足了物联网、医疗智能穿戴设备等方面的应用场景。
传统蓝牙与低功耗BLE的对比

基本上所有的Android设备都支持经典蓝牙配置文件,它适合更耗电的操作比如视频流。而Android 4.3开始支持蓝牙低功耗及蓝牙智能(BluetoothSmart)技术,它能够支持GATT(GENERIC ATTRIBUTE PROFILE 通用属性剖面)配置的设备进行通信(比如有心脏检测器、计步器等)
一个设备可以有多个服务,如电池、心率监视器和自行车骑行速度。每一个服务都有一些特性,如心率监听器的身体位置,或者自行车的RPM数量。有些特性,比如当前时间,支持从客户端写操作,而另一些只支持读取和/或通知。每个特性呢可以有多个描述符,描述符用来描述特性的额外信息。
一个设备—->服务(一设备n个服务)—->特性(一服务n特性)—->描述符(一特性n描述符)

1.0 权限及功能注册及声明
使用蓝牙低功耗ble时,需要注册相应的权限及申明相应的功能(过滤掉不支持的设备)

       <users-permission android:name="android.permission.BLUETOOTH" />    <users-permission android:name="android.permission.BLUETOOTH_ADMIN" />    <users-feature android:name="android.hardware.bluetooth_le" android:required="true" />

按时required为true时,则应用只能在支持BLE的Android设备上安装运行;required为false时,Android设备均可正常安装运行,需要在代码运行时判断设备是否支持BLE feature:

   // Use this check to determine whether BLE is supported on the device. Then// you can selectively disable BLE-related features.if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {    Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();    finish();}

1.1 判断蓝牙是否开启了

f(!mBluethoothAdapter.isEnable()){        Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_EANBLE);        startActivityForResult(enableIntent,ENABLE_REQUEST);    }

1.2 接下来可以扫描查找蓝牙低功耗设备

 public void doStartBleScan(){        mLeScanCallback = new MyLeScanCallback();        BluetoothManager bluetoothManager = (BluetoothManage)getSystem(Context.BLUETOOTH_SERVICE);        mBluethoothAdapter = bluetoothManager.getAdapter();        mBluethoothAdapter.startLeScan(mLeScanCallback);    }

1.3 查找的过程中,会回调LeScanCallback中的onLeScan方法,在此方法中判断是指定设备后进行连接。

 private class MyLeScanCallback implements BluetoothAdapter.LeScanCallbakc{        public void  onLeScan(BluetoothDevice device,int rssi,byte[] scanRecode){            //...判断过程,            mBluethoothAdapter.stopLeScan(this);            mMyGattCallback = new MyGattCallback();            mGatt = device.connectGatt(BtleDemo.this,false,mMyGattCallback);        }    }

1.4 连接完成后会回调onConnectionStateChange方法。此时可以查找发现远程设备上的可用服务

 private class MyGattCallback extends BluetoothGattCallback{        public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState){            super.onConnectionStateChange(gatt,status,newState);            if(newState == BluetoothGatt.STATE_CONNECTED && status == BluetoothGatt.GATT_SUCCESS){                //远程设备名称                //String deviceName = gatt.getDevice().getName();                gatt.discoverServices();            }        }    }

1.5 当发现可用服务后,会回调onServicesDiscovered方法,在此可以遍历服务和它的特性。对每个特性可以检查是否支持读写和/或通知,如果支持的话调用相应的方法。

    public void onServicesDiscovered(BluetoothGatt gatt,int status){        if(status == BluetoothGatt.GATT_SUCCESS){            List<BluetoothGattService> services =  gatt.getServices();            for(BluetoothGattService service :  services){                for(BluetoothGattCharacteristic chara :  service.getCharacteristics()){                    if(hasProperty(chara,BluetoothGattCharacteristic.PROPERTY_READ)){                        gatt.readCharacteristic(chara);                    }                     if(hasProperty(chara,BluetoothGattCharacteristic.PROPERTY_NOTITY)){                        gatt.setCharacteristicNotification(chara,true);                    }                   }            }        }    }public static boolean hasProperty(BluetoothGattCharacteristic chara,int property){    int  prop = chara.getProperties()&property;    return prop == property;}

1.6 对服务特性的读取与通知都是异步回调的。

public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic chara,int status){    super.onCharacteristicRead(gatt,chara,status);    if(status == BluetoothGatt.SUCCESS){        Integer value = chara.getIntValue(BluetoothGattCharacteristic.FROM_SINT32,0);        //todo 处理数据读取    }}public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic chara){    super.onCharacteristicChanged(gatt,chara);     Integer value = chara.getIntValue(BluetoothGattCharacteristic.FROM_SINT32,0);     //todo 处理通知中的值}

官网Gatt资料https://developer.bluetooth.org/TechnologyOverview/Pages/GATT.aspx

更多相关文章

  1. Android(安卓)设备上使得google play store 应用市场中不能搜索
  2. Android(安卓)关于佳博和汉印蓝牙热敏打印机开发
  3. 传谷歌年底推Android眼镜:可返回实时信息
  4. Android(安卓)传感器概述
  5. 通过 WIFI 用 adb 调试 Android(安卓)设备
  6. android设备静默升级
  7. Android(安卓)设备在Play Store无法搜索下载Netflix软件
  8. android 扫码设备获取扫码回调内容实践
  9. android获取设备分辨率的新方法

随机推荐

  1. Android(安卓)Data Storage --- Android(安
  2. Android(安卓)之 AsyncTask 异步任务
  3. Android常用开发工具的用法
  4. 开源项目之Android Afinal框架
  5. android 弹出日期滑动选择框,日期滚动滑动
  6. 系出名门Android(10) - HTTP 通信, XML
  7. 用activity实现半透明的、淡入的menu
  8. Hello Android(安卓)- proguard混淆器使
  9. Android下修改hosts文件
  10. Android(安卓)2.2新增Widget之ProtipWidg