android BLE4.0 流程图

时间:2025-01-27 07:02:49

BLE蓝牙在android上连接,底层实现读取的详细执行过程:

1、扫描:

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

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

2、连接和读写数据:

使用来获取到BluetoothGatt对象;

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

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

接着通过获取BluetoothGattCharacteristic;

然后通过Value获取体温数据。


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

;

;

;

;

;

;

;

;

initialize();初始化

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

close();关闭关闭GATT

readCharacteristic();读取指定的characteristic

readDeviceData();读取设备信息

connect();连接设备

getCharacteristic();获取BluetoothGattCharacteristic对象

SendReadOrder();发送读数据指令

getSupportedGattServices();获取所有服务

 

BluetoothLeService采用与显示层bindunbind的方式,在后台保持运行,并提供与前台交互的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
 *
 *      /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 ;

import ;
import ;
import ;
import ;

import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;
import ;


public class BluetoothLeService extends Service implements BleManager{

	private final static String TAG = ();

	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 = ".ACTION_GATT_CONNECTED";
	public final static String ACTION_GATT_DISCONNECTED = ".ACTION_GATT_DISCONNECTED";
	public final static String ACTION_GATT_SERVICES_DISCOVERED = ".ACTION_GATT_SERVICES_DISCOVERED";
	public final static String ACTION_DATA_AVAILABLE = ".ACTION_DATA_AVAILABLE";
	public final static String EXTRA_DATA = ".EXTRA_DATA";

	public final static UUID UUID_HEART_RATE_MEASUREMENT = ("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 = ();
		if (mBluetoothAdapter == null) {
			return false;
		}

		return true;
	}

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

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

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

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

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

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

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

	}

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

		if (mBluetoothDeviceAddress != null&& (mBluetoothDeviceAddress)&& mBluetoothGatt != null) {
			if (()) {
				mConnectionState = STATE_CONNECTING;
				return true;
			} else {
				return false;
			}
		}
		final BluetoothDevice device = (address);
		if (device == null) {
			return false;
		}
		mBluetoothGatt = (this, false, back);
		("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 = (UUID
				.fromString(service_uuid));
		if (gService == null) {
			return null;
		}
		BluetoothGattCharacteristic characteristic = gService
				.getCharacteristic((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 = ();
		(TAG, "storedLevel() - storedLevel=" + storedLevel);
		(by);
		characteristic
		.setWriteType(BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE);
		status = (characteristic);
		(TAG, "writeLlsAlertLevel() - status=" + status);
		return status;

	}

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

		return ();
	}

	public class LocalBinder extends Binder {

		public BluetoothLeService getService() {
			return ;
		}
	}

	@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;
				(TAG, "Connected to GATT server.");
				// Attempts to discover services after successful connection.
				(TAG, "Attempting to start service discovery:"+ ());
				("FH", "mBluetoothGatt-------7897987987:"+().size());
					("已经连接上设备");
					broadcastUpdate(intentAction);
					(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;
				(TAG, "Disconnected from GATT server.");
				broadcastUpdate(intentAction);
				("已经断开设备");
			}
		}

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

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

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

		@Override
		public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
			(TAG, "onCharacteristicWrite" + (()));
		};

	};


	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:
		// /gatt/characteristics/Pages/?u=.heart_rate_measurement.xml
		if (UUID_HEART_RATE_MEASUREMENT.equals(())) {
			int flag = ();
			(TAG, flag + "");
			int format = -1;
			if ((flag & 0x01) != 0) {
				format = BluetoothGattCharacteristic.FORMAT_UINT16;
				(TAG, "Heart rate format UINT16.");
			} else {
				format = BluetoothGattCharacteristic.FORMAT_UINT8;
				(TAG, "Heart rate format UINT8.");
			}
			final int heartRate = (format, 1);
			(TAG, ("Received heart rate: %d", heartRate));
			(EXTRA_DATA, (heartRate));
		} else {
			final byte[] data = ();
			// ---------------------------------
			if (data != null &&  > 0) {
				final StringBuilder stringBuilder = new StringBuilder();
				for (byte byteChar : data) {
					(("%02X ", byteChar));
				}
				// ((byteChar));

				(EXTRA_DATA, new String(data) + "\n"+ ());
				SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
				((())+ "-----" + ());
				("byte", data);
				("order", order);
				// -------------------------------------------------

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

		}
		sendBroadcast(intent);
	}




	/**
	 * 解绑Service
	 */
	@Override
	public boolean onUnbind(Intent intent) {
		close();
		return (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 :
			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;
	}
}