Поскольку зефир обновляет обнаружение Bluetooth с помощью BluetoothAdapter.getDefaultAdapter(). StartDiscovery(); сломан

У меня есть приложение, использующее bluetooth и подключающееся к устройствам, can'f найти любые устройства, использующие BluetoothAdapter.getDefaultAdapter(). startDiscovery(); Он отлично работал перед открытием. Пробовал и другие приложения, он не работает и в других приложениях. Но устройство, с которым я пытаюсь соединиться (Arduino bt-module), можно найти в настройках Android. Любая идея, что я могу попробовать? Я реализовал все, как описано в http://developer.android.com/guide/topics/connectivity/bluetooth.html, и работал до обновления.

Ответ 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).

https://developer.android.com/about/versions/marshmallow/android-6.0-changes.html#behavior-hardware-id

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

Добавлено разрешение на 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