it-roy-ru.com

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 # поведение-аппаратный-идентификатор . Затем я добавил разрешение, как описано здесь: https://developer.Android.com/training/permissions/requesting.html . Но в конце Кажется, он не работает, он не отправляет обратно устройства.

Это мой код:

manifest

<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);
            }
        }

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

17
Jacopo Tosi

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

17
qinmiao

Ваше приложение запрашивает разрешение «Местоположение» при запуске? Если это не так, обработайте код где-нибудь еще, чтобы он запрашивался.

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

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

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

6
Kamal Kishore

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

Android: targetSdkVersion = "21"

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

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

3
Brian Reinhold

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

            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);


            }
        }
    };
0
aiden_fry

Это старый вопрос, но я отвечу, чтобы помочь кому-то.
К сожалению, комбинация 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

0
Andromer