优化蓝牙扫描,解决上一次扫描结束未来得及处理扫描结果时,就开始新的扫描造成结果被清空的问题。
authorsnickersun <scy@incartech.cn>
Tue, 24 Nov 2020 08:23:16 +0000 (16:23 +0800)
committersnickersun <scy@incartech.cn>
Tue, 24 Nov 2020 08:23:16 +0000 (16:23 +0800)
app/src/main/java/com/enqualcomm/support/adapter/BTHelper.java

index ae2ecb2..8487507 100644 (file)
-package com.enqualcomm.support.adapter;\r
-\r
-import android.bluetooth.BluetoothAdapter;\r
-import android.bluetooth.BluetoothAdapter.LeScanCallback;\r
-import android.bluetooth.BluetoothDevice;\r
-import android.content.BroadcastReceiver;\r
-import android.content.Context;\r
-import android.content.Intent;\r
-import android.content.IntentFilter;\r
-import android.net.wifi.ScanResult;\r
-import android.os.Handler;\r
-import com.enqualcomm.support.bean.Runtime;\r
-import com.enqualcomm.support.Config;\r
-import com.enqualcomm.support.utils.ICLogger;\r
-import com.enqualcomm.support.utils.Util;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.Comparator;\r
-import java.util.Set;\r
-\r
-public class BTHelper {\r
-\r
-    private BluetoothAdapter mBtAdapter;\r
-    private static ArrayList<String> mPairedDevicesArray=new ArrayList<>();\r
-    private static ArrayList<String> mNewDevicesArray=new ArrayList<>();\r
-    private Context mContext=null;\r
-    private BTScanCallback mCallback=null;\r
-    private static BTHelper mBThelper=null;\r
-    private int  BLETimeoutForOneScan=10;\r
-    private static boolean btscanning=false;\r
-    private static Runtime mRuntime;\r
-    private boolean enabledBeforScan=false;\r
-    private static Handler mHandler=null;\r
-    BTHelper(){\r
-\r
-    }\r
-\r
-    public void setBLEScanTimeout(int timeout){\r
-        BLETimeoutForOneScan=timeout;\r
-    }\r
-    private boolean isBeaconFounded(String beaconAddr){\r
-\r
-        String tmp = beaconAddr.replace(":", "").toLowerCase();\r
-        if(tmp.contains(","))\r
-            tmp = tmp.substring(0, tmp.indexOf(","));\r
-        for (String beacon:mRuntime.bleInfo.btMacList){\r
-           if (tmp.equals(beacon)) {\r
-               ICLogger.i("bt mac " + tmp + "  " + beaconAddr.toLowerCase());\r
-               return true;\r
-           }\r
-        }\r
-        return false;\r
-    }\r
-    //enableBT\r
-    public void enableBT() {\r
-        ICLogger.i("BT enableBT()");\r
-\r
-\r
-        if (!mBtAdapter.isEnabled()) {\r
-\r
-            mBtAdapter.enable();\r
-            Util.mSleep(2000);\r
-            //此处无法执行说没权限\r
-//            mBtAdapter.enableNoAutoConnect();\r
-        }\r
-\r
-    }\r
-\r
-    //disableBT\r
-    public void disableBT(){\r
-        ICLogger.i( "BT disableBT()");\r
-         if (mBtAdapter.isEnabled()) {\r
-            mBtAdapter.disable();\r
-        }\r
-    }\r
-\r
-    //初始化 BTHlper\r
-    public void Init(Context context , BTScanCallback callback){\r
-        ICLogger.i( "BT Init()");\r
-        mCallback=callback;\r
-        mContext=context;\r
-        // Get the local Bluetooth adapter\r
-        mBtAdapter = BluetoothAdapter.getDefaultAdapter();\r
-\r
-        if (lecallback==null)\r
-            lecallback= new BLeScanCallback();\r
-        if(mHandler==null)\r
-            mHandler=new Handler();\r
-\r
-    }\r
-\r
-\r
-    //获取实例\r
-    public static BTHelper CreateInstance(Runtime runtime , BTScanCallback callback){\r
-        mRuntime=runtime;\r
-        if (mBThelper==null) {\r
-            ICLogger.i( "BT getInstance ");\r
-            mBThelper = new BTHelper();\r
-            mBThelper.Init(runtime.getContextProxy().context,callback);\r
-        }\r
-        return mBThelper;\r
-    }\r
-\r
-    private  BLeScanCallback lecallback =null;\r
-\r
-    private RunableStopBleScan mRunable_stopBleScan=new RunableStopBleScan();\r
-\r
-    private static boolean hasStopedByFoundBT=false;\r
-    public boolean isBtscanning(){\r
-        return btscanning;\r
-    }\r
-    //开始扫描BLE\r
-    public void scanBLE() {\r
-        ICLogger.i( "BT scanBLE()");\r
-\r
-        if(btscanning==false) {\r
-            btscanning=true;\r
-            enabledBeforScan = mBtAdapter.isEnabled();\r
-            enableBT();\r
-\r
-            mPairedDevicesArray.clear();\r
-            mNewDevicesArray.clear();\r
-\r
-//            mBtAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE, BLETimeoutForOneScan);\r
-\r
-            ICLogger.i("BT startLeScan");\r
-            if (lecallback==null)\r
-                lecallback= new BLeScanCallback();\r
-            if(mHandler==null)\r
-                mHandler=new Handler();\r
-            mBtAdapter.startLeScan(lecallback);\r
-            mHandler.postDelayed(mRunable_stopBleScan, BLETimeoutForOneScan*1000);\r
-\r
-        }else{\r
-            ICLogger.i("BT Scanning skip Scan!");\r
-        }\r
-\r
-    }\r
-\r
-\r
-\r
-    //开启蓝牙可被搜索300秒\r
-    private void ensureDiscoverable() {\r
-       ICLogger.i("ensure discoverable");\r
-        if (mBtAdapter.getScanMode() !=\r
-                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {\r
-\r
-//            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);\r
-//            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);\r
-//            mContext.startActivity(discoverableIntent);\r
-        }\r
-    }\r
-\r
-    private advcallback advcb=new advcallback();\r
-\r
-    //停止自定义广播\r
-    public void stopGattAdvertising(){\r
-        if (mBtAdapter.isEnabled())\r
-            mBtAdapter.stopAdvertising(advcb);\r
-\r
-    }\r
-\r
-    //开启自定义广播数据,前两字会被丢弃\r
-    public void enableGattAdvertising(String serverData){\r
-        byte[] serviceData = serverData.getBytes();\r
-        if (mBtAdapter.isEnabled())\r
-            mBtAdapter.startAdvertising(advcb, serviceData);\r
-    }\r
-    public class advcallback implements BluetoothAdapter.AdvertiseCallback {\r
-\r
-\r
-        public void onAdvertiseStart(int status){\r
-            ICLogger.i( "--onAdvertiseStart --");\r
-\r
-        }\r
-\r
-        public void onAdvertiseStop(int status){\r
-\r
-           ICLogger.i( "-- onAdvertiseStop --");\r
-\r
-        }\r
-    }\r
-    private class BLeScanCallback  implements  LeScanCallback{\r
-\r
-        @Override\r
-        public void onLeScan(BluetoothDevice bluetoothDevice, int rssi, byte[] scanRecode) {\r
-//                ICLogger.i( "BT onLeScan "+bluetoothDevice.getName()+" "+bluetoothDevice.getAddress()+" rssi "+rssi);\r
-//                ICLogger.logToFile("LBS","BT onLeScan "+bluetoothDevice.getName()+" "+bluetoothDevice.getAddress()+" rssi "+rssi );\r
-            boolean found = false;\r
-            for (String dev : mNewDevicesArray) {\r
-                if (dev.contains(bluetoothDevice.getAddress())) {\r
-                    found = true;\r
-                    break;\r
-                }\r
-            }\r
-\r
-            if (!found) {\r
-                mNewDevicesArray.add(bluetoothDevice.getAddress() + "," + rssi);\r
-            }\r
-\r
-            if(isBeaconFounded(bluetoothDevice.getAddress())){\r
-\r
-                mHandler.removeCallbacks(mRunable_stopBleScan);\r
-\r
-                ICLogger.i("BT onLeScan stopLeScan");\r
-                mBtAdapter.stopLeScan(this);\r
-                btscanning=false;\r
-\r
-                //开始扫描前是关闭的,就关闭它\r
-                //                if(!enabledBeforScan)\r
-                disableBT();\r
-                hasStopedByFoundBT=true;\r
-\r
-                if (mCallback != null) {\r
-                    resortScanResult(mNewDevicesArray);\r
-                    mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray);\r
-                }\r
-            }\r
-        }\r
-    }\r
-\r
-    private  void resortScanResult( ArrayList<String> btlist){\r
-\r
-        Collections.sort(btlist, new Comparator<String>() {\r
-            public int compare(String var1, String var2) {\r
-                try {\r
-                    int tmp = var1.indexOf(",");\r
-                    int rssi1 = Integer.parseInt(var1.substring(tmp + 1));\r
-                    tmp = var2.indexOf(",");\r
-                    int rssi2 = Integer.parseInt(var2.substring(tmp + 1));\r
-                    return Math.abs(rssi1) - Math.abs(rssi2);\r
-                }catch (Exception e){\r
-                    return 0;\r
-                }\r
-            }\r
-        });\r
-\r
-    }\r
-    private class RunableStopBleScan implements   Runnable{\r
-\r
-        @Override\r
-        public void run() {\r
-            ICLogger.i("BT stopLeScan");\r
-            mBtAdapter.stopLeScan(lecallback);\r
-            btscanning=false;\r
-            //开始扫描前是关闭的,就关闭它\r
-            //                if(!enabledBeforScan)\r
-            disableBT();\r
-            if (mCallback != null){\r
-                resortScanResult(mNewDevicesArray);\r
-                mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray);\r
-            }\r
-        }\r
-    }\r
-\r
-    public interface BTScanCallback{\r
-        void OnScanFinished(ArrayList<String> btPairedScanResult,ArrayList<String> btNewScanResult);\r
-    }\r
-}\r
+package com.enqualcomm.support.adapter;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothAdapter.LeScanCallback;
+import android.bluetooth.BluetoothDevice;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.ScanResult;
+import android.os.Handler;
+import com.enqualcomm.support.bean.Runtime;
+import com.enqualcomm.support.Config;
+import com.enqualcomm.support.utils.ICLogger;
+import com.enqualcomm.support.utils.Util;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Set;
+
+public class BTHelper {
+
+    private BluetoothAdapter mBtAdapter;
+    private static ArrayList<String> mPairedDevicesArray=new ArrayList<>();
+    private static ArrayList<String> mNewDevicesArray=new ArrayList<>();
+    private Context mContext=null;
+    private BTScanCallback mCallback=null;
+    private static BTHelper mBThelper=null;
+    private int  BLETimeoutForOneScan=10;
+    private static boolean btscanning=false;
+    private static Runtime mRuntime;
+    private boolean enabledBeforScan=false;
+    private static Handler mHandler=null;
+    BTHelper(){
+
+    }
+
+    public void setBLEScanTimeout(int timeout){
+        BLETimeoutForOneScan=timeout;
+    }
+    private boolean isBeaconFounded(String beaconAddr){
+
+        String tmp = beaconAddr.replace(":", "").toLowerCase();
+        if(tmp.contains(","))
+            tmp = tmp.substring(0, tmp.indexOf(","));
+        for (String beacon:mRuntime.bleInfo.btMacList){
+           if (tmp.equals(beacon)) {
+               ICLogger.i("bt mac " + tmp + "  " + beaconAddr.toLowerCase());
+               return true;
+           }
+        }
+        return false;
+    }
+    //enableBT
+    public void enableBT() {
+        ICLogger.i("BT enableBT()");
+
+
+        if (!mBtAdapter.isEnabled()) {
+
+            mBtAdapter.enable();
+            Util.mSleep(2000);
+            //此处无法执行说没权限
+//            mBtAdapter.enableNoAutoConnect();
+        }
+
+    }
+
+    //disableBT
+    public void disableBT(){
+        ICLogger.i( "BT disableBT()");
+         if (mBtAdapter.isEnabled()) {
+            mBtAdapter.disable();
+        }
+    }
+
+    //初始化 BTHlper
+    public void Init(Context context , BTScanCallback callback){
+        ICLogger.i( "BT Init()");
+        mCallback=callback;
+        mContext=context;
+        // Get the local Bluetooth adapter
+        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
+
+        if (lecallback==null)
+            lecallback= new BLeScanCallback();
+        if(mHandler==null)
+            mHandler=new Handler();
+
+    }
+
+
+    //获取实例
+    public static BTHelper CreateInstance(Runtime runtime , BTScanCallback callback){
+        mRuntime=runtime;
+        if (mBThelper==null) {
+            ICLogger.i( "BT getInstance ");
+            mBThelper = new BTHelper();
+            mBThelper.Init(runtime.getContextProxy().context,callback);
+        }
+        return mBThelper;
+    }
+
+    private  BLeScanCallback lecallback =null;
+
+    private RunableStopBleScan mRunable_stopBleScan=new RunableStopBleScan();
+
+    private static boolean hasStopedByFoundBT=false;
+    public boolean isBtscanning(){
+        return btscanning;
+    }
+    //开始扫描BLE
+    public void scanBLE() {
+        ICLogger.i( "BT scanBLE()");
+
+        if(btscanning==false) {
+            btscanning=true;
+            enabledBeforScan = mBtAdapter.isEnabled();
+            enableBT();
+
+            mPairedDevicesArray.clear();
+            mNewDevicesArray.clear();
+
+//            mBtAdapter.setScanMode(BluetoothAdapter.SCAN_MODE_NONE, BLETimeoutForOneScan);
+
+            ICLogger.i("BT startLeScan");
+            if (lecallback==null)
+                lecallback= new BLeScanCallback();
+            if(mHandler==null)
+                mHandler=new Handler();
+            mBtAdapter.startLeScan(lecallback);
+            mHandler.postDelayed(mRunable_stopBleScan, BLETimeoutForOneScan*1000);
+
+        }else{
+            ICLogger.i("BT Scanning skip Scan!");
+        }
+
+    }
+
+
+
+    //开启蓝牙可被搜索300秒
+    private void ensureDiscoverable() {
+       ICLogger.i("ensure discoverable");
+        if (mBtAdapter.getScanMode() !=
+                BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
+
+//            Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
+//            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
+//            mContext.startActivity(discoverableIntent);
+        }
+    }
+
+    private advcallback advcb=new advcallback();
+
+    //停止自定义广播
+    public void stopGattAdvertising(){
+        if (mBtAdapter.isEnabled())
+            mBtAdapter.stopAdvertising(advcb);
+
+    }
+
+    //开启自定义广播数据,前两字会被丢弃
+    public void enableGattAdvertising(String serverData){
+        byte[] serviceData = serverData.getBytes();
+        if (mBtAdapter.isEnabled())
+            mBtAdapter.startAdvertising(advcb, serviceData);
+    }
+    public class advcallback implements BluetoothAdapter.AdvertiseCallback {
+
+
+        public void onAdvertiseStart(int status){
+            ICLogger.i( "--onAdvertiseStart --");
+
+        }
+
+        public void onAdvertiseStop(int status){
+
+           ICLogger.i( "-- onAdvertiseStop --");
+
+        }
+    }
+    private class BLeScanCallback  implements  LeScanCallback{
+
+        @Override
+        public void onLeScan(BluetoothDevice bluetoothDevice, int rssi, byte[] scanRecode) {
+//                ICLogger.i( "BT onLeScan "+bluetoothDevice.getName()+" "+bluetoothDevice.getAddress()+" rssi "+rssi);
+//                ICLogger.logToFile("LBS","BT onLeScan "+bluetoothDevice.getName()+" "+bluetoothDevice.getAddress()+" rssi "+rssi );
+            boolean found = false;
+            for (String dev : mNewDevicesArray) {
+                if (dev.contains(bluetoothDevice.getAddress())) {
+                    found = true;
+                    break;
+                }
+            }
+             if (!found) {
+                mNewDevicesArray.add(bluetoothDevice.getAddress() + "," + rssi);
+            }
+
+
+            //scanRecode 可以解码 major minor
+            //ICLogger.i(bluetoothDevice.getAddress()+" "+bluetoothDevice.getName()+" "+rssi+" "+Util.byte2hex(scanRecode));
+
+            if(isBeaconFounded(bluetoothDevice.getAddress())){
+
+                mHandler.removeCallbacks(mRunable_stopBleScan);
+
+                ICLogger.i("BT onLeScan stopLeScan");
+                mBtAdapter.stopLeScan(this);
+                //开始扫描前是关闭的,就关闭它
+                //                if(!enabledBeforScan)
+                disableBT();
+                hasStopedByFoundBT=true;
+                if (mCallback != null) {
+                    resortScanResult(mNewDevicesArray);
+                    mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray);
+                }
+                btscanning=false;
+            }
+        }
+    }
+
+    private  void resortScanResult( ArrayList<String> btlist){
+
+        Collections.sort(btlist, new Comparator<String>() {
+            public int compare(String var1, String var2) {
+                try {
+                    int tmp = var1.indexOf(",");
+                    int rssi1 = Integer.parseInt(var1.substring(tmp + 1));
+                    tmp = var2.indexOf(",");
+                    int rssi2 = Integer.parseInt(var2.substring(tmp + 1));
+                    return Math.abs(rssi1) - Math.abs(rssi2);
+                }catch (Exception e){
+                    return 0;
+                }
+            }
+        });
+
+    }
+    private class RunableStopBleScan implements   Runnable{
+
+        @Override
+        public void run() {
+            ICLogger.i("BT stopLeScan");
+            mBtAdapter.stopLeScan(lecallback);
+             //开始扫描前是关闭的,就关闭它
+            //                if(!enabledBeforScan)
+            disableBT();
+            if (mCallback != null){
+                resortScanResult(mNewDevicesArray);
+                mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray);
+            }
+            btscanning=false;
+
+        }
+    }
+
+    public interface BTScanCallback{
+        void OnScanFinished(ArrayList<String> btPairedScanResult,ArrayList<String> btNewScanResult);
+    }
+}