Местоположение должно быть включено для Bluetooth Low Energy Scanning на Android 6.0
После обновления до Android версии 6.0 Bluetooth Low Energy (BLE) сканирование будет работать, только если на устройстве включены службы определения местоположения. Смотрите здесь для справки: Bluetooth Low Energy startScan на Android 6.0 не находит устройства
По сути, вам нужно включить разрешение для приложения, а также для телефона. Это ошибка? Можно ли сканировать без фактически включенных служб определения местоположения? Я не хочу иметь местоположение для всех моих приложений.
РЕДАКТИРОВАТЬ Я не упомянул, что я использую startScan()
метод в BluetoothLeScanner
предоставляется в API 21. У меня все в порядке с разрешениями для курса и точного местоположения в манифесте, которые требуются для этого метода. Я просто не хочу, чтобы пользователи моего приложения включали службы определения местоположения на своем устройстве (GPS и т. Д.) Для использования моего приложения.
Ранее startScan()
метод будет запускаться и возвращать результаты с отключенными службами определения местоположения на телефоне. Однако в случае "Зефира" то же приложение "сканировало", но молчаливо отказывало и не давало результатов, если на телефоне не были включены службы определения местоположения, а разрешения на курс / точное местоположение все еще были в манифесте.
10 ответов
Нет, это не ошибка.
Эта проблема была поднята в Google, где они ответили, что это было предполагаемое поведение, и они не будут это исправлять. Они направили разработчиков на этот сайт, где указывалось, что теперь для доступа к идентификатору оборудования необходимо разрешение на местоположение. Теперь ответственность за информирование пользователей о требованиях лежит на разработчике.
В этом выпуске, однако, не рассматривается, почему требуются службы определения местоположения (GPS и т. Д.), И не похоже, что они собираются вернуться к этой проблеме, чтобы объяснить это, поскольку она была помечена как предполагаемое поведение.
Чтобы ответить на вторую часть вопроса: да, можно сканировать без включения служб определения местоположения. Вы можете выполнить классическое сканирование Bluetooth, используя BluetoothAdapter.getDefaultAdapter().startDiscovery()
и это будет работать с отключенными службами определения местоположения. Это обнаружит все устройства Bluetooth, BLE и другие. Однако на устройствах BLE не будет записи сканирования, которая была бы у них, если бы они рассматривались в результате startScan()
,
Я решил это, установив targetSdkVersion
до 22 в файле Gradle. Вы должны объявить ACCESS_COARSE_LOCATION
в манифесте, но сканирование BLE будет работать, даже если пользователь отказывает в этом разрешении в настройках приложения.
Это просто взлом, чтобы не запрашивать разрешение на местоположение. Лучше ориентироваться на последние версии Android.
Я обнаружил, что после Android 6 вы должны предоставить разрешение ACCESS_COARSE_LOCATION. Но на некоторых устройствах также необходимо включить службу определения местоположения телефона (GPS), чтобы вы могли обнаружить периферийные устройства. Я обнаружил, что с помощью Nexus 5x, с Android 7.0.
Ты можешь использовать BluetoothAdapter.startDiscovery()
,
Он будет сканировать как Bluetooth Smart, так и классические устройства Bluetooth, но услуги определения местоположения не должны быть включены.
(Вам все еще нужно ACCESS_COARSE_LOCATION
разрешения на Android 6.)
Ты можешь позвонить BluetoothDevice.getType
на найденных устройствах для фильтрации для устройств Bluetooth Smart / Low Energy.
Я также попробовал это на манифесте, но не запрашивал разрешения, не уверен почему. Ваше приложение запрашивает разрешение "Местоположение" при запуске? Если это не так, нам нужно запросить разрешение во время выполнения.
Также вы можете проверить это, чтобы проверить, нормально ли работает ваше приложение:
Откройте "Настройки"> "Приложения"> "Ваше приложение"> "Разрешения" и включите "Местоположение", а затем попробуйте выполнить поиск результатов.
Местоположение будет указано здесь, только если вы указали ACCESS_COARSE_LOCATION в манифесте.
после того, как вы добавите
ACCESS_COARSE_LOCATION
чтобы манифестировать, запрашивать разрешение во время выполнения:
public void checkPermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED && checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
} else {
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,}, 1);
}
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
} else {
checkPermission();
}
}
работал на меня!
Начиная с API 31, вы можете использовать новое разрешение вместо разрешения местоположения.
Если приложение не получает физические местоположения, вы можете добавитьandroid:usesPermissionFlags="neverForLocation"
отнести кBLUETOOTH_SCAN
декларация о разрешении:
<manifest ...>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation" />
...
</manifest>
А потом:
val requiredPermissions = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
arrayOf(Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN)
}
requestPermissions(requiredPermissions, 9999)
Подробнее: https://xizzhu.me/post/2021-10-05-android-12-bluetooth-permissions/
Вы можете сканировать устройства BLE без доступа к местоположению с помощью CompanionDeviceManager (API26).https://developer.android.com/reference/android/companion/CompanionDeviceManager.
Что ж, я посмотрел на мой код, написанный на Eclipse, и использую там функцию startScan (API 21), не объявляя данные о местоположении в файле манифеста. Я все еще получаю правильный обратный звонок. Вы пытались запустить код без объявления местоположения? С другой стороны - вы можете использовать устаревший startLeScan (API 18), который не требует этих разрешений. Однако, на мой взгляд, поиск и чтение требуемой характеристики в сервисе более сложны с помощью методов API 18.
Из того, что я недавно заметил на Android 8.0, не требуется включать GPS для сканирования BLE, но вы должны объявить его в манифесте, но пользователь должен разрешить разрешение.
Android предложит пользователю разрешить разрешение местоположения при попытке сканирования с startScan()
метод. Ваше сканирование не удастся, если разрешение не разрешено.