From: snickersun Date: Tue, 24 Nov 2020 08:23:16 +0000 (+0800) Subject: 优化蓝牙扫描,解决上一次扫描结束未来得及处理扫描结果时,就开始新的扫描造成结果被清空的问题。 X-Git-Url: http://git.snicker.com.cn/Users/apple/Desktop/static/gitweb.css?a=commitdiff_plain;h=adf128d0de041410c62fb9a2273d08c2ddd6d4d0;p=protocol_srv.git 优化蓝牙扫描,解决上一次扫描结束未来得及处理扫描结果时,就开始新的扫描造成结果被清空的问题。 --- diff --git a/app/src/main/java/com/enqualcomm/support/adapter/BTHelper.java b/app/src/main/java/com/enqualcomm/support/adapter/BTHelper.java index ae2ecb2f..84875076 100644 --- a/app/src/main/java/com/enqualcomm/support/adapter/BTHelper.java +++ b/app/src/main/java/com/enqualcomm/support/adapter/BTHelper.java @@ -1,260 +1,262 @@ -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 mPairedDevicesArray=new ArrayList<>(); - private static ArrayList 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); - } - - if(isBeaconFounded(bluetoothDevice.getAddress())){ - - mHandler.removeCallbacks(mRunable_stopBleScan); - - ICLogger.i("BT onLeScan stopLeScan"); - mBtAdapter.stopLeScan(this); - btscanning=false; - - //开始扫描前是关闭的,就关闭它 - // if(!enabledBeforScan) - disableBT(); - hasStopedByFoundBT=true; - - if (mCallback != null) { - resortScanResult(mNewDevicesArray); - mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray); - } - } - } - } - - private void resortScanResult( ArrayList btlist){ - - Collections.sort(btlist, new Comparator() { - 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); - btscanning=false; - //开始扫描前是关闭的,就关闭它 - // if(!enabledBeforScan) - disableBT(); - if (mCallback != null){ - resortScanResult(mNewDevicesArray); - mCallback.OnScanFinished(mPairedDevicesArray, mNewDevicesArray); - } - } - } - - public interface BTScanCallback{ - void OnScanFinished(ArrayList btPairedScanResult,ArrayList btNewScanResult); - } -} +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 mPairedDevicesArray=new ArrayList<>(); + private static ArrayList 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 btlist){ + + Collections.sort(btlist, new Comparator() { + 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 btPairedScanResult,ArrayList btNewScanResult); + } +}