美文网首页移动互联网学习蓝牙
深入了解Android蓝牙Bluetooth ——《总结篇》

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

作者: goodgleCoder | 来源:发表于2017-03-10 13:47 被阅读1504次

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

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

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

    目前项目中的效果图:

    请点击此链接看效果图​http://p1.bqimg.com/583828/1ea8450c8a9c2167.gif​

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

    蓝牙API

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

    BluetoothGatt

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

    BluetoothGattCharacteristic

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

    BluetoothGattDescriptor

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

    BluetoothGattService

    服务,Characteristic的集合。

    BluetoothProfile

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

    BluetoothManager

    通过BluetoothManager来获取BluetoothAdapter

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

    BluetoothAdapter

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

    BluetoothAdaptermBluetoothAdapter =bluetoothManager.getAdapter();1.8BluetoothGattCallback

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

    privateBluetoothGattCallback GattCallback =newBluetoothGattCallback() {// 这里有9个要实现的方法,看情况要实现那些,用到那些就实现那些publicvoidonConnectionStateChange(BluetoothGatt gatt,intstatus,intnewState){};publicvoidonCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,intstatus){};};BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);BluetoothGatt gatt = device.connectGatt(this,false, mGattCallback);

    notification对应onCharacteristicChanged

    gatt.setCharacteristicNotification(characteristic,true);

    readCharacteristic对应onCharacteristicRead

    gatt.readCharacteristic(characteristic);

    writeCharacteristic对应onCharacteristicWrite

    gatt.wirteCharacteristic(mCurrentcharacteristic);

    连接蓝牙或者断开蓝牙 对应 onConnectionStateChange

    readDescriptor对应onDescriptorRead;

    writeDescriptor对应onDescriptorWrite;

    gatt.writeDescriptor(descriptor);

    readRemoteRssi对应onReadRemoteRssi

    gatt.readRemoteRssi()

    executeReliableWrite对应onReliableWriteCompleted;

    discoverServices对应onServicesDiscovered

    gatt.discoverServices()

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

    二、开启蓝牙权限

    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();finalBluetoothManagerbluetoothManager=                (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()

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

    Intentintent= newIntent(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 =newIntent(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);

    回调

    publicabstractclassBluetoothGattCallback{publicvoidonConnectionStateChange(BluetoothGatt gatt,intstatus,intnewState){    }publicvoidonServicesDiscovered(BluetoothGatt gatt,intstatus){    }publicvoidonCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic,intstatus){publicvoidonCharacteristicWrite(BluetoothGatt gatt,                                      BluetoothGattCharacteristic characteristic,intstatus){    }publicvoidonCharacteristicChanged(BluetoothGatt gatt,

    BluetoothGattCharacteristic characteristic){    }

    设置通知

    publicbooleansetCharacteristicNotification(UUID serviceUuid, UUID characteristicUuid,booleanenable) {    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 :newbyte[]{0x00,0x00});returnmConnGatt.writeDescriptor(descriptor);// descriptor write}

    曾经遇到的坑

    蓝牙接连时超时

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

    privatefinal BroadcastReceiver mGattUpdateReceiver =newBroadcastReceiver() {        @OverridepublicvoidonReceive(Context context, Intent intent) {            finalStringaction = intent.getAction();if(BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) {//蓝牙已连接tvBluetooth.setText("(已连接)");            }elseif(BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) {                showToast("蓝牙连接断开,请重试");//这里重新连接蓝牙hideLoading();            }elseif(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {//发现蓝牙,设置命令......}elseif(BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) {//接收到数据......}        }    };

    蓝牙搜索进行匹配不来BLE设备

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

    连接成功后断开

    保证BLE小设备没有被其他连接

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

    读取过程中蓝牙断开

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

    断开连接

    断开(关闭)service

    关闭蓝牙

    然后执行: 先停止扫描---》重新扫描---》重新连接

    上传数据失败

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

    注意:BLE蓝牙连接小设备时一般属于主从模块,其中主模块蓝牙可以同时连接多个设备,但读取时只能读取一个。

    蓝牙搜索读取设备的流程:

    链接地址: http://blog.csdn.net/androidstarjack/article/details/60781892

    有关项目下载地址: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    微信公众号:终端研发部

    (欢迎关注学习和交流)

    http://blog.csdn.net/androidstarjack/article/details/60781892

    相关文章

      网友评论

        本文标题:深入了解Android蓝牙Bluetooth ——《总结篇》

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