public class BleService{
private final String TAG="BleService";
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBtMac;
String bleUuid=SampleGattAttributes.DEFAULT_UUID;
BluetoothGattCharacteristic characteristic;
BluetoothGattCharacteristic mNotifyCharacteristic;
private BluetoothGatt mBluetoothGatt;
public final static UUID UUID_HEART_RATE_MEASUREMENT =
UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
public final static UUID UUID_CLIENT_CHARACTERISTIC_CONFIG =
UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG);
private static BleService instance = null;
public static BleService getInstance() {
if (instance == null) {
synchronized (BleService.class) {
if (instance == null) {
instance = new BleService();
}
}
}
return instance;
}
public void setBleUuid(String bleUuid) {
this.bleUuid=bleUuid;
}
public BluetoothGattCharacteristic getCharacteristic() {
return characteristic;
}
public void setCharacteristic(BluetoothGattCharacteristic characteristic) {
this.characteristic = characteristic;
}
/**
* Initializes a reference to the local Bluetooth adapter.
*
* @return Return true if the initialization is successful.
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
public boolean initialize(Context context) {
// For API level 18 and above, get a reference to BluetoothAdapter through
// BluetoothManager.
if (mBluetoothManager == null) {
mBluetoothManager = (BluetoothManager) context.getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null) {
L.e("Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null) {
L.e("Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
public boolean connect(Context context,String btMac) {
if (mBluetoothAdapter == null || btMac == null) {
L.e("BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBtMac != null && btMac.equals(mBtMac)
&& mBluetoothGatt != null) {
L.d("Trying to use an existing mBluetoothGatt for connection.");
return mBluetoothGatt.connect();
}
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(btMac);
// We want to directly connect to the device, so we are setting the autoConnect
// parameter to false.
mBluetoothGatt = device.connectGatt(context, false, mGattCallback);
Log.d(TAG,"mac:"+btMac);
mBtMac = btMac;
return true;
}
/**
* After using a given BLE device, the app must call this method to ensure resources are
* released properly.
*/
public void disConnect() {
if (mBluetoothGatt == null) {
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
setCharacteristic(null);
}
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
if (newState == BluetoothProfile.STATE_CONNECTED) {
Log.d(TAG, "Connected to GATT server.");
mBluetoothGatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
App.BUS.post(new ConnectStatusEventArgs(false));
Log.d(TAG, "Disconnected from GATT server.");
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
if (status == BluetoothGatt.GATT_SUCCESS) {
if (searchGattServices(getSupportedGattServices())){
checkCharacteristic();
}
}else {
App.BUS.post(new ConnectStatusEventArgs(false));
}
Log.d(TAG, "onServicesDiscovered" + status);
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
Log.d(TAG, "onCharacteristicRead");
if (status == BluetoothGatt.GATT_SUCCESS) {
postData(characteristic);
}
}
/**
* 返回数据。
*/
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic) {
postData(characteristic);
}
private void postData(BluetoothGattCharacteristic characteristic){
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));
// }
//
// }
App.BUS.post(new ReceiverDataEventArgs(data));
}
};
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
private boolean checkCharacteristic(){
BluetoothGattCharacteristic characteristic = getCharacteristic();
if (characteristic==null){
App.BUS.post(new ConnectStatusEventArgs(false));
return false;
}
int charaProp = characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_READ) > 0) {
if (mNotifyCharacteristic != null) {
setCharacteristicNotification(
mNotifyCharacteristic, false);
mNotifyCharacteristic = null;
}
readCharacteristic(characteristic);
}
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) {
mNotifyCharacteristic = characteristic;
setCharacteristicNotification(
characteristic, true);
}
App.BUS.post(new ConnectStatusEventArgs(true));
return true;
}
/**
* Retrieves a list of supported GATT services on the connected device. This should be
* invoked only after {@code BluetoothGatt#discoverServices()} completes successfully.
*
* @return A {@code List} of supported services.
*/
public List
if (mBluetoothGatt == null) {
return null;
}
return mBluetoothGatt.getServices();
}
/**
* Enables or disables notification on a give characteristic.
*
* @param characteristic Characteristic to act on.
* @param enabled If true, enable notification. False otherwise.
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic,
boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
/**
* 打开数据FFF4
*/
// This is specific to Heart Rate Measurement.
if (UUID_HEART_RATE_MEASUREMENT.equals(characteristic.getUuid())) {
BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
UUID_CLIENT_CHARACTERISTIC_CONFIG);
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
mBluetoothGatt.writeDescriptor(descriptor);
}
}
/**
* Request a read on a given {@code BluetoothGattCharacteristic}. The read result is reported
* asynchronously through the {@code BluetoothGattCallback#onCharacteristicRead(android.bluetooth.BluetoothGatt, android.bluetooth.BluetoothGattCharacteristic, int)}
* callback.
*
* @param characteristic The characteristic to read from.
*/
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
//写入特征值
public boolean writeCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return false;
}
return mBluetoothGatt.writeCharacteristic(characteristic);
}
public boolean sendCmd(CMD cmd) {
return write(cmd.cmd);
}
public boolean write(byte[] cmd){
if (getCharacteristic()!=null){
int charaProp = this.characteristic.getProperties();
if ((charaProp | BluetoothGattCharacteristic.PROPERTY_WRITE) > 0) {
//注意: 以下读取的值 通过 BluetoothGattCallback#onCharacteristicRead() 函数返回
this.characteristic.setValue(cmd);
return writeCharacteristic(this.characteristic);
}
}
return false;
}
private boolean searchGattServices(List
if (gattServices == null){
return false;
}
String uuid;
for (BluetoothGattService gattService : gattServices) {
//从当前循环所指向的服务中读取特征值列表
List
gattService.getCharacteristics();
// Loops through available Characteristics.
for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) {
uuid = gattCharacteristic.getUuid().toString();
if (bleUuid.equalsIgnoreCase(uuid)){
setCharacteristic(gattCharacteristic);
return true;
}
}
}
return false;
}
}
public class SampleGattAttributes {
public static String DEFAULT_UUID = "0000fff6-0000-1000-8000-00805f9b34fb";
public static String HEART_RATE_MEASUREMENT = "0000FFF4-0000-1000-8000-00805f9b34fb";//"00002a37-0000-1000-8000-00805f9b34fb";
public static String CLIENT_CHARACTERISTIC_CONFIG = "00002902-0000-1000-8000-00805f9b34fb";
}
调用的方式
public boolean connect(Context context,String strBtMac){
if (!mBleService.initialize(context)) {
L.e("Unable to initialize Bluetooth");
return false;
}
// Automatically connects to the device upon successful start-up
// initialization.
mBleService.connect(context,strBtMac);
return true;
}