粗暴的解释Android与蓝牙Ble之间的通信,android蓝牙ble
首先,先简单介绍一下ble的特征(注意:蓝牙4.0只有android4.3或4.3以上才支持)
1.BLE(Bluetooth Low Energy),蓝牙4.0核心profile,主要特点是快速搜索,快速连接,超低功耗保持连接和数据传输,缺点:数据传输速率低,由于其具有低功耗特点,所以经常用在可穿戴设备之中。
2.关于BLE数据传输:
a.profile可以理解为一种规范,一个标准的通信协议,其存在于手机中,蓝牙组织规定了一些标准的profile:HID OVER GATT ,防丢器等,每个profile中包含了多个service。
b.service 可以理解为一个服务,在BLE从机中有多个服务,电量信息,系统服务信息等,每一个service中包含了多个characteristic特征值,每一个具体的characteristic特征值才是BLE通信的主题。
c.characteristic特征值:BLE主机从机通信均是通过characteristic进行,可以将其理解为一个标签,通过该标签可以读取或写入相关信息。
d. UUID(统一标识码):service和characteristic均需要这个唯一的UUID进行标识。
e. 角色和职责,看到这里我觉得您老人家应该知道了,就是中心设备和外围设备(GATT server vs. GATT client.),不过呢在这里我就不这样说了,其实也不太懂那么的官方说法,我就简单粗暴点就是运用了ble的app和ble设备之间的通信,当app搜索到了ble设备,app会收到ble反馈过来的信息比如电量什么的,对于怎么得来的不用说都知道肯定是在一个规范好的一个对象中啦(先不需要知道这个对象是什么鬼东西因为我也不知道,官方叫characteristic也就是上面说的特征值),相反我们app也可以通过写入一些信息到这个对象(characteristic)发送给设备,设备收到之后就会执行我们的要它做的动作了。其实也就和平常我们的对象赋值一样(setValue("fuzhi")),只是方法不同而已,一个是set一个是write。
最后来举个例子简答说明一下:其实说白了characteristic特征值就好比一支球队的各个球员,service好比这个球队的名称,profile就当国家吧,假如我们要找到某一个球员,世界这么多国家第一需要知道是哪个国家的,第二需要知道是哪个球队的,最后才知道是那个球员,只有这样最后才能了解这个球员的一些信息(类似从ble设备获取信息),相反也只有这样找到球员后告诉这个球员应该怎么打球的(类似对ble设备设置信息)。例子很难懂吧,如果你看懂了说明你和我一样小学毕业,看不懂的话就直接看代码吧,因为本人小学毕业,识字不多,脑袋不能转太快,怕翻车,,,
/****************************************************代码块*****************************************************
1、 权限和相关属性这是最基本的啦
<uses-featureandroid:name="android.hardware.bluetooth_le"android:required="true"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH"/>
<uses-permissionandroid:name="android.permission.BLUETOOTH_ADMIN"/>
2、初始化蓝牙,这个方法一般可以写在项目的启动activity,不然怕在写完ble代码执行后发现没有打开蓝牙还需要手动去打开对项目体验感不好,当然只要您老人家开心,写不写都可以。
private void initBluetooth() {
BluetoothManager mBluetoothManager = (BluetoothManager) this.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager != null) {
BluetoothAdapter mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter != null) {
if (!mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.enable(); //打开蓝牙
}
}
}
}
3、获取本地ble对象(BluetoothAdapter),它对应本地Android设备的蓝牙模块,可能这么称呼为本地ble对象不太准确,但我老人家开心这么称呼。从此段代码开始可以把这些有关ble通信的代码写到一个class中当做一个ble工具class,以便代码清晰查看和方便调用。这里我们就当这个工具类叫BleManager
private BluetoothAdapter mBluetoothAdapter;
private BluetoothDevice mBluetoothDevice;
private BluetoothGatt mBluetoothGatt;
private boolean isScanning = false;
//以上所定义的对象在下面的方法中都有用到,(建议在看蓝牙这方面的东西时,不管看谁的文章,都先把以上或者还有些蓝牙基本用的对象先熟悉是什么意思和基本作用)。
private BleManager(Context context) {
this.mContext = context;
BluetoothManager bluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE); //BluetoothManager只在android4.3以上有
if (bluetoothManager == null) {
TLog.e(TAG, "Unable to initialize BluetoothManager.");
return;
}
mBluetoothAdapter = bluetoothManager.getAdapter();
}
4、既然获得了BluetoothAdapter对象,那么接下来就可以搜索ble设备了,这时就需要用到BluetoothAdapter的startLeScan()这个方法了
public void startLeScan() {
if (mBluetoothAdapter == null) {
return;
}
if (isScanning) {
return;
}
isScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback); //此mLeScanCallback为回调函数
mHandler.sendEmptyMessageDelayed(STOP_LESCAN, 10000); //这个搜索10秒,如果搜索不到则停止搜索
}
在4.3之前的api是通过注册广播来处理搜索时发生的一些事件,而支持ble的新的api中,是通过回调的方式来处理的,而mLeScanCallback就是一个接口对象
private LeScanCallback mLeScanCallback = new LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int arg1, byte[] arg2) {
TLog.i(TAG, "onLeScan() DeviceName------>"+device.getName()); //在这里可通过device这个对象来获取到搜索到的ble设备名称和一些相关信息
if(device.getName() == null){
return;
}
if (device.getName().contains("Ble_Name")) { //判断是否搜索到你需要的ble设备
TLog.i(TAG, "onLeScan() DeviceAddress------>"+device.getAddress());
mBluetoothDevice = device; //获取到周边设备
stopLeScan(); //1、当找到对应的设备后,立即停止扫描;2、不要循环搜索设备,为每次搜索设置适合的时间限制。避免设备不在可用范围的时候持续不停扫描,消耗电量。
connect(); //连接
}
}