扫描蓝牙LE设备存在问题(无回调)

3

我正在尝试开发一个可以连接到BLE设备的Android应用程序,但是我遇到了找不到BLE设备的问题。scanLeDevice方法运行,但是没有回调。您可以在下面找到我的代码:我使用Log.i()显示BLE设备。

使用另一个从商店下载的应用程序,我可以找到我的BLE设备和其他附近的蓝牙设备。因此,这不是我的手机的问题。

谢谢帮助!




public class MainActivity extends AppCompatActivity {
    private BluetoothAdapter bluetoothAdapter;
    private final int REQUEST_ENABLE_BT = 1;
    private boolean mScanning;

    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Log.i("MainActivity", "Begin");

        // Initializes Bluetooth adapter.
        final BluetoothManager bluetoothManager =
                (BluetoothManager) 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);
        }
        Log.i("MainActivity", "End for permissions");

        if(Build.VERSION.SDK_INT < 21){
            scanLeDevice(true);
        }else{
            scanDevice(true);
        }

    }

    private Handler handler = new Handler();
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    bluetoothAdapter.stopLeScan(leScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = true;
            bluetoothAdapter.startLeScan(leScanCallback);
            Log.i("MainActivity", "scanning");
        } else {
            mScanning = false;
            bluetoothAdapter.stopLeScan(leScanCallback);
        }

    }

    // Device scan callback.
    private BluetoothAdapter.LeScanCallback leScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            //Ici///////////////////////////////////////
                            Log.i("MainActivity", "Nam: "+device.getName()+" Adresse: "+device.getAddress());
                            if(device.getName() != null && device.getName().equals("RN4871-85D7"))
                                scanLeDevice(false);
                        }
                    });
                }
            };

    ///////////////////Scan for API 21
    private ScanSettings settings;
    private List<ScanFilter> filters;
    private BluetoothLeScanner mLEScanner;
    private void scanDevice(final boolean enable){
        if (mLEScanner==null){
            mLEScanner = bluetoothAdapter.getBluetoothLeScanner();
            settings = new ScanSettings.Builder()
                    .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
                    .build();
            filters = new ArrayList<ScanFilter>();
        }

        if (enable) {
            if (mScanning) return;
            // Stops scanning after a pre-defined scan period.
            handler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    if (!mScanning) return;
                    try {
                        mScanning = false;
                        //Log.d("MainActivity","STOP SCAN AFTER DELAY");
                        mLEScanner.stopScan(mScanCallback);
                        Log.i("MainActivity", "stop scanning API 21");
                    } catch (Exception e){Log.e("MainActivity",e.getMessage());}
                }
            }, SCAN_PERIOD);

            mScanning = true;
            //Log.d("MainActivity","START SCAN FROM EXPLICIT CALL");
            mLEScanner.startScan(filters, settings, mScanCallback);
            Log.i("MainActivity", "scanning API 21");
        } else  if (mLEScanner!=null){
            if (!mScanning) return;
            mScanning = false;
            try {
                //Log.d("MainActivity","STOP SCAN FROM EXPLICIT CALL");
                mLEScanner.stopScan(mScanCallback);
                Log.i("MainActivity", "stop scanning API 21");
            } catch (Exception e){Log.i("MainActivity",e.getMessage());}
        }
    }

    //call back for API 21
    //@TargetApi(21)
    private ScanCallback mScanCallback = new ScanCallback() {
        @Override
        public void onScanResult(int callbackType, ScanResult result) {
            super.onScanResult(callbackType, result);
            Log.i("MainActivity", "onScanResult API 21");
        }

        @Override
        public void onBatchScanResults(List<ScanResult> results) {
            super.onBatchScanResults(results);
            Log.i("MainActivity", "onBatchScanResults API 21");
        }

        @Override
        public void onScanFailed(int errorCode) {
            super.onScanFailed(errorCode);
            Log.i("MainActivity", "onScanFailed API 21");
        }
    };

}


感谢您的帮助。

你能分享一下当你运行扫描并且附近有BLE设备时获取的日志吗? - Ananth
是的,设备在附近。问题是授权应用程序访问位置。感谢您的反应。 - barkigandal
2个回答

3

我找到了有关位置问题的原因。

实际上,如果您使用的API版本>=23,则必须授权您的应用程序访问位置(不仅在清单文件中,还要在代码中)。

所以,如果您遇到了同样的问题:

  1. 首先,手动前往您手机的设置并授权您的应用程序访问位置:确保这是问题的原因。
  2. 然后添加以下代码,以便应用程序请求用户授权访问位置。

    /////////////////////////Location/////
    @TargetApi(Build.VERSION_CODES.M)
    private void loadPermissions(String perm,int requestCode) {
        if (ContextCompat.checkSelfPermission(this, perm) != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(this, perm)) {
                ActivityCompat.requestPermissions(this, new String[]{perm},requestCode);
            }
        } else if (checkLocationEnabled())
            initScanner();
    }
    private boolean checkLocationEnabled(){
        LocationManager lm = (LocationManager)this.getSystemService(Context.LOCATION_SERVICE);
        boolean gps_enabled = false;
        boolean network_enabled = false;

        try {
            gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        } catch(Exception ex) {}

        try {
            network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        } catch(Exception ex) {}

        if(!gps_enabled && !network_enabled) {
            // notify user
            AlertDialog.Builder dialog = new AlertDialog.Builder(this);
            dialog.setMessage("GPS desabled");
            dialog.setPositiveButton("Open GPS settings", new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    // TODO Auto-generated method stub
                    Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    startActivity(myIntent);
                    //get gps
                }
            });
            dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                @Override
                public void onClick(DialogInterface paramDialogInterface, int paramInt) {
                    // TODO Auto-generated method stub

                }
            });
            dialog.show();
            return false;
        } else return true;
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case REQUEST_FINE_LOCATION: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // granted
                    if (checkLocationEnabled())
                        initScanner();
                }
                else{
                    // no granted
                }
                return;
            }

        }

    }


2

我之前也遇到过这个问题,因为我在权限中使用了 ACCESS_COARSE_LOCATION

当我更改为 ACCESS_FINE_LOCATION 时,它终于能正常运行了!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接