BluetoothLeScanner.startScan с Android 6.0 не обнаруживает устройства

Я пытаюсь использовать функцию BluatoothLeScanner.startScan вместо устаревшего BluetoothAdapter.startLeScan. Вчера я обновил свой Nexus 5 до Android 6.0, и с этого момента мое приложение больше не работает. Сначала я добавляю необходимые настройки ACCESS_COARSE_LOCATION как найдено здесь, https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id. Затем я добавил разрешение, как описано здесь: https://developer.android.com/training/permissions/requesting.html. Но в конце концов, похоже, не работает, он не отправляет обратно устройства ble.

Это мой код:

манифест

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.stm.sensitronapp">
          <uses-sdk android:maxSdkVersion="23"/>
          <uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>

          <uses-permission android:name="android.permission.BLUETOOTH"/>
          <uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
          <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>`

DeviceScanActivity

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
...

if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED){
        if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                Manifest.permission.ACCESS_COARSE_LOCATION)) {
        } else {
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                    MY_PERMISSIONS_REQUEST_ACCESS_COARSE);
        }
    }

// Device scan callback.
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        if (ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)
                == PackageManager.PERMISSION_GRANTED) {
            mScanCallback = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);
                    mLeDeviceListAdapter.addDevice(result.getDevice());
                    mLeDeviceListAdapter.notifyDataSetChanged();
                }
            };
        }
    } 
}
final BluetoothManager bluetoothManager =
            (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();

if (mBluetoothAdapter.getState() == BluetoothAdapter.STATE_ON) {
        mSwipeRefreshLayout.setRefreshing(true);
        mLeDeviceListAdapter.clear();
        mBluetoothLeScanner = mBluetoothAdapter.getBluetoothLeScanner();
        if(ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION ) == PackageManager.PERMISSION_GRANTED) {
                mBluetoothLeScanner.startScan(mScanCallback);
            }
        }

EDIT:для решения этой проблемы я включил только GPS. Это легко сделать программно в таким образом.

6 ответов


Если разрешения предоставлены, попробуйте: включите GPS.


вы приложение запрашивает разрешение на местоположение при запуске? Если это не так, обработайте код в другом месте, чтобы он запрашивался.

также вы можете проверить это, чтобы проверить, если ваше приложение работает нормально:

Открыть Настройки > Приложения > YourApplication > Разрешения и включите Location, а затем попробуйте сканировать результаты.

местоположение будет указано в разделе Разрешения, только если вы предоставили ACCESS_COARSE_LOCATION в манифесте.


использование решений, приведенных выше, работает, но побочным эффектом является то, что вы должны включить службы определения местоположения для чего-то, что в этом не нуждается. Уродливая и неудовлетворительная работа заключается в том, чтобы указать целевую версию в манифесте

android: targetSdkVersion= "21"

Это позволяет сканировать на моем Nexus 7, даже если установленная версия 6.0.1. Я не знаю, какие побочные эффекты имеют таргетинг на более низкую версию, чем установленная версия, но в наименьшее сканирование работает. Возможно, это единственное решение для устройств без GPS (если такие устройства существуют).

Google должен быть распят за это.


один-не идеальный ответ, заключается в том, что вы все еще можете использовать тот же старый метод сканирования BT, как только у вас будет включено новое разрешение на местоположение во время выполнения.

            mBluetoothAdapter.startDiscovery();

.......

private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();

                if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                mDeviceList.add(device);


            }
        }
    };

Это старый вопрос, но я отвечу, чтобы помочь кому-то.
К сожалению, комбинация ACCESS_COARSE_LOCATION и targetSdkVersion 22 не работает на некоторых устройствах.
это не хороший метод, но я решил его следующим образом без использования разрешений среды выполнения (ACCESS_COARSE_LOCATION или ACCESS_FINE_LOCATION)

  1. установите "targetSdkVersion" на 19 (я думаю, возможно, api19 ~ api22 будет возможно)
  2. добавить следующие разрешение на файл манифеста

    <uses-permission android:name="android.permission.READ_OWNER_DATA" />
    <uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
    

проверено на Android 4.4 ~ 7.1.1


установите значение "minSdkVersion" на 18 targetSdkVersion 22