package com.example.test;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Handler;
import android.util.Log;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
/**
* Author: ming.zeng
* Date: 9/4/2020 下午 6:28
* Desc: 蓝牙工具类
*/
public class BLEUtils {
public static final String TAG = "BLEUtils";
public static final String SERVICE_UUID = "00001204-0000-1000-8000-00805f9b34fb";
public static final String CHARACTER_UUID = "00001204-0000-1000-8000-00805f9b34fb";
private BluetoothManager manager;
private BluetoothAdapter mBluetoothAdapter;
//打开蓝牙的请求码
public static final int REQUEST_ENABLE_BLUETOOTH = 10010;
//是否正在扫描蓝牙设备
private boolean mScanning = false;
//设置扫描时长
private static final long SCAN_PERIOD = 10000;
//蓝牙扫描的返回
private BluetoothAdapter.LeScanCallback leScanCallback;
//蓝牙设别的list
private List<BluetoothDevice> bluetoothDeviceList = new ArrayList<BluetoothDevice>();
private Handler mHandler = new Handler();
private LeScanListener leScanListener;
//蓝牙当前连接的设备
private BluetoothDevice mBluetoothDevice;
private BluetoothGattCharacteristic characteristic;
private BluetoothGatt mBluetoothGatt;
private BLEUtils() {
}
private static class BLEUtilsHelper {
static BLEUtils instance = new BLEUtils();
}
public static BLEUtils getInstance() {
return BLEUtilsHelper.instance;
}
public void init(Activity activity) {
manager = (BluetoothManager) activity.getSystemService(Context.BLUETOOTH_SERVICE);
if (manager != null) {
mBluetoothAdapter = manager.getAdapter();
//蓝牙搜索的回调
leScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
if (device.getName() != null) {
if (!bluetoothDeviceList.contains(device)) {//去下重
bluetoothDeviceList.add(device);
}
if (null != leScanListener) {
//返回所有列表
leScanListener.leScanCallBack(bluetoothDeviceList);
}
Log.e(TAG, "scan--" + device.getName());
}
}
};
//判断蓝牙是否正常开启
if ((mBluetoothAdapter == null) || !mBluetoothAdapter.isEnabled()) {
//打开蓝牙
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
} else {
scanLeDevice(true);
}
}
}
/**
* 开始(true)或结束(false)蓝牙扫描
*
* @param enable
*/
private void scanLeDevice(final boolean enable) {
if (enable && !mScanning) {
// 预先定义停止蓝牙扫描的时间(因为蓝牙扫描需要消耗较多的电量)
mHandler.postDelayed(new Runnable() {
@Override
public void run() {
mScanning = false;
mBluetoothAdapter.stopLeScan(leScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
// 定义一个回调接口供扫描结束处理
mBluetoothAdapter.startLeScan(leScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(leScanCallback);
}
}
/**
* 开始搜索蓝牙设备
*
* @param leScanListener 搜索蓝牙设备的回调(返回设备列表)
*/
public void startScanLeDevice(final LeScanListener leScanListener) {
bluetoothDeviceList.clear();
this.leScanListener = leScanListener;
scanLeDevice(true);
}
/**
* 停止搜索设备
*/
public void stopScanLeDevice() {
if (leScanCallback == null)
return;
scanLeDevice(false);
}
/**
* 搜索蓝牙的回调
*/
public interface LeScanListener {
void leScanCallBack(List<BluetoothDevice> bluetoothDeviceList);
}
/**
* 得到BluetoothGatt
*
* @param device 设备
* @param autoConnect 是否自动链接
* @param bluetoothGattCallback 回调
*/
public BluetoothGatt getConnectGatt(Context context, BluetoothDevice device, boolean autoConnect,
BluetoothGattCallback bluetoothGattCallback) {
this.mBluetoothDevice = device;
return device.connectGatt(context, autoConnect, bluetoothGattCallback);
}
public void getConnectGatt(Context context, BluetoothDevice bluetoothDevice) {
mBluetoothDevice = bluetoothDevice;
if (bluetoothDevice != null) {
//第二个参数 是否重连
mBluetoothGatt = bluetoothDevice.connectGatt(context, false, bluetoothGattCallback);
}
}
/**
* 蓝牙连接成功回调
*/
private BluetoothGattCallback bluetoothGattCallback = new BluetoothGattCallback() {
@Override
public void onPhyUpdate(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
super.onPhyUpdate(gatt, txPhy, rxPhy, status);
}
@Override
public void onPhyRead(BluetoothGatt gatt, int txPhy, int rxPhy, int status) {
super.onPhyRead(gatt, txPhy, rxPhy, status);
}
//不要执行耗时操作
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
super.onConnectionStateChange(gatt, status, newState);
if (newState == BluetoothProfile.STATE_CONNECTED) {//连接成功
Log.e(TAG, "onConnectionStateChange 蓝牙连接");
//这里要执行以下方法,会在onServicesDiscovered这个方法中回调,如果在onServicesDiscovered方法中回调成功,设备才真正连接起来,正常通信
gatt.discoverServices();
} else if (newState == BluetoothProfile.STATE_DISCONNECTED) {
Log.e(TAG, "onConnectionStateChange 蓝牙断连");
if (null != mBluetoothDevice) {
//关闭当前新的连接
gatt.close();
characteristic = null;
}
}
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {
super.onServicesDiscovered(gatt, status);
//回调之后,设备之间才真正通信连接起来
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "onServicesDiscovered 蓝牙连接正常");
BluetoothGattService service = gatt.getService(UUID.fromString(SERVICE_UUID));//uuid从硬件工程师获取
characteristic = service.getCharacteristic(UUID.fromString(CHARACTER_UUID));
gatt.readCharacteristic(characteristic);//执行之后,会执行下面的onCharacteristicRead的回调方法
//设置通知,一般设备给手机发送数据,需要以下监听
setCharacteristicNotification(characteristic, true);
//耗时操作,如果有ui操作,需要用到handler
} else {
Log.e(TAG, "onServicesDiscovered 蓝牙连接失败");
}
}
//这个方法一般用不到
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicRead(gatt, characteristic, status);
Log.e(TAG, "callback characteristic read status " + status
+ " in thread " + Thread.currentThread());
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.e(TAG, "read value: " + characteristic.getValue());
}
}
//这个方法是写入数据时的回调,可以和你写入的数据做对比
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
super.onCharacteristicWrite(gatt, characteristic, status);
// Log.e(TAG, "write value: " + FormatUtil.bytesToHexString(characteristic.getValue()));
}
//设备发出通知时会调用到该接口,蓝牙设备给手机发送数据,在这个方法接收
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
super.onCharacteristicChanged(gatt, characteristic);
// Log.e(TAG, "接收:" + FormatUtil.bytesToHexString(characteristic.getValue()));//byte[]转为16进制字符串
// bleWriteReceiveCallback();
byte[] bytes = characteristic.getValue();
String str = new String(bytes);
Log.e(TAG, "## readCharacteristic, 读取到: " + str);
}
};
/**
* 设置通知
*/
public void setCharacteristicNotification(BluetoothGattCharacteristic characteristic, boolean enabled) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
return;
}
mBluetoothGatt.setCharacteristicNotification(characteristic, enabled);
// BluetoothGattDescriptor descriptor = characteristic.getDescriptor(
// UUID.fromString(SampleGattAttributes.CLIENT_CHARACTERISTIC_CONFIG));
// descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
// mBluetoothGatt.writeDescriptor(descriptor);
}
/**
* 写入命令
*/
public void write(byte[] cmd) {
if (characteristic != null) {
// 发出数据
characteristic.setValue(cmd);
if (mBluetoothGatt.writeCharacteristic(characteristic)) {
Log.e(TAG, "写入成功");
} else {
Log.e(TAG, "写入失败");
}
} else {
Log.e(TAG, "write: 蓝牙未连接");
}
}
/**
* 断开蓝牙设备
*/
public void bleDisConnectDevice(BluetoothDevice device) {
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
}
}
/**
* 释放资源
*/
private void releaseResource() {
Log.e(TAG, "断开蓝牙连接,释放资源");
if (mBluetoothGatt != null) {
mBluetoothGatt.disconnect();
mBluetoothGatt.close();
}
}
/**
* 注册蓝牙监听广播
*/
private void registerBleListenerReceiver(Context context) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_CONNECTED);
intentFilter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);
context.registerReceiver(bleListenerReceiver, intentFilter);
}
/**
* 解除蓝牙监听广播
*/
private void unregisterBleListenerReceiver(Context context) {
context.unregisterReceiver(bleListenerReceiver);
}
/**
* 蓝牙监听广播接受者
*/
private BroadcastReceiver bleListenerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//连接的设备信息
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.e(TAG, "蓝牙广播" + action);
if (mBluetoothDevice != null && mBluetoothDevice.equals(device)) {
Log.e(TAG, "收到广播-->是当前连接的蓝牙设备");
if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
Log.e(TAG, "广播 蓝牙已经连接");
} else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
Log.e(TAG, "广播 蓝牙断开连接");
}
} else {
Log.e(TAG, "收到广播-->不是当前连接的蓝牙设备");
}
if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
Log.e(TAG, "STATE_OFF 手机蓝牙关闭");
bluetoothDeviceList.clear();
releaseResource();
break;
case BluetoothAdapter.STATE_TURNING_OFF:
Log.e(TAG, "STATE_TURNING_OFF 蓝牙正在关闭");
//停止蓝牙扫描
scanLeDevice(false);
break;
case BluetoothAdapter.STATE_ON:
Log.d(TAG, "STATE_ON 蓝牙开启");
//扫描蓝牙设备
scanLeDevice(true);
break;
case BluetoothAdapter.STATE_TURNING_ON:
Log.e(TAG, "STATE_TURNING_ON 蓝牙正在开启");
break;
}
}
}
};
}
网友评论