Android 蓝牙4.0开发

1、  权限和相关属性

“android:required="true"表示apk只有在具有bluetooth_le属性的系统里运行,这个4.3之前android系统没有

<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>

<uses-permissionandroid:name="android.permission.BLUETOOTH"/>

<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>

2、  程序开妈操作蓝牙之前,先判断ble是否支持

if(!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {

Toast.makeText(this,R.string.ble_not_supported, Toast.LENGTH_SHORT).show();

finish();

}

3、  打开、关闭蓝牙

先获取蓝牙的一个代理

final BluetoothManager bluetoothManager =

(BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);

mBluetoothAdapter = bluetoothManager.getAdapter();

发intent通知系统打开蓝牙

if(!mBluetoothAdapter.isEnabled()) {

if (!mBluetoothAdapter.isEnabled()){

Intent enableBtIntent = newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE);

startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);

}

}

也可以使用 enable 和disable函数来打开关闭

4、  搜索ble设备

mHandler.postDelayed(newRunnable() {

@Override

public void run() {

mScanning = false;

mBluetoothAdapter.stopLeScan(mLeScanCallback);

}

}, SCAN_PERIOD);

mScanning = true;

mBluetoothAdapter.startLeScan(mLeScanCallback);

//SCAN_PERIOD是10000,表示每次的搜索时间为10秒

需要注意的是mLeScanCallback,在4.3之前的api是通过注册广播来处理搜索时发生的一些事件,而支持ble的新的api中,是通过回调的方式来处理的,mLeScanCallback就是一个接口对象,看一下实现:

privateBluetoothAdapter.LeScanCallback mLeScanCallback =

newBluetoothAdapter.LeScanCallback() {

@Override

public void onLeScan(finalBluetoothDevice device, int rssi, byte[] scanRecord) {

runOnUiThread(new Runnable() {

@Override

public void run() {

mLeDeviceListAdapter.addDevice(device);

mLeDeviceListAdapter.notifyDataSetChanged();

}

});

}

};

5、  连接

4.3之前的api是通过socket方式在蓝牙之间互相通信,连接的结果是返回一个socket对象

在支持4.0蓝牙的新的api中,返回的是BluetoothGatt对象

可以将BluetoothGatt对象看成是远程设备的一个代理

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

mGattCallback是一个抽象类对象,之前的广播形式,在新的api中都改成了回调

BluetoothGattCallback抽象类,只有9个方法,字面意思就都可以看懂,在处理连接事件上,需要处理方法:

public voidonConnectionStateChange(BluetoothGatt gatt, int status,

intnewState)

条件:if (newState ==BluetoothProfile.STATE_CONNECTED)

else if (newState ==BluetoothProfile.STATE_DISCONNECTED)分别表示已连接和已断开

6、 通讯

这一点与之前形式上完全不一样了

BLE分为三部分Service、Characteristic、Descriptor,这三部分都由UUID作为唯一标示符。一个蓝牙4.0的终端可以包含多个Service,一个Service可以包含多个Characteristic,一个Characteristic包含一个Value和多个Descriptor,一个Descriptor包含一个Value。

在连接上某个终端后,可以将其每个结点的UUID全部打印出来,但每个结点不是都能读写。

一般来说,Characteristic是手机与BLE终端交换数据的关键,Characteristic有较多的跟权限相关的字段,例如PERMISSION和PROPERTY,而其中最常用的是PROPERTY,本文所用的BLE蓝牙模块竟然没有标准的Characteristic的PERMISSION。Characteristic的PROPERTY可以通过位运算符组合来设置读写属性,例如READ|WRITE、READ|WRITE_NO_RESPONSE|NOTIFY,因此读取PROPERTY后要分解成所用的组合

我是这么去和ble终端通信的:

得到某个service的对象

BluetoothGattService linkLossService =mBluetoothGatt

.getService(UUID.fromString("49535343-fe7d-4ae5-8fa9-9fafd205e455"));

一般说来,ble设备都带有几个标准的服务,其UUID已经定义好了,这些结点里的值只能读了,因为我一个一个试过了,终于找到了我的设备里可以读写的服务,其中49535343-fe7d-4ae5-8fa9-9fafd205e455就是对应这个服务的

获取此服务结点下的某个Characteristic对象

BluetoothGattCharacteristic alertLevel =linkLossService.getCharacteristic(UUID.fromString("49535343-8841-43f4-a8d4-ecbe34729bb3"));

一般供应商会给出多个Characteristic,你需要找到到底哪个才是让你去写的,怎么找需要看对应的终端的一些开发文档之类的,在这里我经过测试已经找到我要的了

设置要写的值

alertLevel.setValue(values_on);

