如题:
1)断开连接时需要把BluetoothGatt 先disconnect, 然后close, 最后 = null
2)断开某连接的函数处,将与此连接所有相关的成员变量都初始化或清空;
完整代码(取自项目,稳定有效)如下:
package net.southking.smartbattery;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothGattDescriptor;
import android.bluetooth.BluetoothGattCallback;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanRecord;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
// import android.bluetooth.le.BluetoothReceiver;
//import android.net.wifi.ScanResult;
// import android.net.wifi.WifiManager;
// import android.net.wifi.WifiConfiguration;
// import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.net.ConnectivityManager;
// import android.net.NetworkInfo;
import android.os.ParcelUuid;
import android.os.Message;
import android.os.Handler;
import android.os.Bundle;
import android.os.Build;
import android.os.Environment;
import android.os.StrictMode;
import android.text.TextUtils;
import android.content.Context;
import android.provider.MediaStore;
import java.lang.Thread;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.nio.charset.Charset;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Set;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.UUID;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.Collections;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.lang.reflect.Field;
import java.net.NetworkInterface;
import android.app.ActivityManager;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.net.Uri;
import android.Manifest;
import androidx.core.app.ActivityCompat;
import org.json.JSONObject;
//import org.json.JSONArray;
import java.text.SimpleDateFormat;
import androidx.core.content.FileProvider;
public class BleTrans extends org.qtproject.qt.android.bindings.QtActivity
{
//private static m_instance;
public BleTrans(){
// m_instance = this;
this.bleInit();
//android 7.0之后调用相机时需要处理;
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
builder.detectFileUriExposure();
}
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
// builder.detectFileUriExposure();
// }
// //注册广播;
// BluetoothReceiver receiver = new BluetoothReceiver();
// IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
// registerReceiver(receiver,filter);
}
//初始化;
private void bleInit() {
// 创建查询指令串缓存 及 停止充电指令串缓存;
m_buff1 = this.getBuffer1();
m_buff2 = this.getBuffer2();
m_buff3 = this.getBuffer3();
}
-- BLE -- ///
//uuid相关;
//ps2000;
// private static final UUID SERVICE_UUID = UUID.fromString("0000FFF0-0000-1000-8000-00805F9B34FB");
// private static final UUID WriteCharacteristicGuid = UUID.fromString("0000FFF2-0000-1000-8000-00805f9b34fb");
// private static final UUID NotifyCharacteristicGuid = UUID.fromString("0000FFF1-0000-1000-8000-00805f9b34fb"); //READ, WRITE, NOTIFY
//48V;
private static final UUID SERVICE_UUID = UUID.fromString("0000FFE0-0000-1000-8000-00805F9B34FB");
private static final UUID WriteCharacteristicGuid = UUID.fromString("0000FFE1-0000-1000-8000-00805f9b34fb");
private static final UUID NotifyCharacteristicGuid = UUID.fromString("0000FFE1-0000-1000-8000-00805f9b34fb"); //READ, WRITE, NOTIFY
//状态;
// 0=ble.init,
// 1=start.scan.ble, 2=stop.scan.ble,
// 3=ble.connected, 4=ble.disconnect, 5=ble.service.ready;
//
// 10=wifi.init,
// 11=start.scan.wifi, 12=stop.scan.wifi,
// 13=wifi.connected, 14=wifi.disconnect;
private int m_current_state = 0;
//临时数据;
private JSONObject m_jsonDevices = new JSONObject();
private JSONObject m_jsonRecvDatas1 = new JSONObject();
private JSONObject m_jsonRecvDatas2 = new JSONObject();
private JSONObject m_jsonRecvDatas3 = new JSONObject();
private String m_last_msg = "";
private String m_debug_msg = "";
//接收到的数据缓冲区;
private byte[] m_recv_buffer = null;
private int m_recv_curBuf_len = -1;//当前要处理的数据长度(从m_recv_buffer中取);
private boolean m_hw_download = false; //是否开始固件下载;
//BLE GATT;
private BluetoothGatt m_bluetoothGatt; //被手机连接的BLE设备;
//Lock;
ReentrantLock m_deviceLock = new ReentrantLock();
ReentrantLock m_recvDataLock1 = new ReentrantLock();
ReentrantLock m_recvDataLock2 = new ReentrantLock();
ReentrantLock m_recvDataLock3 = new ReentrantLock();
ReentrantLock m_lastMsgLock = new ReentrantLock();
ReentrantLock m_stateLock = new ReentrantLock();
//指令包相关;
private static final int[] m_cmds = new int[]{0x03, 0x02, 0x01};
private byte[] m_buff1, m_buff2, m_buff3; //3个查询指令串;
//BLE扫描相关;
private BluetoothAdapter m_btAdapter = BluetoothAdapter.getDefaultAdapter(); //手机蓝牙适配器;
private BluetoothLeScanner m_bluetoothLeScanner = null; //BLE搜索器;
private static final ParcelUuid m_filterUuid = new ParcelUuid(SERVICE_UUID);
private HashMap<String,BluetoothDevice> m_bleDevices = new HashMap<String,BluetoothDevice>(); //临时缓存,存储搜索到的BLE设备;
//ble扫描回调;
ScanCallback leCallback = new ScanCallback() {
@Override
public void onScanResult(int callbackType, ScanResult result) {
super.onScanResult(callbackType, result);
ScanRecord record = result.getScanRecord();
if(record == null){
return ;
}
List<ParcelUuid> list = record.getServiceUuids();
if(list == null){
return ;
}
boolean flag = false;
if (list.contains(m_filterUuid)) { //过滤非指定的蓝牙(如: 0000a002-xxx...);
byte[] scanRecord = record.getBytes();
if (scanRecord != null ){
flag = true;
}
}
if (flag) {
ScanResult leScanResult = result;
// System.out.println("leScanResult >>>>>>");
// System.out.println(leScanResult);
BluetoothDevice device = leScanResult.getDevice();
String name = device.getName();
// System.out.println(name);
int rssi = leScanResult.getRssi();
String address = device.getAddress();
if (!TextUtils.isEmpty(name) && !TextUtils.isEmpty(address)) {
if(m_deviceLock.tryLock()){
try{
JSONObject devObj = new JSONObject();
devObj.put("name",name);
devObj.put("rssi",rssi);
devObj.put("addr",address);
m_jsonDevices.put(address,devObj);
m_bleDevices.put(address,device);
} catch (Exception e) {
e.printStackTrace();
}
finally {
m_deviceLock.unlock();
}
}
}
}
}
};
//开始扫描;
private void startBleScanPrivate(){
m_bluetoothLeScanner = m_btAdapter.getBluetoothLeScanner();
// ScanSettings settings = new ScanSettings.Builder().setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
final ScanSettings.Builder builder = new ScanSettings.Builder();
builder.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES);
// builder.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER);
builder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
// builder.setScanResultType(ScanSettings.SCAN_RESULT_TYPE_FULL);
ScanSettings settings = builder.build();
// ScanSettings settings = new ScanSettings.Builder().setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES).setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY).build();
if(m_btAdapter.isDiscovering()){
m_btAdapter.startDiscovery();
}
if(m_lastMsgLock.tryLock()){
m_last_msg = "start scan ble ...";
m_lastMsgLock.unlock();
}
m_bluetoothLeScanner.startScan(new ArrayList<ScanFilter>(), settings, leCallback);
}
public void startBleScan(){
if(m_deviceLock.tryLock()){
m_bleDevices.clear(); //先清空;
m_jsonDevices = new JSONObject();
m_deviceLock.unlock();
}
if(!m_btAdapter.isEnabled()){
m_btAdapter.enable(); //启动本地蓝牙;
//延时处理,因为启动本地蓝牙需要时间;
Timer timer = new Timer();
timer.schedule(new TimerTask(){
@Override
public void run(){
if(!m_btAdapter.isEnabled()){
if(m_lastMsgLock.tryLock()){
m_last_msg = "start bluetooth failed!";
m_lastMsgLock.unlock();
}
return ;
}
startBleScanPrivate();
}
},2000); //2秒后查看是否正常开启;
}
else{
startBleScanPrivate();
}
}
//结束扫描;
public void stopBleScan(){
if(m_lastMsgLock.tryLock()){
m_last_msg = "stop scan ble ...";
m_lastMsgLock.unlock();
}
if(m_btAdapter.isEnabled()){
m_btAdapter.cancelDiscovery();
m_bluetoothLeScanner.stopScan(leCallback);
}
// if(m_deviceLock.tryLock()){
// m_bleDevices.clear(); //先清空;
// m_jsonDevices = new JSONObject();
// m_deviceLock.unlock();
// }
}
//关闭/打开蓝牙
public void openBle(int on){
// if(on >= 1){
// m_btAdapter.enable();
// }
// else{
// m_btAdapter.disable();
// }
openBle2(on>=1);
// if(on>=1){
// // restartBleAdapter();
// // // Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
// // // startActivityForResult(enableBtIntent, 1);
// }
}
private void restartBleAdapter(){
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter != null) {
// 关闭蓝牙适配器
bluetoothAdapter.disable();
// 等待一段时间,确保蓝牙已关闭
delayMsec(1000);
// 重新启用蓝牙适配器
bluetoothAdapter.enable();
} else {
// 设备不支持蓝牙
}
}
//开始连接;
public void startBleConn(String bleAddress) {
try {
//
// if(m_bluetoothGatt != null && m_bluetoothGatt.getConnectedDevices() != null) {
// for(BluetoothDevice dev: m_bluetoothGatt.getConnectedDevices()){
// if(dev.getAddress().equals(bleAddress)){
// m_bluetoothGatt.disconnect();
// break;
// }
// }
// m_bluetoothGatt.close();
// m_bluetoothGatt = null;
// }
// if(m_bluetoothGatt != null){
// m_bluetoothGatt.disconnect();
// delayMsec(250);
// m_bluetoothGatt.close();
// m_bluetoothGatt = null;
// }
// BluetoothManager bluetoothManager = (BluetoothManager)getSystemService(Context.BLUETOOTH_SERVICE);//BLE;
// BluetoothAdapter bluetoothAdapter = bluetoothManager.getAdapter();
// if (!bluetoothAdapter.isEnabled()) {
// bluetoothAdapter.enable();
// }
BluetoothDevice device = null;
if(m_deviceLock.tryLock()){
if(!m_bleDevices.containsKey(bleAddress)){
m_deviceLock.unlock();
return ;
}
device = m_bleDevices.get(bleAddress);
m_deviceLock.unlock();
}
if(device == null){
return ;
}
if(m_stateLock.tryLock()){
m_current_state = 1;
m_stateLock.unlock();
}
///开始连接;
m_bluetoothGatt = device.connectGatt(this,false, new BluetoothGattCallback() {//连接某ble;
@Override
public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {//连接状态;
super.onConnectionStateChange(gatt,status,newState);
// if(status == 0){
if (newState == BluetoothProfile.STATE_CONNECTED) {//已连接;
gatt.requestMtu(247);//设置mtu;有些android手机无法获得数据,需要等待一段时间让配置生效;
delayMsec(1000);//等待配置生效;
gatt.discoverServices(); //开始搜索服务;
if(m_stateLock.tryLock()){
m_current_state = 3;
m_stateLock.unlock();
}
if(m_lastMsgLock.tryLock()){
m_last_msg = "ble connect successed! discover services ...";
m_lastMsgLock.unlock();
}
}
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {//连接失败或主动断开连接
// if(gatt == m_bluetoothGatt) {
// System.out.println("same gatt!");
// }
// if(m_bluetoothGatt != null){
// refreshGattCache(m_bluetoothGatt);
// m_bluetoothGatt.close();
// m_bluetoothGatt = null;
// }
if(gatt != null){
refreshGattCache(gatt);
gatt.close();
gatt = null;
}
if(m_stateLock.tryLock()){
m_current_state = 4;
m_stateLock.unlock();
}
if(m_lastMsgLock.tryLock()){
m_last_msg = "ble connect failed!";
m_lastMsgLock.unlock();
}
}
// }
// else{
// gatt.disconnect();
// gatt.close();
// if(status == 133){
// }
// }
}
@Override
public void onServicesDiscovered(BluetoothGatt gatt, int status) {//发现服务;
BluetoothGattService service = gatt.getService(SERVICE_UUID); //服务;
if (service == null) {
return ;
}
//
BluetoothGattCharacteristic characteristic = service.getCharacteristic(NotifyCharacteristicGuid);//获取Notification特征;
//
if (characteristic == null) {
return ;
}
//
boolean isEnableNotification = m_bluetoothGatt.setCharacteristicNotification(characteristic, true); //开启Notification通知;
System.out.println("isEnableNotification => "+isEnableNotification);
if(isEnableNotification) {
List<BluetoothGattDescriptor> descriptorList = characteristic.getDescriptors();
if(descriptorList != null && descriptorList.size() > 0){
for(BluetoothGattDescriptor descriptor : descriptorList) {
descriptor.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE);
m_bluetoothGatt.writeDescriptor(descriptor);
}
if(m_stateLock.tryLock()){
m_current_state = 5;//服务已启动;
m_stateLock.unlock();
}
if(m_lastMsgLock.tryLock()){
m_last_msg = "ble ready ...";
m_lastMsgLock.unlock();
}
}
}
}
@Override
public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//已发送至BLE时;
String hex = new BigInteger(1,characteristic.getValue()).toString(16);
m_debug_msg = "write to ble: " + hex ;
System.out.println("write to ble => " + hex);
}
@Override
public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) {
//Read recv;
String hex = new BigInteger(1,characteristic.getValue()).toString(16);
m_debug_msg = "read from ble..." + hex;
System.out.println("read from ble: " + hex);
}
@Override
public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) {
//Notification recv;
final byte[] data = characteristic.getValue();
String hex = new BigInteger(1,data).toString(16);
m_debug_msg = "notify from ble... " + hex;
System.out.println("notify from ble: " + hex);
if(data == null){
System.out.println(">>>>>>>>> data == null <<<<<<<<");
return ;
}
final int length = data.length;
if(length <= 0){
System.out.println(">>>>>>>>> length <= 0 <<<<<<<<");
return ;
}
byte head = 0x7E;
if(m_hw_download){
head = 0x7F;
// System.out.println(">>>>>>>>> 0x7F >>> ");
}
if(!m_hw_download){
//
m_recv_buffer = mergeByteArray(m_recv_buffer,data);
// System.out.println(">>>>>>>>> m_recv_buffer : ");
// System.out.println(new BigInteger(1,m_recv_buffer).toString(16));
do{
if(m_recv_buffer.length >= 100){ //累积成巨包,丢弃;
m_recv_buffer = null;
System.out.println(">>>>>>>>> m_recv_buffer.length >= 100 <<<<<<<<");
break ;
}
byte[] curr_buff = removeByteArrFrom(m_recv_buffer, head);
int len = m_recv_buffer.length;
// System.out.println(">>>>>>>>> curr_buff >>> ");
// System.out.println("m_recv_curBuf_len >>> ");
// System.out.println(m_recv_curBuf_len);
if(curr_buff == null){
System.out.println(">>>>>>>>> curr_buff == null <<<<<<<<");
if(len == m_recv_curBuf_len){
m_recv_buffer = null; //清空;
}
else if(m_recv_curBuf_len > 0 && len > m_recv_curBuf_len) { //要从头移除 m_recv_curBuf_len 这么长的数据;
m_recv_buffer = subArr(m_recv_buffer,0,len-m_recv_curBuf_len);
}
break ;
}
m_recv_buffer = subArr(m_recv_buffer,m_recv_curBuf_len,len-m_recv_curBuf_len); //拷贝后面的数据作为新的缓存;
recvDataFromBle(curr_buff);
delayMsec(200);
} while(m_recv_buffer!=null && m_recv_buffer.length>=6);
}
else{
recvDataFromBle(data);
}
}
});
} catch (Exception e) {
e.printStackTrace();
}
}
public boolean refreshGattCache(BluetoothGatt gatt){
boolean result = false;
try {
if(gatt != null){
Method refresh = BluetoothGatt.class.getMethod("refresh");
if(refresh != null){
refresh.setAccessible(true);
result = (boolean)refresh.invoke(gatt,new Object[0]);
}
}
} catch(Exception e){
//
}
return result;
}
//结束连接;
public void stopBleConn() {
if(m_stateLock.tryLock()){
m_current_state = 2;
m_stateLock.unlock();
}
if(m_bluetoothGatt != null){
refreshGattCache(m_bluetoothGatt);
m_bluetoothGatt.disconnect(); //在onConnectionStateChange中作为gatt.close()处理;
//or
// delayMsec(300);
// m_bluetoothGatt.close();
// m_bluetoothGatt = null;
}
//
clearBuff();
}
//发送指令数据到BLE;
private void writeBleData(final byte[] data) {
if (m_bluetoothGatt != null) {
BluetoothGattService service = m_bluetoothGatt.getService(SERVICE_UUID);
if (service != null) {
BluetoothGattCharacteristic characteristic = service.getCharacteristic(WriteCharacteristicGuid);
if (characteristic != null) {
characteristic.setValue(data);
m_bluetoothGatt.writeCharacteristic(characteristic);
}
}
}
}
//延迟;
private void delayMsec(int msec){
try{
Thread.sleep(msec);
} catch (InterruptedException e){
e.printStackTrace();
}
}
//clear;
private void clearBuff(){
//
m_recv_buffer = null;
m_recv_curBuf_len = -1;
m_hw_download = false;
if(m_deviceLock.tryLock()){
// m_bleDevices.clear(); //先清空;
m_jsonDevices = new JSONObject();
m_deviceLock.unlock();
}
if(m_recvDataLock1.tryLock()){
m_jsonRecvDatas1 = new JSONObject();
m_recvDataLock1.unlock();
}
if(m_recvDataLock2.tryLock()){
m_jsonRecvDatas2 = new JSONObject();
m_recvDataLock2.unlock();
}
if(m_recvDataLock3.tryLock()){
m_jsonRecvDatas3 = new JSONObject();
m_recvDataLock3.unlock();
}
}
/// <1> 当前状态
//获取当前状态;
public int getCurrentBleState(){
int state = 0;
if(m_stateLock.tryLock()){
state = m_current_state;
m_stateLock.unlock();
}
return state;
}
//获取设备列表;
public String getBleDevices(){
String devices = "";
if(m_deviceLock.tryLock()){
devices = m_jsonDevices.toString();
m_deviceLock.unlock();
}
return devices;
}
//获取接收到的数据(loop);
public String getBleLastRecvData1(){
String recv = "";
if(m_recvDataLock1.tryLock()){
recv = m_jsonRecvDatas1.toString();
m_recvDataLock1.unlock();
}
return recv;
}
//获取request的数据;
public String getBleLastRecvData2(){
String recv = "";
if(m_recvDataLock2.tryLock()){
recv = m_jsonRecvDatas2.toString();
m_recvDataLock2.unlock();
}
return recv;
}
//download / get fw ver;
public String getBleLastRecvData3(){
String recv = "";
if(m_recvDataLock3.tryLock()){
recv = m_jsonRecvDatas3.toString();
m_recvDataLock3.unlock();
}
return recv;
}
//获取当前的信息;
public String getBleLastMessage(){
String msg = "";
if(m_lastMsgLock.tryLock()){
msg = m_last_msg;
m_lastMsgLock.unlock();
}
return msg;
}
//获取调试信息;
public String getDebugMessage(){
return m_debug_msg;
}
/ -- <1> end --//
<2> private 基础功能函数 //
//小端:低字节在低地址端,高字节在高地址端;大端则相反;
//8位unsigned 转为 有符号byte; v 为 [0,255] 之间的数;
private byte int2byte(int v) {
ByteBuffer buffer = ByteBuffer.allocate(4);
buffer.putInt(v);
return buffer.get(3); //小端; low + height
}
//效果同上;
private byte int2byte2(int v){
if(v < 0x80){
return (byte)v;
}
// return (byte)(((~v+0x01)+0x80)>>24); //大端;
return (byte)v; //大端;
}
//16位unsigned 转为 两个byte; 大端: height + low;
private byte[] int16ToByte2(int v){
byte[] b = new byte[2];
b[0] = (byte)(v>>8);
b[1] = (byte)v;
return b;
}
//两个byte转换为16位unsigned int; 小端: low+height;
private int byte2ToInt16(byte[] b){
return (b[0]&0xff) | ((b[1]&0xff)<<8);
}
//两个byte转换为16位unsigned int; 大端: height+low;
private int byte2ToInt16H(byte[] b){
return (b[1]&0xff) | ((b[0]&0xff)<<8);
}
//32位unsigned 转 4个byte, 大端: height + low;
private byte[] int32ToByte4(int v){
byte[] b = new byte[4];
b[0] = (byte) v;
b[1] = (byte) (v >> 8);
b[2] = (byte) (v >> 16);
b[3] = (byte) (v >> 24);
return b;
}
//从byte数组中节取一部分为子byte数组;
private byte[] subArr(byte[] arr, int beg, int len){
if(arr.length == 0 || beg < 0 || len <= 0) {
return null;
}
if(arr.length < len || arr.length <= beg || beg+len > arr.length){
return null;
}
byte[] res = new byte[len];
System.arraycopy(arr,beg,res,0,len);
return res;
}
//从arr中找到首次出现某值的位置;
private int indexOf(byte[] arr, byte b)
{
for(int i=0;i<arr.length;i++){
if(arr[i] == b){
return i;
}
}
return -1;
}
//以16进制打印byte数组;
private void printHexByteArr(byte[] arr)
{
if(arr == null || arr.length <= 0){
System.out.println("print arr == null!");
return ;
}
for(byte b : arr){
String hex = Integer.toHexString(b&0xFF);
if(hex.length() == 1){
hex = "0" + hex;
}
System.out.print(hex.toUpperCase() + " ");
}
System.out.println();
}
//CRC-8
private byte crc8(byte[] datas) {
int i = 0;
byte crc = 0;
int length = datas.length;
while(length-- > 0){
crc ^= datas[i++];
for(int j=0;j<8;j++){
if((crc & 0x80) != 0) {
crc = int2byte2((crc << 1) ^ 0x07);
}
else {
crc <<= 1;
}
}
}
return crc;
}
//4个字节转成32位正整数;
private double byte4Int32(byte[] bytes){
return (bytes[0] & 0xff) << 24
| (bytes[1] & 0xff) << 16
| (bytes[2] & 0xff) << 8
| (bytes[3] & 0xff);
}
//2个字节转成16位的正整数(前面加两个字节,使其变成正整数);
private double byte2Int16(byte[] bytes){
return (0x00) << 24
| (0x00) << 16
| (bytes[0] & 0xff) << 8
| (bytes[1] & 0xff);
}
//1个字节转成16位的正整数(前面加3个字节,使其变成正整数);
private double byteOne2Int16(byte bt){
return (0x00) << 24
| (0x00) << 16
| (0x00) << 8
| (bt & 0xff);
}
//1个字节转成16位的正整数(前面加1个字节,使其变成正整数);
private int byte2Int8(byte bt){
return (0x00) << 8
| (bt & 0xff);
}
//包协议拼装
private byte[] getCommand(byte commandType, byte commandLength, byte[] content) {
byte[] result = null;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write((byte) 0x7E);
os.write(commandType);
os.write(commandLength);
os.write(content);
os.write(crc8(subArr(content,0,commandLength)));
os.write((byte) 0x0D);
result = os.toByteArray();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//包协议拼装2
private byte[] getCommand2(byte commandType, byte commandLength, byte[] content) {
byte[] result = null;
try {
ByteArrayOutputStream os = new ByteArrayOutputStream();
os.write((byte) 0x7F);
os.write(commandType);
os.write(commandLength);
os.write(content);
os.write(crc8(subArr(content,0,byte2Int8(commandLength))));
os.write((byte) 0x0D);
result = os.toByteArray();
os.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
//合并两个byte数组; 返回合并后的数组;
private byte[] mergeByteArray(byte[] arr1, byte[] arr2)
{
if(arr1 == null || arr1.length <= 0){
if(arr2 != null && arr2.length > 0) {
int len2 = arr2.length;
byte[] arr0 = new byte[len2];
System.arraycopy(arr2,0,arr0,0,len2);
return arr0;
}
}
else if(arr2 == null || arr2.length <= 0)
{
if(arr1 != null && arr1.length > 0) {
int len1 = arr1.length;
byte[] arr0 = new byte[len1];
System.arraycopy(arr1,0,arr0,0,len1);
return arr0;
}
}
else if(arr1 != null && arr1.length > 0 && arr2 != null && arr2.length > 0){
int len1 = arr1.length;
int len2 = arr2.length;
byte[] arr0 = new byte[len1+len2];
System.arraycopy(arr1,0,arr0,0,len1);
System.arraycopy(arr2,0,arr0,len1,len2);
return arr0;
}
return null;
}
//按协议从byte数组中移出一个协议数据包;
private byte[] removeByteArrFrom(byte[] arr, byte head)
{
System.out.println(">>>>>>>>> arr : ");
System.out.println(new BigInteger(1,arr).toString(16));
m_recv_curBuf_len = 0;
if(arr == null || arr.length < 6){
System.out.println(">>>>>>>>> arr == null || arr.length < 6 <<<<<<<<");
return null;
}
int len = arr.length;
int begIdx = indexOf(arr,head); //查找包头位置;
if(begIdx < 0){ //找不到包头,为非法数据,全丢弃!
m_recv_curBuf_len = len;
System.out.println(">>>>>>>>> begIdx < 0 <<<<<<<<");
return null;
}
if(len < begIdx+6){//最小长度都不够,需要继续接收数据;
System.out.println(">>>>>>>>> len < begIdx+6 <<<<<<<<");
return null;
}
//此时最小数据长度足够;
int dataLen = byte2Int8(arr[begIdx+2]); //计算包内业务数据长度;
if(len-begIdx < 5+dataLen){ //完整协议包不够,需要继续接收数据;
System.out.println(">>>>>>>>> len-begIdx < 5+dataLen <<<<<<<<");
System.out.println("len:"+len+", begIdx="+begIdx+", dataLen="+dataLen);
return null;
}
//此时为协议包长度,再判断crc和结束符是否相同;
int endIdx = begIdx+4+dataLen;
m_recv_curBuf_len = endIdx+1;
if(arr[endIdx] != (byte)0x0D){//结尾错误,非法包;
m_recv_curBuf_len = len;
System.out.println(">>>>>>>>> arr[endIdx] != (byte)0x0D <<<<<<<<");
return null; //全丢弃;
}
//crc, 这里不究;
//
byte[] firstArr = subArr(arr,begIdx,5+dataLen);
// arr = subArr(arr,endIdx+1,len-endIdx-1); //拷贝后面的数据作为新的缓存;
return firstArr;
}
//-------<2> end -----------/
<3> 协议相关 //
private void recvData1(int cmd, byte[] data)
{
if(m_recvDataLock1.tryLock())
{
try{
JSONObject ret = new JSONObject();
ret.put("Cmd",cmd);
switch(cmd)
{
case 0x01://电池包电压;
if(data.length >= 13)
{
int nums = byte2Int8(data[2]) / 2;
if(data.length >= (5 + nums*2) ){
int idx = 3;
for(int i=1; i<=nums; i++,idx+=2){
byte[] c = new byte[2];
c[0] = data[idx+1];
c[1] = data[idx];
ret.put("Cell"+i,byte2Int16(c));
}
m_jsonRecvDatas1 = ret;
}
}
break;
case 0x02://实时电池包电流,温度,容量,循环次数;
if(data.length >= 13)
{
int len = byte2Int8(data[2]);
byte[] curr = new byte[2];
if((data[4] & 0x80) == 0x80){ //放电;
curr[0] = int2byte2(0xFF - byte2Int8(data[4]));
curr[1] = int2byte2(0xFF - byte2Int8(data[3]));
ret.put("Curr",-byte2Int16(curr));
}
else{
curr[0] = data[4];
curr[1] = data[3];
ret.put("Curr",byte2Int16(curr));
}
//
byte[] temp = new byte[2];
temp[0] = data[6];
temp[1] = data[5];
ret.put("Temp1",(byte2Int16(temp)-2731)/10.0);
if(len == 8)
{
ret.put("VolumeLeft",byteOne2Int16(data[7])); //剩余容量(百分率);
ret.put("VolumeTotal",byteOne2Int16(data[8])); //总容量;
byte[] cycle = new byte[2];
cycle[0] = data[10];
cycle[1] = data[9];
ret.put("Cycle",byte2Int16(cycle));
}
else if(len >= 12)
{
byte[] temp2 = new byte[2];
temp2[0] = data[8];
temp2[1] = data[7];
ret.put("Temp2",(byte2Int16(temp2)-2731)/10.0);
byte[] temp3 = new byte[2];
temp3[0] = data[10];
temp3[1] = data[9];
ret.put("Temp3",(byte2Int16(temp3)-2731)/10.0);
if(len==12){
ret.put("VolumeLeft",byteOne2Int16(data[11])); //剩余容量(百分率);
ret.put("VolumeTotal",byteOne2Int16(data[12])); //总容量;
byte[] cycle = new byte[2];
cycle[0] = data[14];
cycle[1] = data[13];
ret.put("Cycle",byte2Int16(cycle));
}
else if(len == 13){
ret.put("HeatStatus",byteOne2Int16(data[11])); //加热状态;
ret.put("VolumeLeft",byteOne2Int16(data[12])); //剩余容量(百分率);
ret.put("VolumeTotal",byteOne2Int16(data[13])); //总容量;
byte[] cycle = new byte[2];
cycle[0] = data[15];
cycle[1] = data[14];
ret.put("Cycle",byte2Int16(cycle));
}
}
m_jsonRecvDatas1 = ret;
}
break;
case 0x03: //电池包输出状态;
if(data.length >= 11)
{
ret.put("HealthSt1",byteOne2Int16(data[3]));
ret.put("HealthSt2",byteOne2Int16(data[4]));
ret.put("HealthSt3",byteOne2Int16(data[5]));
ret.put("HealthSt4",byteOne2Int16(data[6]));
byte[] ts = new byte[2];
ts[0] = data[8];
ts[1] = data[7];
ret.put("StartTimes", byte2Int16(ts));
m_jsonRecvDatas1 = ret;
}
else if(data.length >= 9)
{
ret.put("HealthSt1",byteOne2Int16(data[3]));
ret.put("HealthSt2",byteOne2Int16(data[4]));
byte[] ts = new byte[2];
ts[0] = data[6];
ts[1] = data[5];
ret.put("StartTimes", byte2Int16(ts));
m_jsonRecvDatas1 = ret;
}
break;
}
}catch (Exception e){
e.printStackTrace();
} finally {
m_recvDataLock1.unlock();
}
}
}
private void recvData2(int cmd, byte[] data)
{
if(m_recvDataLock2.tryLock())
{
try{
JSONObject ret = new JSONObject();
ret.put("Cmd",cmd);
switch(cmd)
{
case 0x20://控制电池关闭;
if(data.length >= 9){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
ret.put("X2",byteOne2Int16(data[5]));
ret.put("X3",byteOne2Int16(data[6]));
m_jsonRecvDatas2 = ret;
}
else if(data.length >= 7){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
m_jsonRecvDatas2 = ret;
}
break;
case 0x21://控制电池开启;
if(data.length >= 9){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
ret.put("X2",byteOne2Int16(data[5]));
ret.put("X3",byteOne2Int16(data[6]));
m_jsonRecvDatas2 = ret;
}
else if(data.length >= 7){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
m_jsonRecvDatas2 = ret;
}
break;
case 0x23://手动加热关闭;
if(data.length >= 9){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
ret.put("X2",byteOne2Int16(data[5]));
ret.put("X3",byteOne2Int16(data[6]));
m_jsonRecvDatas2 = ret;
}
else if(data.length >= 7){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
m_jsonRecvDatas2 = ret;
}
break;
case 0x22://手动加热开启;
if(data.length >= 9){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
ret.put("X2",byteOne2Int16(data[5]));
ret.put("X3",byteOne2Int16(data[6]));
m_jsonRecvDatas2 = ret;
}
else if(data.length >= 7){
ret.put("X0",byteOne2Int16(data[3]));
ret.put("X1",byteOne2Int16(data[4]));
m_jsonRecvDatas2 = ret;
}
break;
case 0x60: //配置/查询序列号;
if(data.length >= 13){
String sn = new String(subArr(data,3,8), StandardCharsets.UTF_8);
System.out.println(sn);
ret.put("SN",sn);
m_jsonRecvDatas2 = ret;
}
break;
case 0x40: //密码修改、验证;
if(data.length >= 7){
ret.put("PwdRes", byteOne2Int16(data[3]));
m_jsonRecvDatas2 = ret;
}
break;
}
}catch (Exception e){
e.printStackTrace();
} finally {
m_recvDataLock2.unlock();
}
}
}
private void recvData3(int cmd, byte[] data)
{
if(m_recvDataLock3.tryLock())
{
try{
JSONObject ret = new JSONObject();
ret.put("Cmd1",cmd);
switch(cmd)
{
case 0x1F://版本;
if(data.length >= 7){
int len = byte2Int8(data[2]);
if(data.length >= len+5){
String ver = new String(subArr(data,3,len), StandardCharsets.UTF_8);
System.out.println(ver);
ret.put("Ver",ver);
m_jsonRecvDatas3 = ret;
}
}
break;
case 0x10: //升级命令;
if(data.length >= 8){
int idx = byte2ToInt16(subArr(data,3,2));
int stat = byte2Int8(data[5]);
ret.put("Index",idx);
ret.put("Succ",stat==0);
m_jsonRecvDatas3 = ret;
}
break;
case 0x11://升级验证;
System.out.println("chk........");
if(data.length >= 6){
int stat = byte2Int8(data[3]);
ret.put("Succ",stat==0);
m_jsonRecvDatas3 = ret;
System.out.println("chk succ!");
}
break;
}
}catch (Exception e){
e.printStackTrace();
} finally {
m_recvDataLock3.unlock();
}
}
}
>>> 接收到btye[]数据,并转换成json数据;
private void recvDataFromBle(byte[] data) {
if(data == null || data.length <= 2){
System.out.println(">>>>>>>>> data == null || data.length <= 2 <<<<<<<<");
return ;
}
System.out.print("recv package: ");
printHexByteArr(data);
int head = byte2Int8(data[0]);
int cmd = byte2Int8(data[1]);
//
if(0x7E == head)
{
if(cmd <= 0x03){
recvData1(cmd, data);
}
else{
recvData2(cmd, data);
}
}
//
if(0x7F == head){
recvData3(cmd, data);
}
}
/--
/ >>> 获取状态数据(定时循环);
public void queryBatteryStatus(int cmd){
switch (cmd) {
case 0x01: //获取当前电池包电压;
this.writeBleData(m_buff1);
break;
case 0x02: //电池包电流/温度/容量;
this.writeBleData(m_buff2);
break;
case 0x03: //电池状态;
this.writeBleData(m_buff3);
break;
}
}
//获取当前电池包电压;
private byte[] getBuffer1() {
byte[] b = new byte[2];
b[0] = 0x00;
b[1] = 0x00;
return this.getCommand((byte) 0x01, (byte) 0x02, b);
}
//电池包电流/温度/容量;
private byte[] getBuffer2() {
byte[] b = new byte[2];
b[0] = 0x00;
b[1] = 0x00;
return this.getCommand((byte) 0x02, (byte) 0x02, b);
}
//电池状态;
private byte[] getBuffer3() {
byte[] b = new byte[2];
b[0] = 0x00;
b[1] = 0x00;
return this.getCommand((byte) 0x03, (byte) 0x02, b);
}
/--
//控制电池关闭;
public void controlBatteryOff(int x0, int x1)
{
byte[] b = new byte[2];
b[0] = int2byte2(x0);
b[1] = int2byte2(x1);
byte[] buff = this.getCommand((byte) 0x20, (byte) 0x02, b);
this.writeBleData(buff);
}
//按制电池开启;
public void controlBatteryOn(int x0, int x1)
{
byte[] b = new byte[2];
b[0] = int2byte2(x0);
b[1] = int2byte2(x1);
byte[] buff = this.getCommand((byte) 0x21, (byte) 0x02, b);
this.writeBleData(buff);
}
//手动加热开启;
public void hotBatteryOff(int x0, int x1)
{
byte[] b = new byte[2];
b[0] = int2byte2(x0);
b[1] = int2byte2(x1);
byte[] buff = this.getCommand((byte) 0x22, (byte) 0x02, b);
this.writeBleData(buff);
}
//手动加热关闭;
public void hotBatteryOn(int x0, int x1)
{
byte[] b = new byte[2];
b[0] = int2byte2(x0);
b[1] = int2byte2(x1);
byte[] buff = this.getCommand((byte) 0x23, (byte) 0x02, b);
this.writeBleData(buff);
}
//修改设备名称;
public void alterDevName(String newName)
{
int nCount = newName.length();
if((nCount < 1) || (nCount > 18)){
return ;
}
try{
// byte[] clearBuf = new byte[16];
// for(int i=0;i<16;i++){
// clearBuf[i] = (byte)0x00;
// }
// this.writeBleData(this.getCommand((byte) 0x30, (byte) 0x10, clearBuf)); //先发送一条清除改名数组缓存指令;
//then.
byte[] ssid = new byte[nCount];
char[] chars = newName.toCharArray();
for(int i=0;i<nCount;i++){
ssid[i] = (byte) chars[i];
}
this.writeBleData(this.getCommand((byte) 0x30, (byte) nCount, ssid)); //再发送改名指令;
} catch (NumberFormatException e){
e.printStackTrace();
}
}
//强制复位;
public void forceReset()
{
byte[] b = new byte[1];
b[0] = 0;
byte[] buff = this.getCommand((byte) 0x50, (byte) 0x01, b);
this.writeBleData(buff);
}
//校准电流;
public void adjustCurrent()
{
byte[] b = new byte[2];
b[0] = 0x01;
b[1] = int2byte2(0xAA);
byte[] buff = this.getCommand((byte) 0x55, (byte) 0x02, b);
this.writeBleData(buff);
}
//查询设备信息;
public void queryDevInfo()
{
byte[] b = new byte[1];
b[0] = 0;
byte[] buff = this.getCommand((byte) 0xF1, (byte) 0x01, b);
this.writeBleData(buff);
}
//开始固件下载的相关操作; 因为粘包处理的包头存在不同;
public void startHwDownload(int on)
{
if(on >= 1){
m_hw_download = true;
}
else{
m_hw_download = false;
}
m_recv_buffer = null;
}
//固件版本查询;
public void queryHwVersion()
{
byte[] b = new byte[1];
b[0] = 0x01;
byte[] buff = this.getCommand2((byte) 0x0F, (byte) 0x01, b);
this.writeBleData(buff);
}
//固件升级;
public void upgradeHw(int idx, int len, String data)
{
//
byte[] b = new byte[len+2];
byte[] lenArr = int16ToByte2(idx);
b[0] = lenArr[1];
b[1] = lenArr[0];
try{
for(int i=0;i<len;i++){
String hex = data.substring(i*2,i*2+2);
int byteVal = Integer.parseInt(hex,16);
b[i+2] = int2byte2(byteVal);
}
byte[] buff = this.getCommand2((byte) 0x00, int2byte2(len+2), b);
this.writeBleData(buff);
} catch (NumberFormatException e){
e.printStackTrace();
}
}
//固件升级验证;
public void upgradeHwChk1(int length, int sum)
{
byte[] b = new byte[20];
byte[] lenArr = int32ToByte4(length);
b[0] = lenArr[0];
b[1] = lenArr[1];
b[2] = lenArr[2];
b[3] = lenArr[3];
byte[] sumArr = int32ToByte4(sum);
b[4] = sumArr[0];
b[5] = sumArr[1];
b[6] = sumArr[2];
b[7] = sumArr[3];
for(int i=4;i<16;i++){
b[i+4] = (byte)0x00;
}
byte[] buff = this.getCommand2((byte) 0x01, (byte) 0x14, b);
this.writeBleData(buff);
}
//固件升级验证2; for 48V
public void upgradeHwChk2(int length, String md5) //md5.length = 32
{
byte[] b = new byte[20];
byte[] lenArr = int32ToByte4(length);
b[0] = lenArr[0];
b[1] = lenArr[1];
b[2] = lenArr[2];
b[3] = lenArr[3];
try{
for(int i=0;i<16;i++){
String hex = md5.substring(i*2,i*2+2);
int byteVal = Integer.parseInt(hex,16);
b[i+4] = int2byte2(byteVal);
}
byte[] buff = this.getCommand2((byte) 0x01, (byte) 0x14, b);
this.writeBleData(buff);
} catch (NumberFormatException e){
e.printStackTrace();
}
}
//寻找电池;
public void searchBattery()
{
byte[] b = new byte[2];
b[0] = 0x00;//int2byte2(x0);
b[1] = 0x00;//int2byte2(x1);
byte[] buff = this.getCommand((byte) 0x0F, (byte) 0x02, b);
this.writeBleData(buff);
}
//查询序列号;
public void querySerialNumber()
{
byte[] b = new byte[1];
b[0] = 0x00; //int2byte2(serial);
byte[] buff = this.getCommand((byte) 0x60, (byte) 0x01, b);
this.writeBleData(buff);
}
//配置序列号;
public void setSerialNumber(String newSN)
{
if(newSN.length() != 8){
return ;
}
byte[] b = new byte[8];
try{
char[] chars = newSN.toCharArray();
for(int i=0;i<8;i++){
b[i] = (byte) chars[i];
}
byte[] buff = this.getCommand((byte) 0x61, (byte) 0x08, b);
this.writeBleData(buff);
} catch (NumberFormatException e){
e.printStackTrace();
}
}
// 验证密码;
public void authPassword(String pwd)
{
if(pwd.length() != 4) {
return ;
}
byte[] b = new byte[4];
char[] chars = pwd.toCharArray();
for(int i=0;i<4;i++){
b[i] = (byte) chars[i];
}
byte[] buff = this.getCommand((byte) 0x40, (byte) 0x04, b);
this.writeBleData(buff);
}
// 修改密码;
public void modifyPassword(String pwd)
{
if(pwd.length() != 4) {
return ;
}
byte[] b = new byte[4];
char[] chars = pwd.toCharArray();
for(int i=0;i<4;i++){
b[i] = (byte) chars[i];
}
byte[] buff = this.getCommand((byte) 0x41, (byte) 0x04, b);
this.writeBleData(buff);
}
//-------<3> end -----------/
<4> BLE相关函数 //
//获取本机蓝牙地址(反射); 获取不到!!
public String getBleLocalAddress1(){
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
try {
Field field = BluetoothAdapter.class.getDeclaredField("mService");
field.setAccessible(true);
Object bluetoothManagerService = field.get(bluetoothAdapter);
if (bluetoothManagerService == null) {
return "";
}
Method method = bluetoothManagerService.getClass().getMethod("getAddress");
if(method == null) {
return "";
}
Object obj = method.invoke(bluetoothManagerService);
if(obj == null) {
return "";
}
return obj.toString();
} catch (Exception e) {
e.printStackTrace();
}
return "";
}
//获取本机蓝牙地址; 获取的为虚拟地址!!
public String getBleLocalAddress2(){
if(Build.VERSION.SDK_INT >= 22){
try{
List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
for(NetworkInterface nif : all){
if(!nif.getName().equalsIgnoreCase("wlan0")){
continue;
}
byte[] macBytes = nif.getHardwareAddress();
if(macBytes == null){
return "";
}
StringBuilder res1 = new StringBuilder();
for(byte b : macBytes){
res1.append(String.format("%02X:",b));
}
if(res1.length() > 0){
res1.deleteCharAt(res1.length() - 1);
}
return res1.toString();
}
} catch (Exception e){
e.printStackTrace();
}
}
else{
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
String macAddr = adapter.getAddress();
return macAddr;
}
return "";
}
//-------<4> end -----------/
<5> 其它非会话连接的功能函数 //
public void openBle2(boolean on){
if(on){
System.out.println("open >>>>> ble !!! ");
startActivityForResult(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE),1);//RESULT_OK==1
}
else{
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
adapter.disable();
System.out.println("close >>>>> ble !!! ");
}
}
//重启app;
public void restartApp(){
restartApp4();
}
private void restartApp0(){
Intent intent = new Intent(this, Object.class);
startActivity(intent);
// System.exit(0);
}
private void restartApp1(){
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
manager.restartPackage("net.southking.smartbattery");
}
private void restartApp2(){
new Handler().postDelayed(new Runnable(){
@Override
public void run(){
// Intent intent = getBaseContext().getPackageManager().getLaunchIntentForPackage(getBaseContext().getPackageName());
// intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// Intent intent = getPackageManager().getLaunchIntentForPackage(getApplication().getPackageName());
Intent intent = getPackageManager().getLaunchIntentForPackage("smartbattery.southking.net");
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
}
},1000);
}
private void restartApp3(){
Intent intent = getPackageManager().getLaunchIntentForPackage(getApplication().getPackageName());
PendingIntent restartIntent = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC, System.currentTimeMillis() + 1000, restartIntent); //1秒后重启;
System.exit(0);
}
private void restartApp4(){ //仅此有用;
Intent intent = getPackageManager().getLaunchIntentForPackage("net.southking.smartbattery");
startActivity(intent);
}
//权限申请;
String[] permission = new String[]{
Manifest.permission.INTERNET,
Manifest.permission.CHANGE_NETWORK_STATE,
Manifest.permission.ACCESS_NETWORK_STATE,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS,
Manifest.permission.WRITE_SETTINGS,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE
};
public void requestPermissions(){ //请求权限;
ActivityCompat.requestPermissions(this,permission,5);
}
//-------<5> end -----------/
}
其实关键的代码也就几行:
if(m_bluetoothGatt != null){
refreshGattCache(m_bluetoothGatt);
m_bluetoothGatt.disconnect(); //在onConnectionStateChange中作为gatt.close()处理;
}
clearBuff();
然后在 public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState)
中
else if (newState == BluetoothProfile.STATE_DISCONNECTED) {//连接失败或主动断开连接
if(gatt != null){
refreshGattCache(gatt);
gatt.close();
gatt = null;
}
}