微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在android中进行BLE扫描后收到错误的结果

如何解决在android中进行BLE扫描后收到错误的结果

我正在使用以下代码扫描附近所有的 BLE 设备

这是代码

    package com.btexample;

    import android.Manifest;
    import android.app.Activity;
    import android.bluetooth.BluetoothAdapter;
    import android.bluetooth.BluetoothManager;
    import android.bluetooth.le.BluetoothLeScanner;
    import android.bluetooth.le.ScanCallback;
    import android.bluetooth.le.ScanFilter;
    import android.bluetooth.le.ScanResult;
    import android.bluetooth.le.ScanSettings;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.os.Handler;
    import androidx.annotation.NonNull;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    import com.facebook.react.bridge.ActivityEventListener;
    import com.facebook.react.bridge.ReactApplicationContext;
    import com.facebook.react.bridge.ReactContextBaseJavaModule;
    import com.facebook.react.bridge.ReactMethod;
    import com.facebook.react.bridge.Callback;
    import com.facebook.react.bridge.WritableMap;
    import com.facebook.react.bridge.WritableNativeMap;
    import java.util.ArrayList;
    import java.util.List;
    
    
    public class MyBluetooth extends ReactContextBaseJavaModule implements ActivityEventListener {


    private ReactApplicationContext context;
    private static final int PERMISSION_REQUEST_CODE = 200;
    private static final int REQUEST_ENABLE_BT = 10112;
    private String[] permissions = new String[]{Manifest.permission.BLUetoOTH,Manifest.permission.BLUetoOTH_ADMIN};
    private BluetoothManager bluetoothManager;
    private BluetoothAdapter bluetoothAdapter;
    private BluetoothLeScanner bluetoothLeScanner;
    private Callback scanSuccessCallBack,scanFailedCallBack;

    public MyBluetooth(ReactApplicationContext reactContext) {
        super(reactContext);
        context = reactContext;
        bluetoothManager =
                (BluetoothManager) context.getSystemService(Context.BLUetoOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();
        bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
    }

    @NonNull
    @Override
    public String getName() {
        return "MyBluetooth";
    }




    @ReactMethod
    public void turnOnBluetooth() {
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            getCurrentActivity().startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
        }
    }

    private WritableMap convertJsonToMap(String name) {
        WritableMap map = new WritableNativeMap();
        map.putString("device_name",name);
        return map;
    }

    @ReactMethod
    private void requestGPSPermissions() {
        boolean permissionCheck =
                ContextCompat.checkSelfPermission(context,Manifest.permission.ACCESS_FINE_LOCATION)
                        != PackageManager.PERMISSION_GRANTED
                        &&
                        ContextCompat.checkSelfPermission(context,Manifest.permission.ACCESS_COARSE_LOCATION)
                                != PackageManager.PERMISSION_GRANTED;


        if (permissionCheck) {

            ActivityCompat.requestPermissions(getCurrentActivity(),new String[]{
                            Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION
                    },PERMISSION_REQUEST_CODE);

        }
    }


    private boolean mScanning = false,isInvoked;
    private Handler handler;

    @ReactMethod
    public void scanLeDevice(int scanSeconds,Callback scanSuccessCallBack,Callback scanFailedCallBack) {
        if (!mScanning) {
            // Stops scanning after a pre-defined scan period.
            this.scanSuccessCallBack  = scanSuccessCallBack;
            this.scanFailedCallBack  = scanFailedCallBack;
            isInvoked = false;
            handler = new Handler();
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if(mScanning) {
                        bluetoothLeScanner.stopScan(leScanCallback);
                        mScanning = false;
                        if(!isInvoked){
                            scanFailedCallBack.invoke("No results found");
                        }
                    }
                }
            },scanSeconds*1000);

            mScanning = true;
            List<ScanFilter> filters = new ArrayList<ScanFilter>();

            ScanSettings settings = new ScanSettings.Builder()
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                    .setReportDelay(1000)
                    .build();



            bluetoothLeScanner.startScan(filters,settings,leScanCallback);
        } else {
            mScanning = false;
            bluetoothLeScanner.stopScan(leScanCallback);
            scanFailedCallBack.invoke("Already scanning");
        }
    }


    private ScanCallback leScanCallback = new ScanCallback() {


        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            if(results.size() > 0 && mScanning) {
                mScanning = false;
                if(!isInvoked){
                    scanSuccessCallBack.invoke("results found");
                    isInvoked = true;
                    bluetoothLeScanner.stopScan(leScanCallback);
                    handler.removeCallbacksAndMessages(null);
                }
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            scanFailedCallBack.invoke("Scan Failed");
        }
    };


    @Override
    public void onActivityResult(Activity activity,int requestCode,int resultCode,Intent data) {

    }

    @Override
    public void onNewIntent(Intent intent) {

    }
}

现在

  1. 目前我没有任何外围设备,所以我使用一个应用程序作为模拟器 链接https://play.google.com/store/apps/details?id=com.ble.peripheral.sim&hl=en_IN&gl=US

  2. 现在正在使用另一台设备上的另一应用 https://play.google.com/store/apps/details?id=com.macdom.ble.blescanner&hl=en_IN&gl=US 进行扫描,我收到了正确的结果

  3. 现在用我的应用程序再次扫描接收结果。

现在的主要问题是。

  1. 当我关闭模拟器应用程序并卸载它时,我仍然在我的应用程序中得到它作为结果,而不是在那个扫描仪应用程序中。

  2. 此外,我的应用正在接收 deviceName=null 的随机设备(很多东西也是 null),而这些随机设备没有出现在该扫描仪应用中。

  3. 当我从 starScan() 中删除过滤器和设置时;

    例如

    bluetoothLeScanner.startScan(filters,leScanCallback);

从未收到 onBatchScanResults() 的回调。

  1. 从设备中删除模拟器应用程序,在第三个设备上全新安装我的应用程序仍然得到 1 或 2 个随机结果,设备名称为空

注意:我正在 android studio 的调试器中检查结果

请帮我提前谢谢

解决方法

1-2。一旦您的扫描过滤器为空,您将获得所有扫描结果,因此在此应用程序中可能有不同的扫描过滤器。因此,您可以获得不同的扫描结果。

  1. 我认为您开始在回调方法 onScanResult 中接收扫描结果,这在您的代码中没有实现。

  2. 可能是您周围的一些 BLE 设备 - 例如笔记本电脑、鼠标、电视等。

,

我不确定什么对我有用,但这些是我已经改变的东西。

  1. 在两个清单中再添加一个权限并在运行时询问 ACCESS_BACKGROUND_LOCATION

  2. 停止使用 android.bluetooth.le,现在我正在使用这个库来这样做 https://github.com/NordicSemiconductor/Android-Scanner-Compat-Library 两者的代码是相同的,我们只需要从这个包中导入类。

  3. 在问题中我忘了提到我没有收到 onScanResult 的回调,即使这样做之后我也无法获得扫描结果

  4. 所以我只是从 startScan 中删除了扫描过滤器和扫描设置,然后使用 onScanResult 来获取设备。

    这是最终代码

SITES

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。