Intereting Posts
Значки оповещения, не содержащие слова в Android O В чем разница между частными библиотеками Android, зависимостями и папкой libs? Использование FLAG_SHOW_WHEN_LOCKED с отключеннымKeyguard () в защищенном экране блокировки Android Как установить фоновое изображение кнопки с эффектом пульсации в android Получение изображения из галереи из Picasa // Google + синхронизированные папки не работают Пользовательские сочетания клавиш Можно ли удалить фрагмент, определенный в файле layout.xml? Фоновый эффект пульсации на элементах панели инструментов StandAlone отсутствует Библиотека загрузки изображений Picasso: как загрузить видео эскизы LinearLayout: layout_width vs. minWidth Лучший способ реализовать приложение чата с помощью XMPP на Android? Почему android.app.Activity не абстрактно по дизайну? SQLite и сохранение изображений Ошибка сервера Volley с нулевым ответом сети Как выбрать данные между двумя диапазонами дат в android SQLite

Android 6.0 запрашивает сопряжение с удаленными устройствами при извлечении UUIDS

Я пытаюсь получить UUIDS с удаленного устройства Bluetooth следующим образом:

device.fetchUuidsWithSdp(); 

Это будет работать тихо и без взаимодействия с пользователем на всех устройствах, кроме тех, у которых Android 6.0, которые явно запрашивают диалог сопряжения, чтобы подключиться к удаленному устройству для получения UUID. Это ожидаемое поведение? Где это документировано? Есть ли способ инициировать обнаружение UUID без явного разрешения разрешить его с другого конца?

Solutions Collecting From Web of "Android 6.0 запрашивает сопряжение с удаленными устройствами при извлечении UUIDS"

