У меня есть приложение, использующее bluetooth и подключающееся к устройствам, can'f найти любые устройства, использующие BluetoothAdapter.getDefaultAdapter(). startDiscovery(); Он отлично работал перед открытием. Пробовал и другие приложения, он не работает и в других приложениях. Но устройство, с которым я пытаюсь соединиться (Arduino bt-module), можно найти в настройках Android. Любая идея, что я могу попробовать? Я реализовал все, как описано в http://developer.android.com/guide/topics/connectivity/bluetooth.html, и работал до обновления.
Поскольку зефир обновляет обнаружение Bluetooth с помощью BluetoothAdapter.getDefaultAdapter(). StartDiscovery(); сломан
Ответ 1
Адаптер Bluetooth был изменен в Android 6.0
Вам необходимо установить разрешение ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION и использовать Метод BluetoothLeScanner.startScan() для запуска сканирования.
Ниже приведено описание из журналов изменений:
Чтобы обеспечить пользователям большую защиту данных, в Android 6.0 Android удаляет программный доступ к локальному идентификатору аппаратного обеспечения устройств для приложений с использованием API Wi-Fi и Bluetooth. Теперь методы WifiInfo.getMacAddress() и BluetoothAdapter.getAddress() возвращают постоянное значение 02: 00: 00: 00: 00: 00.
Чтобы получить доступ к идентификаторам оборудования соседних внешних устройств через Bluetooth и сканирование Wi-Fi, ваше приложение должно теперь иметь разрешения ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION:
WifiManager.getScanResults()
BluetoothDevice.ACTION_FOUND
BluetoothLeScanner.startScan()
Примечание. Когда устройство под управлением Android 6.0 (API-уровень 23) инициирует фоновое сканирование Wi-Fi или Bluetooth, операция видна внешним устройствам, исходя из рандомизированного MAC-адреса.
Вы можете получить более подробную информацию по этой ссылке: http://developer.android.com/about/versions/marshmallow/android-6.0-changes.html
Ответ 2
Просто включите "Местоположение в настройках", и он хорошо работает.
Ответ 3
Из уровня API 23 для обнаружения Bluetooth также требуется разрешение доступа к местоположению (ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION).
И просто добавить разрешение в файл манифеста недостаточно, поскольку это разрешение относится к "опасному" уровню защиты. Пользовательское согласие необходимо для запроса разрешения во время выполнения.
Добавлено разрешение на AndroidManifest.xml:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
Запрос на ACCESS_FINE_LOCATION или ACCESS_COARSE_LOCATION во время выполнения:
private void accessLocationPermission() {
int accessCoarseLocation = checkSelfPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION);
int accessFineLocation = checkSelfPermission(android.Manifest.permission.ACCESS_FINE_LOCATION);
List<String> listRequestPermission = new ArrayList<String>();
if (accessCoarseLocation != PackageManager.PERMISSION_GRANTED) {
listRequestPermission.add(android.Manifest.permission.ACCESS_COARSE_LOCATION);
}
if (accessFineLocation != PackageManager.PERMISSION_GRANTED) {
listRequestPermission.add(android.Manifest.permission.ACCESS_FINE_LOCATION);
}
if (!listRequestPermission.isEmpty()) {
String[] strRequestPermission = listRequestPermission.toArray(new String[listRequestPermission.size()]);
requestPermissions(strRequestPermission, REQUEST_CODE_LOC);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case REQUEST_CODE_LOC:
if (grantResults.length > 0) {
for (int gr : grantResults) {
// Check if request is granted or not
if (gr != PackageManager.PERMISSION_GRANTED) {
return;
}
}
//TODO - Add your code here to start Discovery
}
break;
default:
return;
}
}
Подробнее о разрешении: https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en