这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战
这次实际项目中要求了手机终端和低功耗蓝牙即蓝牙4.0通讯的功能,所以这次我也就把我自己的Android代码同大家分享,稍后考虑将框架整理后上传Github供大家交流学习。
1.蓝牙初始化
//初始化蓝牙设备
private void init_ble() {
// 手机硬件支持蓝牙
if (!getPackageManager().hasSystemFeature(
PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, "不支持BLE", Toast.LENGTH_SHORT).show();
}
// Initializes Bluetooth adapter.
// 获取手机本地的蓝牙适配器
final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
// 打开蓝牙权限
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
}
首先判断手机硬件是否支持低功耗蓝牙,如果支持那么获取手机的蓝牙适配器,接着判断蓝牙权限是否已经开启,如果未开启则去申请。
在这里大家也可以重写onActivityResult方法来对蓝牙开启成功后进行一个提示,这里我就没有写了。
2.简单蓝牙Fragment的实现
Fragment界面
在这里我们单独使用一个Fragment来进行蓝牙功能的演示,界面如下:
具体布局很简单,主要就是几个扫描和断开连接,下面三个按钮与此功能无关,是发送命令的,中间的listview显示可以连接的设备。
好了,下面我们将重点讲解具体的程序流程。
功能控件的定义
包括以下几个:
//扫描蓝牙按钮
private Button btnScan;
//取消蓝牙连接按钮
private Button btnDiscoonect;
//蓝牙适配器
BluetoothAdapter mBluetoothAdapter;
// 蓝牙信号强度
private ArrayList<Integer> rssis;
// 自定义Adapter
LeDeviceListAdapter mleDeviceListAdapter;
//蓝牙连接状态
private boolean mConnected = false;
private String status = "disconnected";
//蓝牙特征值
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>();
private static BluetoothGattCharacteristic target_chara = null;
//蓝牙设备的list
private ListView lvDevice;
// 描述扫描蓝牙的状态
private boolean mScanning;
private boolean scan_flag;
//设备信息
public String deviceName;
public String deviceAddress;
public String deviceRssi;
// 蓝牙扫描时间
private static final long SCAN_PERIOD = 10000;
扫描蓝牙设备
case R.id.btn_scan_dev:
if (scan_flag) {
boolean gps_able = false;
mleDeviceListAdapter = new LeDeviceListAdapter();
lvDevice.setAdapter(mleDeviceListAdapter);
gps_able = isGpsEnable(getActivity());
if (gps_able == true) {
scanLeDevice(true);
} else {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
int requestCode = 1;
this.startActivityForResult(intent, requestCode);
}
} else {
scanLeDevice(false);
btnScan.setText("Scan Device");
}
break;
注意:大家可能会对其中对于GPS的操作感到疑惑,但是在Android6.0之后的系统中,想要扫描到蓝牙必须动态添加位置权限。
首先判断当前是否已经扫描,初始flag为true,然后初始化listview的适配器并检查当前位置权限有没有开启,如果开启了则开始扫描。
private void scanLeDevice(final boolean enable) {
if (enable) {
/* 开始扫描蓝牙设备,带mLeScanCallback 回调函数 */
Log.i("SCAN", "begin.....................");
mScanning = true;
scan_flag = false;
btnScan.setText("Stop Scanning");
mBluetoothAdapter.startLeScan(mLeScanCallback);
//TODO:版本
/*if(android.os.Build.VERSION.SDK_INT<21)
bluetoothAdapter.startLeScan(this);
else{
bluetoothLeScanner.startScan(callBack);
}*/
} else {
Log.i("Stop", "stoping................");
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
scan_flag = true;
}
}
核心还是调用了蓝牙适配器的startLeScan方法或者StartScan方法,这个看你的API版本了,下面我们需要重写我们的LeScanCallback函数,用来扫描到的蓝牙信息并添加到我们的listview中去。
/**
* 蓝牙扫描回调函数 实现扫描蓝牙设备,回调蓝牙BluetoothDevice,可以获取name MAC等信息
**/
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
byte[] scanRecord) {
// TODO Auto-generated method stub
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
/* 讲扫描到设备的信息输出到listview的适配器 */
mleDeviceListAdapter.addDevice(device, rssi);
mleDeviceListAdapter.notifyDataSetChanged();
}
});
System.out.println("Address:" + device.getAddress());
System.out.println("Name:" + device.getName());
System.out.println("rssi:" + rssi);
}
};
注意我们是在Fragment中运行的,想要修改UI需要利用上述runOnUiThread方法。
以上就完成了扫描蓝牙设备并添加更新listview的功能了。
蓝牙设备的连接
当点击的listview中展示的对应设备Item的时候我们将对此设备进行连接:
/* listview点击函数 */
lvDevice.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View v, int position,
long id) {
// TODO Auto-generated method stub
final BluetoothDevice device = mleDeviceListAdapter
.getDevice(position);
//这里是更新工具类的信息,可以不看
fBleUtils.setDeviceName(device.getName());
fBleUtils.setDeviceAddress(device.getAddress());
fBleUtils.setRssi(rssis.get(position).toString());
fBleUtils.setBluetoothDevice(device);
fBleUtils.setBluetoothAdapter(mBluetoothAdapter);
//获取Item的信息
deviceName = device.getName();
deviceAddress = device.getAddress();
deviceRssi = rssis.get(position).toString();
if (device == null)
return;
//扫描到蓝牙设备即为true
if (mScanning) {
/* 停止扫描设备 */
mBluetoothAdapter.stopLeScan(mLeScanCallback);
mScanning = false;
}
try {
//启动蓝牙服务
Intent gattServiceIntent = new Intent(getActivity(), BluetoothLeService.class);
getActivity().bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
//注册广播接收器
getActivity().registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
if (mBluetoothLeService != null) {
//根据蓝牙地址,建立连接
final boolean result = mBluetoothLeService.connect(deviceAddress);
Log.d(TAG, "Connect request result=" + result);
}
} catch (Exception e) {
e.printStackTrace();
// TODO: handle exception
}
}
});
首先获取我们点击的设备Item的相关信息,然后关闭扫描。
之后我们需要启动我们的蓝牙服务类(这个类会在下面一节介绍),相当于启动了蓝牙服务。
最后我们根据定义的过滤器来为当前活动注册一个广播接收器(接收蓝牙服务类传来的信息),并根据地址来建立连接。
/* BluetoothLeService绑定的回调函数 */
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName,
IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
}
// Automatically connects to the device upon successful start-up
// initialization.
// 根据蓝牙地址,连接设备
mBluetoothLeService.connect(deviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
注册广播接收器-蓝牙信息接收
具体注册2.4已经说明了,这里把接收器内容提一下:
/**
* 广播接收器,负责接收BluetoothLeService类发送的数据
*/
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action))//Gatt连接成功
{
mConnected = true;
status = "connected";
//更新连接状态
updateConnectionState(status);
System.out.println("BroadcastReceiver :" + "device connected");
Toast.makeText(getActivity(),"AM_Tool连接成功!",Toast.LENGTH_SHORT).show();
} else if (BluetoothLeService.ACTION_GATT_DISCONNECTED//Gatt连接失败
.equals(action)) {
mConnected = false;
status = "disconnected";
//更新连接状态
updateConnectionState(status);
System.out.println("BroadcastReceiver :"
+ "device disconnected");
Toast.makeText(getActivity(),"AM_Tool连接失败!",Toast.LENGTH_SHORT).show();
} else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED//发现GATT服务器
.equals(action)) {
// Show all the supported services and characteristics on the
// user interface.
//获取设备的所有蓝牙服务
displayGattServices(mBluetoothLeService
.getSupportedGattServices());
System.out.println("BroadcastReceiver :"
+ "device SERVICES_DISCOVERED");
} else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action))//有效数据
{
//处理发送过来的数据
displayData(intent.getExtras().getString(
BluetoothLeService.EXTRA_DATA));
System.out.println("BroadcastReceiver onData:"
+ intent.getStringExtra(BluetoothLeService.EXTRA_DATA));
}
}
};
/* 更新连接状态 */ private void updateConnectionState(String status) { tvStatus.setText(status); if (status.equals("connected")){ btnDiscoonect.setEnabled(true); }else { btnDiscoonect.setEnabled(false); } }
过滤器:
/* 意图过滤器 */
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE);
return intentFilter;
}
其实逻辑很简单,根据蓝牙服务类intent传来的action的类别进行不同的处理,对应的action已经通过Filter添加了。
主要就是根据蓝牙连接情况进行用户提示以及UI变更:Gatt连接成功时候提示连接成功并更新TextView,失败时候同理。
displayGattServices这个方法我也将在下面介绍一下,但是这个功能应该是固定的,如果就是使用的话不需要变动。
下面的displayData就是对于我们开发者来说比较重要的功能了,它主要获得蓝牙服务接收到的数据包,简而言之就是协议处理过后的下位机或者终端发送的数据了:
/**
* @param @param rev_string(接受的数据)
* @return void
* @throws
* @Title: displayData
* @Description: TODO(接收到的数据另外两个Fragment中显示!!!)
*/
private void displayData(final String rev_string) {
getActivity().runOnUiThread(new Runnable() {
@Override
public void run() {
String[] direction = rev_string.split("=");
if (direction[0].equals("left_distance")){
fBleUtils.setLeftXLocation(60.0f - Float.parseFloat(direction[1]));
fBleUtils.setLeftDistance(Float.parseFloat(direction[1]));
}else if (direction[0].equals("center_distance")){
fBleUtils.setCenterYLocation(60.0f - Float.parseFloat(direction[1]));
fBleUtils.setCenterDistance(Float.parseFloat(direction[1]));
}else if (direction[0].equals("right_distance")){
fBleUtils.setRightFloatDistance(Float.parseFloat(direction[1]));
fBleUtils.setRightDistance(Float.parseFloat(direction[1]));
}
tvStatus.setText(rev_string);
mDrawerActivity.setBleUtils(fBleUtils);
btnDiscoonect.setEnabled(true);
}
});
}
这里我们用这个数据更新了我们的对应数据TextView与工具类
蓝牙信息的发送
//TODO:选择关闭和开启的红外测距模块
case R.id.btn_left_operation:
if (btnLeftOp.getText().equals("L_Open")) {
Toast.makeText(getActivity(),"打开左边红外测距器",Toast.LENGTH_SHORT).show();
target_chara.setValue("3");
//调用蓝牙服务的写特征值方法实现发送数据
mBluetoothLeService.writeCharacteristic(target_chara);
btnLeftOp.setText(R.string.left_close_status);
} else {
Toast.makeText(getActivity(),"关闭左边红外测距器",Toast.LENGTH_SHORT).show();
target_chara.setValue("2");
//调用蓝牙服务的写特征值方法实现发送数据
mBluetoothLeService.writeCharacteristic(target_chara);
btnLeftOp.setText(R.string.left_open_status);
}
break;
这里我们以一个命令发送按钮为例,首先我们需要给特征值target_chara赋值,然后调用蓝牙服务的发送特征值的命令即可,前提是我们已经连接上了对应设备。
以上我们基本完成了蓝牙初始化-扫描发现蓝牙设备-蓝牙设备的连接-蓝牙接收信息的读取-蓝牙信息的发送这样一套基本的开发流程,如果只是使用蓝牙,那么以上的信息和步骤应该可以满足需求。下面我将具体分析蓝牙服务这个类的功能,帮助大家更好的理解蓝牙通信。
3.蓝牙服务类BluetoothLeService
这个蓝牙服务类运行于后台,帮助我们同蓝牙设备进行连接,并和蓝牙Fragment的广播接收器进行交流,完成蓝牙数据接收和发送的功能。
功能控件的定义
private final static String TAG = "BluetoothLeService";// luetoothLeService.class.getSimpleName();
private List<Sensor> mEnabledSensors = new ArrayList<Sensor>();
//蓝牙相关类
private BluetoothManager mBluetoothManager;
private BluetoothAdapter mBluetoothAdapter;
private String mBluetoothDeviceAddress;
private BluetoothGatt mBluetoothGatt;
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 =zzzzzzzzzzzzz
// UUID.fromString(SampleGattAttributes.HEART_RATE_MEASUREMENT);
private OnDataAvailableListener mOnDataAvailableListener;
这里比较重要的就是BluetoothGatt这个类,这个类通过同给定address的终端设备连接后获得,通过这个类去进行蓝牙通信的操作。
蓝牙服务初始化
这个方法是BleFragment里面BluetoothLeService绑定的回调函数里面调用的:
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName,
IBinder service) {
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
}
// Automatically connects to the device upon successful start-up
// initialization.
// 根据蓝牙地址,连接设备
mBluetoothLeService.connect(deviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
}
};
首先获取服务,然后进行服务的初始化,接着根据地址进行蓝牙设备的连接,初始化代码如下:
/* service 中蓝牙初始化 */
public boolean initialize()
{
// For API level 18 and above, get a reference to BluetoothAdapter
// through
// BluetoothManager.
if (mBluetoothManager == null)
{ //获取系统的蓝牙管理器
mBluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
if (mBluetoothManager == null)
{
Log.e(TAG, "Unable to initialize BluetoothManager.");
return false;
}
}
mBluetoothAdapter = mBluetoothManager.getAdapter();
if (mBluetoothAdapter == null)
{
Log.e(TAG, "Unable to obtain a BluetoothAdapter.");
return false;
}
return true;
}
这里的初始化就是获取当前系统的蓝牙适配器
蓝牙连接
上一节当中我们直接在Fragment里面使用了服务类的connect方法进行连接,这里我们分析里面的功能:
// 连接远程蓝牙
public boolean connect(final String address)
{
if (mBluetoothAdapter == null || address == null)
{
Log.w(TAG,
"BluetoothAdapter not initialized or unspecified address.");
return false;
}
// Previously connected device. Try to reconnect.
if (mBluetoothDeviceAddress != null
&& address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null)
{
Log.d(TAG,
"Trying to use an existing mBluetoothGatt for connection.");
if (mBluetoothGatt.connect())//连接蓝牙,其实就是调用BluetoothGatt的连接方法
{
mConnectionState = STATE_CONNECTING;
return true;
} else
{
return false;
}
}
/* 获取远端的蓝牙设备 */
final BluetoothDevice device = mBluetoothAdapter
.getRemoteDevice(address);
if (device == null)
{
Log.w(TAG, "Device not found. Unable to connect.");
return false;
}
// We want to directly connect to the device, so we are setting the
// autoConnect
// parameter to false.
/* 调用device中的connectGatt连接到远程设备 */
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, "Trying to create a new connection.");
mBluetoothDeviceAddress = address;
mConnectionState = STATE_CONNECTING;
System.out.println("device.getBondState==" + device.getBondState());
return true;
}
首先判断有没有拿到蓝牙适配器,然后判断地址是否拿到且正确,Gatt有没有获得(第一次连接肯定是没有的)。
接着通过地址获取远端的蓝牙设备,然后拿到对应设备的Gatt,所以说第一次连接获得了Gatt()并且绑定了回调函数mGattCallback,第二次连接会进入第二个if中,执行Gatt的conncet方法进行连接并判断连接结果。
Gatt的回调函数BluetoothGattCallback
/* 连接远程设备的回调函数 */
private final BluetoothGattCallback mGattCallback = 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;
/* 通过广播更新连接状态 */
broadcastUpdate(intentAction);
Log.i(TAG, "Connected to GATT server.");
// Attempts to discover services after successful connection.
Log.i(TAG, "Attempting to start service discovery:"
+ mBluetoothGatt.discoverServices());
} else if (newState == BluetoothProfile.STATE_DISCONNECTED)//连接失败
{
intentAction = ACTION_GATT_DISCONNECTED;
mConnectionState = STATE_DISCONNECTED;
Log.i(TAG, "Disconnected from GATT server.");
broadcastUpdate(intentAction);
}
}
/*
* 重写onServicesDiscovered,发现蓝牙服务
*
* */
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status)
{
if (status == BluetoothGatt.GATT_SUCCESS)//发现到服务
{
broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED);
Log.i(TAG, "--onServicesDiscovered called--");
} else
{
Log.w(TAG, "onServicesDiscovered received: " + status);
System.out.println("onServicesDiscovered received: " + status);
}
}
/*
* 特征值的读写
* */
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status)
{
if (status == BluetoothGatt.GATT_SUCCESS)
{
Log.i(TAG, "--onCharacteristicRead called--");
//从特征值读取数据
byte[] sucString = characteristic.getValue();
String string = new String(sucString);
//将数据通过广播到Ble_Fragment
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
/*
* 特征值的改变
* */
@Override
public void onCharacteristicChanged(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic)
{
System.out.println("++++++++++++++++");
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
/*
* 特征值的写
* */
@Override
public void onCharacteristicWrite(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic, int status)
{
Log.w(TAG, "--onCharacteristicWrite--: " + status);
// 以下语句实现 发送完数据或也显示到界面上
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
/*
* 读描述值
* */
@Override
public void onDescriptorRead(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status)
{
// TODO Auto-generated method stub
// super.onDescriptorRead(gatt, descriptor, status);
Log.w(TAG, "----onDescriptorRead status: " + status);
byte[] desc = descriptor.getValue();
if (desc != null)
{
Log.w(TAG, "----onDescriptorRead value: " + new String(desc));
}
}
/*
* 写描述值
* */
@Override
public void onDescriptorWrite(BluetoothGatt gatt,
BluetoothGattDescriptor descriptor, int status)
{
// TODO Auto-generated method stub
// super.onDescriptorWrite(gatt, descriptor, status);
Log.w(TAG, "--onDescriptorWrite--: " + status);
}
/*
* 读写蓝牙信号值
* */
@Override
public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status)
{
// TODO Auto-generated method stub
// super.onReadRemoteRssi(gatt, rssi, status);
Log.w(TAG, "--onReadRemoteRssi--: " + status);
broadcastUpdate(ACTION_DATA_AVAILABLE, rssi);
}
@Override
public void onReliableWriteCompleted(BluetoothGatt gatt, int status)
{
// TODO Auto-generated method stub
// super.onReliableWriteCompleted(gatt, status);
Log.w(TAG, "--onReliableWriteCompleted--: " + status);
}
};
广播更新状态:
//广播意图
private void broadcastUpdate(final String action, int rssi)
{
final Intent intent = new Intent(action);
intent.putExtra(EXTRA_DATA, String.valueOf(rssi));
sendBroadcast(intent);
}
//广播意图
private void broadcastUpdate(final String action)
{
final Intent intent = new Intent(action);
sendBroadcast(intent);
}
/* 广播远程发送过来的数据 */
public void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic)
{
final Intent intent = new Intent(action);
//从特征值获取数据
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));
Log.i(TAG, "***broadcastUpdate: byteChar = " + byteChar);
}
intent.putExtra(EXTRA_DATA, new String(data));
System.out.println("broadcastUpdate for read data:"
+ new String(data));
}
sendBroadcast(intent);
}
这里代码看上去非常多,但是主要就是对蓝牙终端的各种状态的响应,并且和Fragment中注册的广播接收器相配合,完成前后台的交接工作。
这里通过broadcastUpdate方法将不同状态的信息存入intent的EXTRA_DATA中,然后发送广播,与前面广播接收器的过滤器都是一一对应的,确保能够接收到。
其他方法
该服务类还有几个其他方法,具体代码还是比较简单的,这里就直接贴在下面:
/**
* @Title: disconnect
* @Description: TODO(取消蓝牙连接)
* @return void
* @throws
*/
public void disconnect()
{
if (mBluetoothAdapter == null || mBluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.disconnect();
}
/**
* After using a given BLE device, the app must call this method to ensure
* resources are released properly.
*/
/**
* @Title: close
* @Description: TODO(关闭所有蓝牙连接)
* @return void
* @throws
*/
public void close()
{
if (mBluetoothGatt == null)
{
return;
}
mBluetoothGatt.close();
mBluetoothGatt = null;
}
close就是直接关闭了,想要连接还需要重新获取Gatt
/**
* @Title: readCharacteristic
* @Description: TODO(读取特征值)
* @param @param characteristic(要读的特征值)
* @return void 返回类型
* @throws
*/
public void readCharacteristic(BluetoothGattCharacteristic characteristic)
{
if (mBluetoothAdapter == null || mBluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
// 写入特征值
public void writeCharacteristic(BluetoothGattCharacteristic characteristic)
{
if (mBluetoothAdapter == null || mBluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.writeCharacteristic(characteristic);
}
// 读取RSSi
public void readRssi()
{
if (mBluetoothAdapter == null || mBluetoothGatt == null)
{
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readRemoteRssi();
}