您的位置:首页 > 移动开发 > Android开发

android BLE4.0 流程图

2016-05-22 13:51 399 查看
BLE蓝牙在android上连接,底层实现读取的详细执行过程:

1、扫描:

使用BluetoothAdapter.startLeScan来扫描低功耗蓝牙设备,获取设备对象device,通过device.address,device.name获取设备名称和mac地址,通过mac地址分配每个设备唯一名称,例:体温计1,体温计2...。

在扫描到设备的回调函数中获得所有device对象,并使用BluetoothAdapter.stopLeScan停止扫描。

2、连接和读写数据:

使用BluetoothDevice.connectGatt来获取到BluetoothGatt对象;

执行BluetoothGatt.discoverServices,这个方法是异步操作,在回调函数onServicesDiscovered中得到status,通过判断status是否等于BluetoothGatt.GATT_SUCCESS来判断查找Service是否成功;

如果成功了,则通过BluetoothGatt.getService来获取BluetoothGattService;

接着通过BluetoothGattService.getCharacteristic获取BluetoothGattCharacteristic;

然后通过BluetoothGattCharacteristic.getValue获取体温数据。

主要使用BluetoothLeService对上图流程进行控制。BluetoothLeService封装了androidframework
层bluetooth的相关对象和操作方法、回调方法包括:

android.bluetooth.BluetoothAdapter;

android.bluetooth.BluetoothDevice;

android.bluetooth.BluetoothGatt;

android.bluetooth.BluetoothGattCallback;

android.bluetooth.BluetoothGattCharacteristic;

android.bluetooth.BluetoothGattService;

android.bluetooth.BluetoothManager;

android.bluetooth.BluetoothProfile;

initialize();初始化

disconnect();断开与远程设备的GATT连接

close();关闭关闭GATT

readCharacteristic();读取指定的characteristic

readDeviceData();读取设备信息

connect();连接设备

getCharacteristic();获取BluetoothGattCharacteristic对象

SendReadOrder();发送读数据指令

getSupportedGattServices();获取所有服务

BluetoothLeService采用与显示层bind,unbind的方式,在后台保持运行,并提供与前台交互的android组件BroadcastReceiver传递消息。

/*
* Copyright (C) 2013 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.mehow.mehowhealth.bluetooth;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;

import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

public class BluetoothLeService extends Service implements BleManager{

private final static String TAG = BluetoothLeService.class.getSimpleName();

private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
private int order;// 表示发送的是什么读取命令
private BluetoothGattCharacteristic characteristic;

private final IBinder mBinder = new LocalBinder();

private int mConnectionState = STATE_DISCONNECTED;
private static final int STATE_DISCONNECTED = 0;
private static final int STATE_CONNECTING = 1;
private static final int STATE_CONNECTED = 2;

// 广播标识
public final static String ACTION_GATT_CONNECTED = "com.example.bluetooth.le.ACTION_GATT_CONNECTED";
public final static String ACTION_GATT_DISCONNECTED = "com.example.bluetooth.le.ACTION_GATT_DISCONNECTED";
public final static String ACTION_GATT_SERVICES_DISCOVERED = "com.example.bluetooth.le.ACTION_GATT_SERVICES_DISCOVERED";
public final static String ACTION_DATA_AVAILABLE = "com.example.bluetooth.le.ACTION_DATA_AVAILABLE";
public final static String EXTRA_DATA = "com.example.bluetooth.le.EXTRA_DATA";

public final static UUID UUID_HEART_RATE_MEASUREMENT = UUID.fromString("00002a37-0000-1000-8000-00805f9b34fb");

public final static String CHANGE_PRODUCT_PARAMETER = "CHANGE_PRODUCT_PARAMETER";

/**
* 判断BluetoothAdapter对象
*
*/
public boolean initialize() {
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
return false;
}
}

mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
return false;
}

return true;
}

/**
* 断开与远程设备的GATT连接
*/
public void disconnect() {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return;
}
mBluetoothGatt.disconnect();
Log.i(TAG, "disconnect:--------2"+mBluetoothGatt);
}

