Android 12 Новые разрешения Bluetooth
Bluetooth - это основная зависимость нашего приложения. Итак, мы уже пытаемся реализовать новые разрешения Bluetooth в Android 12. Наш единственный ресурс - разработчики Android. Новые разрешения Bluetooth в Android 12 . Там просто говорится добавить разрешения
"android.permission.BLUETOOTH_CONNECT"
"android.permission.BLUETOOTH_SCAN"
Я добавляю, и у меня есть разрешения на выполнение для обоих и, конечно же, местоположения (обычно, как до 12)).
Других изменений в моей кодовой базе нет. Должно быть? Я не знаю. Итак, проблема в том, что мое приложение не может найти устройство BLE. Я не мог найти причину.
У вас есть предложения или ресурсы?
13 ответов
Это была ошибка платформы. Google исправил ошибку в новой бета-версии Android 12.
100% рабочее решение: не нужен сторонний плагин
код манифеста:
<!--BLUETOOTH PERMISSION-->
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- Needed only if your app looks for Bluetooth devices.
If your app doesn't use Bluetooth scan results to derive physical
location information, you can strongly assert that your app
doesn't derive physical location. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<!--bibo01 : hardware option-->
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
Код Котлина:
//check android12+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
requestMultiplePermissions.launch(arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_CONNECT))
}
else{
val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
requestBluetooth.launch(enableBtIntent)
}
....................................................
private var requestBluetooth = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
//granted
}else{
//deny
}
}
private val requestMultiplePermissions =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
permissions.entries.forEach {
Log.d("test006", "${it.key} = ${it.value}")
}
}
Подробнее: https://developer.android.com/guide/topics/connectivity/bluetooth/permissions
Это сработало для меня,
В манифесте добавьте следующие разрешения:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
Затем перед выполнением функции Bluetooth проверьте разрешение:
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED)
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
{
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 2);
return;
}
}
Например,
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.BLUETOOTH_CONNECT}, 2);
return;
}
}
mBTSocket.connect();
Я только что добавил в манифест:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
а затем я запросил эти разрешения у основного действия, как и у любого другого. Для запроса разрешения я использую библиотеку
implementation 'pub.devrel:easypermissions:3.0.0'
тогда вы можете просто вызвать эту функцию
public static final String[] BLUETOOTH_PERMISSIONS_S = { Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT} ;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
if (!EasyPermissions.hasPermissions(this, BLUETOOTH_PERMISSIONS_S)) {
EasyPermissions.requestPermissions(this, message, yourRequestCode,BLUETOOTH_PERMISSIONS_S);
}
}
и переопределить onRequestPermissionResult
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
}
Это происходит с Android 12 и Android 13. Добавление новых разрешений не помогло решить проблему в моем случае: у меня настроены все соответствующие разрешения для Bluetooth и WiFi:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"/>
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-feature android:name="android.hardware.bluetooth" android:required="false"/>
<uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
android:maxSdkVersion="32" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES"
android:usesPermissionFlags="neverForLocation" />
Ручное решение (скриншот добавлен): перейдите в настройки приложения и нажмите «Разрешения». Вы увидите разрешенные и запрещенные (не разрешенные) разрешения. В списке разрешений «Не разрешено» будет разрешение «Близлежащие устройства». Разрешите это, и приложение будет работать без проблем в Android 12 и Android 13.
У меня была ошибка с отсутствием BLUETOOTH_ADVERTISING в манифесте Android при переходе на Android 12.
В общем, я только что добавилcheckSelfPermission(Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED
в моих условиях, гдеstartAdvertising
назывался.
В Android 12 после добавления строки ниже у меня все работает нормально.
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s"/>
На Android 13 я последовал ответу, получившему наибольшее количество голосов, и он устранил проблему с запросом «Сканирование Bluetooth». Однако я получил новую ошибку «Bluetooth Connect». Потратив некоторое время, я смог выяснить, что в Android 13 Bluetooth Connect был сделан запросом во время выполнения, поэтому просто иметь его в файле манифеста недостаточно. мне пришлось перезаписать свойOnCreate
в моемMainActivity.cs
файл, чтобы он мог получить разрешение во время выполнения.
private const int REQUEST_FINE_LOCATION_PERMISSION = 100;
private const int REQUEST_BLUETOOTH_SCAN_PERMISSION = 101;
private const int REQUEST_BACKGROUND_LOCATION_PERMISSION = 102;
private const int REQUEST_BLUETOOTH_CONNECT_PERMISSION= 103;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
RequestedOrientation = ScreenOrientation.Portrait;
// Request the ACCESS_FINE_LOCATION permission at runtime
if (CheckSelfPermission(Manifest.Permission.AccessFineLocation) != Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.AccessFineLocation },
REQUEST_FINE_LOCATION_PERMISSION);
}
if (CheckSelfPermission(Manifest.Permission.AccessBackgroundLocation) != Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.AccessBackgroundLocation },
REQUEST_BACKGROUND_LOCATION_PERMISSION);
}
// Request the BLUETOOTH_SCAN permission at runtime
if (CheckSelfPermission(Manifest.Permission.BluetoothScan) != Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.BluetoothScan },
REQUEST_BLUETOOTH_SCAN_PERMISSION);
}
//Request the BLUETOOTH_CONNECT permission at runtime
if (CheckSelfPermission(Manifest.Permission.BluetoothConnect) != Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.BluetoothConnect },
REQUEST_BLUETOOTH_CONNECT_PERMISSION);
}
}
Как только я добавил разрешение на выполнение, оно начало работать на Android 13.
Если вы хотите, чтобы ваше приложение инициировало обнаружение устройства или манипулировало настройками Bluetooth, вы должны объявить разрешение BLUETOOTH_ADMIN в дополнение к разрешению BLUETOOTH. Большинству приложений это разрешение требуется исключительно для возможности обнаружения локальных устройств Bluetooth. Не используйте другие возможности, предоставленные этим разрешением, если приложение не является «диспетчером питания», который изменяет настройки Bluetooth по запросу пользователя. Объявите разрешения Bluetooth в файле манифеста приложения.
от разработчика Android мы видим, что вам нужно добавить
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
в вашем файле манифеста, но вы не добавили его для обнаружения других устройств, я думаю, что это ресурс вашей проблемы
это сработало для меня:
[AndroidManifest.xml]
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
[MainActivity.java]
private static final String[] PERMISSIONS = new String[]{Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_ADVERTISE };
_
public void getPermissionFromUser()
{
if(BA == null){
BA = BluetoothAdapter.getDefaultAdapter();
}
int i=0;
for(String permission : PERMISSIONS){
String title = "bluetooth permission needed";
String msg="";
if(i==0){
msg = "Give the app permission to use Bluetooth";
}else if(i==1) {
msg = "Give permission to search for the current device on other Bluetooth devices";
}
if (ActivityCompat.checkSelfPermission(MainActivity.this, PERMISSIONS[i]) == PackageManager.PERMISSION_DENIED) {
int finalI = i;
final AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle(title);
builder.setMessage(msg);
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialogInterface) {
requestPermissions(new String[]{PERMISSIONS[finalI]}, 3);
}
});
builder.show();
}
i++;
}
}
Я не уверен, объявили ли они что-нибудь об изменениях Bluetooth, но если ничто другое не помогает, они недавно представили это, что МОЖЕТ помочь в вашем случае использования, если вы не сделаете более сложные вещи.
https://developer.android.com/guide/topics/connectivity/companion-device-pairing#kotlin
В более новых версиях вам также больше не нужно разрешение на местоположение, если это делает все, что вам нужно.
Что касается образца: вы можете просто не включать эти 2 строки:
.setNamePattern(Pattern.compile("My device"))
.addServiceUuid(ParcelUuid(UUID(0x123abcL, -1L)), null)
файл манифеста:
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
private static final int REQUEST_CODE_BLUETOOTH_SCAN = 1;
Метод разрешения проверки. Запрос разрешения требуется для Android 12 или более поздней версии. Поэтому, если версия ниже, она возвращает true.
private boolean checkPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
int permission = ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.BLUETOOTH_SCAN);
return permission == PackageManager.PERMISSION_GRANTED;
}else{
return true;
}
}
И метод разрешения запроса
private void requestPermission() {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.BLUETOOTH_SCAN}, REQUEST_CODE_BLUETOOTH_SCAN);
}
наконец, переопределить onRequestPermissionsResult
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CODE_BLUETOOTH_SCAN) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// The user has granted the permission.
// Start scanning for Bluetooth devices.
} else {
// The user has denied the permission.
// Display an error message.
}
}
}
Запрашивайте разрешение во время выполнения для доступа к точному местоположению при сканировании BLE.