这里的values_on是一个byte数组

status = mBluetoothGatt.writeCharacteristic(alertLevel);

status如果为true,表示写操作已经成功执行,BluetoothGattCallback抽象类的一个方法会被执行,如果刚好你又重写了这个方法,就可以打印一些消息了

public void onCharacteristicWrite(BluetoothGatt gatt,

BluetoothGattCharacteristiccharacteristic, int status)

读某个Characteristic

public void readCharacteristic(BluetoothGattCharacteristiccharacteristic) {

if (mBluetoothAdapter == null || mBluetoothGatt == null) {

Log.w(TAG, "BluetoothAdapter not initialized");

return;

}

mBluetoothGatt.readCharacteristic(characteristic);

}

如果成功,数据会在下面的方法回调中传进来

public voidonCharacteristicRead(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

int status)

当终端有数据要传过来的时候,表面上正常的话,手机这边下面的方法会被调用

public voidonCharacteristicRead(BluetoothGatt gatt,

BluetoothGattCharacteristic characteristic,

intstatus)

这个也是可以控制的,设置descriptor的value不同,可以控制这个重写的方法是否会被调用,没有测试其他的设备,感觉这个应该是会对应不同的设备,具体设置的地方会有不同,在我这边是这么操作的:

public void enableNotification(boolean b)

{

if(b)

{

BluetoothGattService service =mBluetoothGatt

.getService(UUID.fromString("49535343-fe7d-4ae5-8fa9-9fafd205e455"));

BluetoothGattCharacteristicale =service.getCharacteristic(UUID.fromString("49535343-1E4D-4BD9-BA61-23C647249616"));

booleanset = mBluetoothGatt.setCharacteristicNotification(ale, true);

Log.d(TAG," setnotification = " + set);

BluetoothGattDescriptordsc =ale.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

byte[]bytes = {0x01,0x00};

dsc.setValue(bytes);

boolean success =mBluetoothGatt.writeDescriptor(dsc);

Log.d(TAG, "writing enabledescriptor:" + success);

}

else

{

BluetoothGattService service =mBluetoothGatt

.getService(UUID.fromString("49535343-fe7d-4ae5-8fa9-9fafd205e455"));

BluetoothGattCharacteristicale =service.getCharacteristic(UUID.fromString("49535343-1E4D-4BD9-BA61-23C647249616"));

booleanset = mBluetoothGatt.setCharacteristicNotification(ale, false);

Log.d(TAG," setnotification = " + set);

BluetoothGattDescriptordsc =ale.getDescriptor(UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"));

byte[]bytes = {0x00, 0x00};

dsc.setValue(bytes);

boolean success =mBluetoothGatt.writeDescriptor(dsc);

Log.d(TAG, "writing enabledescriptor:" + success);

}

}

7、 总结

网上的一些资料大都以上面的命名来标识自己的文档,有必要解释一下,应该分开来看这个命题:

android指的安装的4.3及以上版本的android系统的设备

4.0蓝牙指的蓝牙芯片使用4.0协议的设备

这种开发的一种标准用处是:用4.3以上android版本的手机,与4.0蓝牙穿戴式设备进行通信

按网上的一种中央与周边的说法,手机就是中央,4.0蓝牙设备就中周边

如果要开发4.0蓝牙,应该知道4.0蓝牙具有高速、低功耗的优点,这些优点对手机的提升不大,但对其他一些终端设备的提升就比较大。

有意思的是,android对与4.0蓝牙通信的封装,不需要本身设备的蓝牙芯片是4.0协议的蓝牙芯片

于是android 蓝牙4.0开发的这么一个“大环境”下的真实情景就是:一个没有必要拥有蓝牙4.0协议的蓝牙芯片的android4.3以上系统的手机,与一些4.0蓝牙协议的蓝牙芯片设备终端的故事

以上是一些事实,以下是一些猜想

1、 蓝牙4.0与之前版本协议之间可以通讯,说明:4.0蓝牙协议并不是修改的无线波的调制与解调,而是修改的数据的组成

2、 对蓝牙4.0协议的支持,是由google提出的,而不是各个手机厂商提出的,说明:android系统在软件上可以一致对待不同的蓝牙芯片,不同的蓝牙芯片对同一段数据的调制解调结果是一样的,于是在这段数据通过串口传到手机主控的时候,也是一样的,在这个环境里,蓝牙芯片只是一个调制解调器,android封装了对数据全部的处理。

android ble蓝牙开发略解的更多相关文章

  1. Android BLE 蓝牙开发——扫码枪基于BLESSED

    一.蓝牙模式HID与BLE 当扫码枪与手机连接时,通常采用的是蓝牙HID(Human Interface Device)模式.本质上是一个把扫码枪作为一个硬件键盘,按照键盘协议把扫码后的结果逐个输入到 ...

  2. Android BLE蓝牙开发-读写数据 获取UUID

    https://www.jianshu.com/p/3711cfbf7128 一个ble蓝牙设备有多个包括多个Profile 一个Profile中有多个服务Service(通过服务的uuid找到对应的 ...

  3. Android BLE蓝牙详细解读

    代码地址如下:http://www.demodashi.com/demo/15062.html 随着物联网时代的到来,越来越多的智能硬件设备开始流行起来,比如智能手环.心率检测仪.以及各式各样的智能家 ...

  4. Android ble 蓝牙4.0 总结

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

  5. Android ble 蓝牙4.0 总结一

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

  6. Android BLE 蓝牙编程(一)

    最近在研究这个,等我有时间来写吧! 终于在端午节给自己放个假,现在就来说说关于android蓝牙ble的 最近的学习成果吧!! 需要材料(写个简单教程吧--关于小米手环的哦!嘿嘿) Android 手 ...

  7. Android ble蓝牙使用注意

    以下均为自己在Android ble开发项目中遇到的问题 1.尽量不要在BluetoothGattCallback里面的回调函数中执行读写通知操作,最多一个,因为例如在onServicesDiscov ...

  8. Android Studio 蓝牙开发实例——基于Android 6.0

    因项目需要做一个Android 的蓝牙app来通过手机蓝牙传输数据以及控制飞行器,在此,我对这段时间里写的蓝牙app的代码进行知识梳理和出现错误的总结. 该应用的Compile Sdk Version ...

  9. iOS 蓝牙开发详解

    目前iOS智能硬件的开发交互方式主要分为两种,一种是基于低功耗的蓝牙4.0技术(由于耗电低,也称作为BLE(Bluetooth Low Energy))对应iOS的框架为CoreBluetooth,另 ...

随机推荐

  1. poj 1731 Orders(暴力)

    题目链接:http://poj.org/problem?id=1731 思路分析:含有重复元素的全排列问题:元素个数为200个,采用暴力枚举法. 代码如下: #include <iostream ...

  2. 饭卡------HDOJ杭电2546(还是01背包!!!!!!)

    Problem Description 电子科大本部食堂的饭卡有一种非常诡异的设计,即在购买之前推断剩余金额. 假设购买一个商品之前,卡上的剩余金额大于或等于5元,就一定能够购买成功(即使购买后卡上剩 ...

  3. Axure滚动效果实现

    下面的这个透明区域用于显示滚动效果,它本身是一个处于隐藏状态的动态面板,它里面也放了一个动态面板用于产生移动的效果 里面的动态面板起名“实际内容”,注意它的默认状态是“状态2”,状态2和状态一的内容一 ...

  4. ThinkPHP - 模板使用函数

    模板使用函数 1.模板引擎自带函数:仅仅是输出变量并不能满足模板输出的需要,内置模板引擎支持对模板变量使用调节器和格式化功能,其实也就是提供函数支持,并支持多个函数同时使用.用于模板标签的函数可以是P ...

  5. B站开源播放框架ijkplayer(iOS版)使用教程

    最近在关注直播这块儿,开始时直接用ffmpeg写了一个,写得比较烂,卡顿很严重,后来听说了B站开源播放框架ijkplayer,于是就去试试看这是链接 ,一用之下果然不错,逢人便向人安利,可总是有部分同 ...

  6. linux脚本:ftp自动传输文件

    使用Shell脚本实现ftp的自动上传下载 http://liwenge.iteye.com/blog/566515 open 192.168.1.171 user guest 123456cd /h ...

  7. ubuntu安装greenplum依赖包

    ubuntu安装greenplum的过程中有两个比较难找的包,特地写出来给大家分享一下: 错误提示1:configure: error: header file <ldap.h> is r ...

  8. 【HTTP 2】HTTP/2 协议概述(HTTP/2 Protocol Overview)

    前情提要 在上一篇文章<[HTTP 2.0] 简介(Introduction)>中,我们简单介绍了 HTTP 2. 在本篇文章中,我们将会了解到 HTTP 2 协议概述部分的内容. HTT ...

  9. zookeeper perl 版本需求

    [root@wx03 ~]# perl -v This is perl 5, version 22, subversion 1 (v5.22.1) built for x86_64-linux Cop ...

  10. 【分享】如何使用sublime代码片段快速输入PHP头部版本声明

    作者:zhanhailiang 日期:2013-06-25 Sublime 菜单栏->Tools→New Snippet→输入以下内容: <snippet> <content& ...