/**
* 关闭关闭GATT
*/
public void close() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
Log.i(TAG, "disconnect:--------2"+mBluetoothGatt);
}

/**
* 读取指定的characteristic
*/
public boolean readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return false;
}
this.characteristic = characteristic;
return mBluetoothGatt.readCharacteristic(characteristic);
}

public interface onReadListener {
public void ReadData(byte[] bys, int order);
}

// 供上层调用
public void getReadtData(onReadListener listener) {
byte[] by = readDeviceData();
listener.ReadData(by, order);
}

// 读取设备信息
public byte[] readDeviceData() {
byte[] data = null;
if (characteristic == null) {
return null;
}
if (UUID.fromString(Constant.SERVICEUUID).equals(
characteristic.getUuid())) {

int flag = characteristic.getProperties();
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
}
final int heartRate = characteristic.getIntValue(format, 1);
} else {
data = characteristic.getValue();
}
return data;

}

/**
* 连接设备
*/
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
return false;
}

if (mBluetoothDeviceAddress != null&& address.equals(mBluetoothDeviceAddress)&& mBluetoothGatt != null) {
if (mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
} else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if (device == null) {
return false;
}
mBluetoothGatt = device.connectGatt(this, false, back);
Log.i("FH", "mBluetoothGatt:"+mBluetoothGatt);

mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
return true;
}

// 获取制定UUID的BluetoothGattCharacteristic对象
// 参数:service_uuid--BluetoothGattService的UUID;characteristic_uuid:BluetoothGattCharacteristic的UUID
public BluetoothGattCharacteristic getCharacteristic(String service_uuid,String characteristic_uuid) {
BluetoothGattService gService = mBluetoothGatt.getService(UUID
.fromString(service_uuid));
if (gService == null) {
return null;
}
BluetoothGattCharacteristic characteristic = gService
.getCharacteristic(UUID.fromString(characteristic_uuid));
return characteristic;
}

// 发送读数据指令
// 参数:by--要发送的指令;characteristic---要发给具体的对象
public boolean SendReadOrder(byte[] by,BluetoothGattCharacteristic characteristic, int identifying) {
if (by == null || characteristic == null) {
return false;
}
order = identifying;
boolean status = false;
int storedLevel = characteristic.getWriteType();
Log.d(TAG, "storedLevel() - storedLevel=" + storedLevel);
characteristic.setValue(by);
characteristic
.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
status = mBluetoothGatt.writeCharacteristic(characteristic);
Log.d(TAG, "writeLlsAlertLevel() - status=" + status);
return status;

}

/**
* 获取所有服务
*/
public List<BluetoothGattService> getSupportedGattServices() {
if (mBluetoothGatt == null)
return null;

return mBluetoothGatt.getServices();
}

public class LocalBinder extends Binder {

public BluetoothLeService getService() {
return BluetoothLeService.this;
}
}

@Override
public IBinder onBind(Intent intent) {
return mBinder;
}

/**
* BluetoothGatt回调函数
*/
private final BluetoothGattCallback back = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status,int newState) {
String intentAction;
if (newState == BluetoothProfile.STATE_CONNECTED) {
intentAction = ACTION_GATT_CONNECTED;
mConnectionState = STATE_CONNECTED;
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:"+ mBluetoothGatt.discoverServices());
Log.i("FH", "mBluetoothGatt-------7897987987:"+mBluetoothGatt.getServices().size());
System.out.println("已经连接上设备");
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
System.out.println("已经断开设备");
}
}

@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
System.out.println("onServicesDiscovered------4623462462------------");
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
Log.i("FH", "mBluetoothGatt:"+mBluetoothGatt.getServices().size());
} else {
Log.w(TAG, "onServicesDiscovered received: " + status);
}
}

@Override
public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
Log.i(TAG, "characteristic----------1:"+characteristic);
Log.i(TAG, "mBluetoothGatt----------1:"+mBluetoothGatt.getServices().size());
}

@Override
public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic characteristic) {
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
Log.i(TAG, "characteristic----------2:"+characteristic);
Log.i(TAG, "mBluetoothGatt----------2:"+mBluetoothGatt.getServices().size());
}

