如题:

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;

        }

}

05-05 14:53