Android 6 bluetooth

Я обновился до Android 6, и мои приложения, которые используют Bluetooth, не работают с этой новой версией API. Это та же проблема с приложением в Play Store: Bluetooth spp tools pro (хорошее приложение для просмотра, если работает bluetooth), что не открывает устройства.

Проблема заключается в обнаружении Bluetooth:

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); mBluetoothAdapter.startDiscovery() Log.i("BLUETOOTH", String.valueOf(mBluetoothAdapter.isDiscovering())); // Return false 

Мои приложения хорошо работают с Android 4/5, и я следил за ними: http://developer.android.com/guide/topics/connectivity/bluetooth.html

Находясь в Android 6.0, недостаточно включить разрешения на манифест. Вы должны спросить пользователя о каждом разрешении, которое считается «опасным». Для BluetoothDevice.ACTION_FOUND требуются разрешения BLUETOOTH и ACCESS_COARSE_LOCATION http://developer.android.com/reference/android/bluetooth/BluetoothDevice.html#ACTION_FOUND

ACCESS_COARSE_LOCATION http://developer.android.com/reference/android/Manifest.permission.html#ACCESS_COARSE_LOCATION – это «опасное» разрешение, и поэтому вы должны попросить его с помощью requestPermission, прежде чем делать фактическое открытие.

  public void doDiscovery() { int hasPermission = ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION); if (hasPermission == PackageManager.PERMISSION_GRANTED) { continueDoDiscovery(); return; } ActivityCompat.requestPermissions(MainActivity.this, new String[]{ android.Manifest.permission.ACCESS_COARSE_LOCATION}, REQUEST_COARSE_LOCATION_PERMISSIONS); } 

То вы получите ответ пользователя onRequestPermissionsResult

 @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case REQUEST_COARSE_LOCATION_PERMISSIONS: { if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { continueDoDiscovery(); } else { Toast.makeText(this, getResources().getString(R.string.permission_failure), Toast.LENGTH_LONG).show(); cancelOperation(); } return; } } } 

Чтобы работать с предыдущими версиями android, вы должны использовать библиотеки совместимости и совершать вызовы с помощью ActivityCompat

Я потратил некоторое время на изучение проблемы.
Создан отчет об ошибке на Android-трекер от Android
Проблема в том, что система не передает BluetoothDevice.ACTION_FOUND для зарегистрированного BroadcastReceiver . Logcat показывает строки следующим образом:

 10-16 07:34:09.147 786-802/? W/BroadcastQueue﹕ Permission Denial: receiving Intent { act=android.bluetooth.device.action.FOUND flg=0x10 (has extras) } to ProcessRecord{5ce2d92 21736:com.example.mvl.bluetoothtest/u0a74} (pid=21736, uid=10074) requires android.permission.ACCESS_COARSE_LOCATION due to sender com.android.bluetooth (uid 1002) 

Какие темы для меня требуют приложения для android.permission.ACCESS_COARSE_LOCATION для получения этого намерения. Я лично не понимаю, зачем мне это разрешение, чтобы получить устройства Bluetooth.
Поэтому, если вы добавите это разрешение в Manifest, тогда оно должно работать с еще одним предварительным условием. Вы должны установить целевой SDK и скомпилировать с SDK не выше, а затем 22.

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

При проверке исходного кода в GattService.java вы найдете некоторые комментарии кода в методе onScanResult:

 // Do no report if location mode is OFF or the client has no location permission // PEERS_MAC_ADDRESS permission holders always get results if (hasScanResultPermission(client) && matchesFilters(client, result)) { try { ScanSettings settings = client.settings; if ((settings.getCallbackType() & ScanSettings.CALLBACK_TYPE_ALL_MATCHES) != 0) { app.callback.onScanResult(result); } } catch (RemoteException e) { Log.e(TAG, "Exception: " + e); mClientMap.remove(client.clientIf); mScanManager.stopScan(client); } } 

Это пояснило, что необходимо для получения рекламного отчета Bluetooth LE.