@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
Log.d(TAG, "onCharacteristicWrite" + Arrays.toString(characteristic.getValue()));
};

};

private void broadcastUpdate(final String action) {
final Intent intent = new Intent(action);
sendBroadcast(intent);
}

/**
* 发送广播
*
* @param action
* @param characteristic
*/
private void broadcastUpdate(final String action,final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);

// This is special handling for the Heart Rate Measurement profile. Data
// parsing is
// carried out as per profile specifications:
// http://developer.bluetooth.org/gatt/characteristics/Pages/CharacteristicViewer.aspx?u=org.bluetooth.characteristic.heart_rate_measurement.xml if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
int flag = characteristic.getProperties();
Log.d(TAG, flag + "");
int format = -1;
if ((flag & 0x01) != 0) {
format = BluetoothGattCharacteristic.FORMAT_UINT16;
Log.d(TAG, "Heart rate format UINT16.");
} else {
format = BluetoothGattCharacteristic.FORMAT_UINT8;
Log.d(TAG, "Heart rate format UINT8.");
}
final int heartRate = characteristic.getIntValue(format, 1);
Log.d(TAG, String.format("Received heart rate: %d", heartRate));
intent.putExtra(EXTRA_DATA, String.valueOf(heartRate));
} else {
final byte[] data = characteristic.getValue();
// ---------------------------------
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for (byte byteChar : data) {
stringBuilder.append(String.format("%02X ", byteChar));
}
// stringBuilder.append(String.valueOf(byteChar));

intent.putExtra(EXTRA_DATA, new String(data) + "\n"+ stringBuilder.toString());
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
System.out.println(df.format(System.currentTimeMillis())+ "-----" + stringBuilder.toString());
intent.putExtra("byte", data);
intent.putExtra("order", order);
// -------------------------------------------------

}
// For all other profiles, writes the data formatted in HEX.

}
sendBroadcast(intent);
}

/**
* 解绑Service
*/
@Override
public boolean onUnbind(Intent intent) {
close();
return super.onUnbind(intent);
}

@Override
public byte[] initReadOrder(int identifying, byte[] be) {
byte[] by = null;
switch (identifying) {
case Constant.PRODUCT_PARAMETER:
if (be != null) {

by = new byte[7];
by[0] = 0x11;
by[1] = 0x08;
by[2] = 0x01;
by[3] = 0x03;
by[4] = be[0];
by[5] = be[1];
by[6] = be[2];
}
break;
case Constant.DATA:
by = new byte[4];
by[0] = 0x11;
by[1] = 0x02;
by[2] = 0x08;
by[3] = 0x00;
break;
case Constant.HISTORY_RECORD:// 历史记录
if (be != null) {

by = new byte[6];
by[0] = Constant.SERIES_NUMBER[0];
by[1] = Constant.SERIES_NUMBER[1];
by[2] = Constant.SERIES_NUMBER[2];
by[3] = Constant.SERIES_NUMBER[3];
by[4] = be[0];
by[5] = be[1];
}
break;
case Constant.USER_INFO:// 写入用户信息
by = new byte[14];
by[0] = 0x11;
by[1] = 0x04;
by[2] = 0x08;
by[3] = 0x0A;
by[4] = Constant.SERIES_NUMBER[0];
by[5] = Constant.SERIES_NUMBER[1];
by[6] = Constant.SERIES_NUMBER[2];
by[7] = Constant.SERIES_NUMBER[3];
break;
case Constant.USER_HISTORY_RECORD:// 读取用户信息,查询是否有历史记录
by = new byte[8];
by[0] = 0x11;
by[1] = 0x03;
by[2] = 0x08;
by[3] = 0x04;
by[4] = Constant.SERIES_NUMBER[0];
by[5] = Constant.SERIES_NUMBER[1];
by[6] = Constant.SERIES_NUMBER[2];
by[7] = Constant.SERIES_NUMBER[3];
break;

default:
break;
}
return by;
}

@Override
public byte[] int2byte(int res) {
byte[] targets = new byte[2];
targets[0] = (byte) ((res >> 8) & 0xff);
targets[1] = (byte) (res & 0xff);
return targets;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: