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

BLE startScan() 只扫描一些设备而不是全部

如何解决BLE startScan() 只扫描一些设备而不是全部

我正在开发一个应用,可以在谷歌地图中看到多部安卓手机。

用例:

我已经删除了这部分的代码,因为它对于我的问题来说是不必要的

到目前为止一切都很好

我想要的:

  • 通过 BLE 将 Android 设备相互连接,以便可以读取 RSSI 值

方法 onResume() 中开始扫描 BLE 设备。此处的扫描过滤器为 NULL,因此扫描所有设备。在 onScanResult() 方法显示找到的设备。

这是我的问题: 它向我显示电视和任何其他 BLE 设备以及它们的 RSSI 值等,但不显示 Android 手机。

我在手机上启用了定位和蓝牙功能

为了测试,我在手机上安装了“nrf connect”,但其他手机也没有被扫描

我认为我的设备支持蓝牙 BLE。它们是 Pixel 4a(5G)

更新

添加了信标发射器。现在,当我在两个设备上运行代码时,nrfConnect 检测我的设备但是

  • nrF 连接器仅扫描我最初运行应用程序的第一个设备
  • 当我调试第二部手机以检测第一部手机时,找不到第一部手机(但可以在 nrfconnector 上找到)

在android xml中我有以下权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.BLUetoOTH"/>
<uses-permission android:name="android.permission.BLUetoOTH_ADMIN"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.LOCAL_MAC_ADDRESS"
            tools:ignore="ProtectedPermissions" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

这是我的 Fragment 类 AnsichtFragment.java

public class AnsichtFragment extends Fragment {
    private static final String TAG = "AnsichtFragment";

    private static final int REQUEST_ENABLE_BT = 1;
    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;
    private final long MIN_TIME = 1000; //miliseconds
    private final long MIN_disT = 5; // meters
    Map<String,Marker> mNamedMarkers = new HashMap<String,Marker>();

    private BluetoothLeScanner bluetoothLeScanner;
    private boolean scanning;
    private BluetoothDevice mDevice;
    private List<ScanFilter> filters;
    private ScanSettings settings;
    private String deviceUUID;
    private String leName;
    private Handler handler;
    //private LeDevicelistadapter leDevicelistadapter;
    private BluetoothAdapter bluetoothAdapter;
    private List<String> uuids;
    private BluetoothGatt mGatt;

    private MapView mMapView;
    private GoogleMap googleMap;
    private FusedLocationProviderClient fusedLocationClient;
    private LocationListener locationListener;
    private LocationManager locationManager;
    private LocationRequest locationRequest;
    private String uniqueID;
    private DatabaseReference databaseReference;
    private DatabaseReference refToParent;

    @Override
    public View onCreateView(LayoutInflater inflater,ViewGroup container,Bundle savedInstanceState) {

        // Use this check to determine whether BLE is supported on the device. Then
// you can selectively disable BLE-related features.
        if (!getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUetoOTH_LE)) {
            Toast.makeText(this.getContext(),R.string.ble_not_supported,Toast.LENGTH_SHORT).show();
            //finish();
        }

        // Initializes Bluetooth adapter.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) getActivity().getSystemService(Context.BLUetoOTH_SERVICE);
        bluetoothAdapter = bluetoothManager.getAdapter();

        // Ensures Bluetooth is available on the device and it is enabled. If not,// displays a dialog requesting user permission to enable Bluetooth.
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
        }

        uuids = new ArrayList<>();

        handler = new Handler(Looper.getMainLooper());//Handler();
        leName = bluetoothAdapter.getName();

        ......

        //initialize view
        View rootView = inflater.inflate(R.layout.fragment_tab_ansicht,container,false);

       ......
        mMapView.getMapAsync(new OnMapReadyCallback() {
            @Override
            public void onMapReady(GoogleMap mMap) {


....

                if (getActivity().checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && getActivity().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                    // Todo: Consider calling
                    //    Activity#requestPermissions
                    // here to request the missing permissions,and then overriding
                    //   public void onRequestPermissionsResult(int requestCode,String[] permissions,//                                          int[] grantResults)
                    // to handle the case where the user grants the permission. See the documentation
                    // for Activity#requestPermissions for more details.
                    return;
                }
                try {
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME,MIN_disT,locationListener);
                    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,locationListener);
                } catch (Exception e) {
                    e.printstacktrace();
                }
            }
        });


        return rootView;

    }


    // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device,int RSSi,byte[] scanRecord) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            //return remote bluetooth device

                           connectToDevice(device);
                        }
                    });
                }
            };

    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType,ScanResult result) {
            Log.i("callbackType",String.valueOf(callbackType));
            Log.i("name",String.valueOf(result));

            String callBackDeviceName = result.getDevice().getName();
            String deviceAddress = result.getDevice().getAddress();
            //String RSSi = result.getRSSi;

            if (callBackDeviceName != null){
                if (callBackDeviceName.startsWith("Pi")){
                    Log.i("result","Device name: "+callBackDeviceName);
                    Log.i("result",result.toString());
                    BluetoothDevice btDevice = result.getDevice();
                    connectToDevice(btDevice);
                }
            }

        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            for (ScanResult sr : results) {
                Log.i("ScanResult – Results",sr.toString());
            }
        }

        @Override
        public void onScanFailed(int errorCode) {
            Log.e("Scan Failed","Error Code: " + errorCode);
        }
    };

    public void connectToDevice(BluetoothDevice device) {
        if (mGatt == null) {
            Log.d("connectToDevice","connecting to device: "+device.toString());
            this.mDevice = device;
            mGatt = device.connectGatt(this.getContext(),false,gattCallback);
            scanLeDevice(false);// will stop after first device detection
        }
    }

    private final BluetoothGattCallback gattCallback = new BluetoothGattCallback() {

        @Override
        public void onConnectionStateChange(BluetoothGatt gatt,int status,int newState) {
            Log.i("onConnectionStateChange","Status: " + status);
            switch (newState) {
                case BluetoothProfile.STATE_CONNECTED:
                    Log.i("gattCallback","STATE_CONNECTED");

                    //update UI
                    Message msg = Message.obtain();

                    String deviceName = gatt.getDevice().getName();
                    
                    msg.obj = deviceName;
                    msg.what = 0;
                    msg.setTarget(handler);
                    msg.sendToTarget();

                    gatt.discoverServices();
                    break;
                case BluetoothProfile.STATE_disCONNECTED:
                    Log.e("gattCallback","STATE_disCONNECTED");
                    Log.i("gattCallback","reconnecting…");
                    BluetoothDevice mDevice = gatt.getDevice();
                    mGatt = null;
                    connectToDevice(mDevice);
                    break;
                default:
                    Log.e("gattCallback","STATE_OTHER");
            }

        }

        @Override
        public void onServicesdiscovered(BluetoothGatt gatt,int status) {
            mGatt = gatt;
            List<BluetoothGattService> services = gatt.getServices();
            Log.i("onServicesdiscovered",services.toString());
            BluetoothGattCharacteristic therm_char = services.get(2).getcharacteristics().get(0);

            for (BluetoothGattDescriptor descriptor : therm_char.getDescriptors()) {
                descriptor.setValue( BluetoothGattDescriptor.ENABLE_INDICATION_VALUE);
                mGatt.writeDescriptor(descriptor);
            }

            //gatt.readCharacteristic(therm_char);
            gatt.setCharacteristicNotification(therm_char,true);

        }

        @Override
        public void onCharacteristicRead(BluetoothGatt gatt,BluetoothGattCharacteristic
                                                 characteristic,int status) {
            Log.i("onCharacteristicRead",characteristic.toString());
            byte[] value=characteristic.getValue();
            String v = new String(value);
            Log.i("onCharacteristicRead","Value: " + v);
            //gatt.disconnect();
        }

        @Override
        public void onCharacteristicChanged(BluetoothGatt gatt,BluetoothGattCharacteristic
                                                    characteristic) {
            float char_float_value = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT,1);
            Log.i("onCharacteristicChanged",Float.toString(char_float_value));


            String deviceName = gatt.getDevice().getName();
            String value = null;
            
        }

    };

    @SuppressLint("MissingPermission")
    private void getCurrentLocationWithLatLong() {
.....
    }

    @Override
    public void onResume() {
        mMapView.onResume();

        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled()) {
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableBtIntent,REQUEST_ENABLE_BT);
        } else {
            if (Build.VERSION.SDK_INT >= 21) {
                bluetoothLeScanner = bluetoothAdapter.getBluetoothLeScanner();
                settings = new ScanSettings.Builder()
                        .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                        .build();
                filters = new ArrayList<ScanFilter>();
            }
            scanLeDevice(true);
        }

 
        super.onResume();
    }


    @Override
    public void onPause() {
        super.onPause();
        if (bluetoothAdapter != null && bluetoothAdapter.isEnabled()) {
            scanLeDevice(false);
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        mMapView.onDestroy();

        if (mGatt == null) {
            return;
        }
        mGatt.close();
        mGatt = null;
        super.onDestroy();


    }

    @Override
    public void onLowMemory() {
        super.onLowMemory();
        mMapView.onLowMemory();
    }

    
    private MarkerOptions getMarkerOptions(String key) {
       .....
    }

    private void scanLeDevice(final boolean enable) {
        if (enable) {
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (Build.VERSION.SDK_INT < 21) {
                        bluetoothAdapter.stopLeScan(mLeScanCallback);
                    } else {
                        bluetoothLeScanner.stopScan(mScanCallback);

                    }
                }
            },SCAN_PERIOD);
            if (Build.VERSION.SDK_INT < 21) {
                bluetoothAdapter.startLeScan(mLeScanCallback);
            } else {
                //bluetoothLeScanner.startScan(filters,settings,mScanCallback);
               bluetoothLeScanner.startScan(mScanCallback);
            }
        } else {
            if (Build.VERSION.SDK_INT < 21) {
                bluetoothAdapter.stopLeScan(mLeScanCallback);
            } else {
                bluetoothLeScanner.stopScan(mScanCallback);
            }
        }
    }

    private void readUUIDsFromFirebase() {
....
    }
   

....
}

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