Я нашел обходное решение для этого, используя скрытый метод sdpSearch вместо fetchUuidsWithSdp. Это требует немного отражения. Это работало для меня на Android версии 6.0 и 5.1.1 без устройств, пытающихся установить соединение. Надеюсь, что это поможет, и не стесняйтесь улучшать довольно плохую обработку исключений.

 public class DeviceFinder{ public interface Callback{ void onDeviceFound(BluetoothDevice bd); void onFinishedCallback(); void onStartCallback(); } private ArrayList<BluetoothDevice> tempDevices = new ArrayList<>(); private Callback mCallback; private Context mContext; private String ACTION_SDP_RECORD; private String EXTRA_SDP_SEARCH_RESULT; private BroadcastReceiver mReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (BluetoothDevice.ACTION_FOUND.equals(action)){ // Aggregating found devices BluetoothDevice bd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); tempDevices.add(bd); }else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)){ // Prepare for new search tempDevices = new ArrayList<>(); mCallback.onStartCallback(); }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)){ // Do a sdpSearch for all found devices for (BluetoothDevice bd : tempDevices){ try { Method m = bd.getClass().getDeclaredMethod("sdpSearch", ParcelUuid.class); m.invoke(bd, new ParcelUuid(/* your uuid here */)); } catch (Exception e) { e.printStackTrace(); } } mCallback.onFinishedCallback(); }else if( ACTION_SDP_RECORD.equals(action)){ // check if the device has the specified uuid BluetoothDevice bd = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); if (intent.getIntExtra(EXTRA_SDP_SEARCH_RESULT, 1) == 0){ mCallback.onDeviceFound(bd); } } } }; public DeviceFinder(Context context, Callback mCallback){ this.mCallback = mCallback; this.mContext = context; try { Field f = BluetoothDevice.class.getDeclaredField("ACTION_SDP_RECORD"); ACTION_SDP_RECORD = ((String)f.get(null)); f = BluetoothDevice.class.getDeclaredField("EXTRA_SDP_SEARCH_STATUS"); EXTRA_SDP_SEARCH_RESULT = ((String)f.get(null)); } catch (Exception e) { e.printStackTrace(); } IntentFilter intentFilter = new IntentFilter(); intentFilter.addAction(BluetoothDevice.ACTION_FOUND); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); intentFilter.addAction(ACTION_SDP_RECORD); context.registerReceiver(mReceiver, intentFilter); startScan(); } public void startScan(){ BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); if (!bluetoothAdapter.isDiscovering()) { bluetoothAdapter.startDiscovery(); } } public void unregisterReciever(){ mContext.unregisterReceiver(mReceiver); } } 

Edit: sdpSearch был добавлен в android 6.0, поэтому он не работает для более ранних версий

Обновить

Официальный ответ Google на ваш вопрос :

Привет. Мы понимаем, что у вас есть запрос на конкретное использование, которое можно найти здесь в stackoverflow.

https://stackoverflow.com/questions/14812326/android-bluetooth-get-uuids-of-discovered-devices

благодаря


В Android 6.0 есть изменения в разрешениях. Внедрение разрешений во время выполнения, а не глобальное принятие всех приложений требуется разрешение при установке приложения.

В двух словах, типы разрешений свободно помещаются в два типа, нормальные или опасные. Любое разрешение, которое нарушает конфиденциальность пользователя, считается опасным.

Разрешения также помещаются в группы аналогичных разрешений, например, доступ к прекрасному местоположению и грубое местоположение.

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

См. Подробности ниже:

Разрешения времени выполнения .

В этом выпуске представлена ​​новая модель разрешений, в которой теперь пользователи могут напрямую управлять разрешениями приложений во время выполнения. Эта модель дает пользователям улучшенную видимость и контроль над разрешениями, а также оптимизирует процессы установки и автоматического обновления для разработчиков приложений. Пользователи могут предоставлять или отменять разрешения для установленных приложений.

В ваших приложениях, ориентированных на Android 6.0 (API-уровень 23) или выше, убедитесь, что вы проверяете и запрашиваете разрешения во время выполнения. Чтобы определить, было ли ваше приложение предоставлено разрешение, вызовите новый метод checkSelfPermission (). Чтобы запросить разрешение, вызовите новый метод requestPermissions (). Даже если ваше приложение не предназначено для Android 6.0 (API-уровень 23), вы должны проверить свое приложение в новой модели разрешений.

… /

Начиная с Android 6.0 (API-уровень 23) , пользователи предоставляют и отменяют разрешения приложений во время выполнения, вместо того, чтобы делать это при установке приложения. В результате вам придется тестировать свое приложение в более широком диапазоне условий. До Android 6.0 можно было бы разумно предположить, что если ваше приложение работает вообще, оно имеет все разрешения, которые он декларирует в манифесте приложения. В новой модели разрешений вы больше не можете делать это предположение.

Разрешения классифицируются как обычные или опасные

Доступ к Bluetooth рассматривается как нормальное разрешение, в то время как спаривание или чтение сведений о приложении считается опасным.

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

Поэтому при запросе информации с устройства:

Если приложение запрашивает опасное разрешение, указанное в его манифестах, и приложение в настоящее время не имеет разрешений в группе разрешений, система показывает диалоговое окно для пользователя, описывающего группу разрешений, к которой приложение хочет получить доступ. Диалоговое окно не описывает конкретные разрешения внутри этой группы. Например, если приложение запрашивает разрешение READ_CONTACTS, системное диалоговое окно просто говорит, что приложение нуждается в доступе к контактам устройства. Если пользователь предоставляет разрешение, система предоставляет приложение только запрашиваемое им разрешение.

См. Раздел « Работа с системными разрешениями» для получения подробной информации о реализации.


В ответ на ваш комментарий

Введите описание изображения здесь

Существует множество проблем с ошибками bluetooth и выпуском android 6.0. Как и в 5.0, ожидается, что они будут исправлены следующим патчем. Тем не менее, я не вижу вашей проблемы в качестве ошибки.

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

Ваш снимок экрана:

Введите описание изображения здесь

И из вашего кода здесь, на github:

 android { compileSdkVersion 23 buildToolsVersion "23.0.1" defaultConfig { applicationId "me.bluetoothuuidsample" minSdkVersion 18 targetSdkVersion 23 versionCode 1 versionName "1.0" } 

Устройства зефира ведут себя точно так же, как они предназначены для разрешений времени выполнения, но я уверен, что Google подтвердит это для вас.

Чтобы избежать необходимости иметь дело с переходом на данном этапе, используйте целевое значение sdk как менее 23.

 targetSdkVersion 22 

Этот блог Cheesefactory хорошо разбирается. Все, что нужно знать разработчикам Android о новых разрешениях Runtime для Android

Изменить 2

Для получения UUID требуется разрешение на размещение, здесь есть сообщение: подробнее https://stackoverflow.com/a/33045489/3956566