Android 12 新蓝牙权限

问题描述 投票:0回答:11

蓝牙是我们应用程序的主要依赖项。因此,我们已经尝试实施新的 Android 12 蓝牙权限。我们唯一的资源是 Android 开发人员 Android 12 中的新蓝牙权限。只是说添加权限

“android.permission.BLUETOOTH_CONNECT”

“android.permission.BLUETOOTH_SCAN”

我添加并且我获得了两者的运行时权限,当然还有位置(通常为 12 之前))。
我的代码库中没有其他更改。应该?我不知道。所以,问题是我的应用找不到 BLE 设备。我找不到原因。

你有什么建议或资源吗?

android bluetooth android-permissions android-bluetooth android-12
11个回答
50
投票

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"/>

科特林代码: //检查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


16
投票

这对我有用,

在清单中,添加以下权限:

<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" />

然后,在执行蓝牙功能之前,检查权限:

//--------------------------Java--------------------------
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;
                    }
                }

//--------------------------Kotlin--------------------------
if (ContextCompat.checkSelfPermission(this@MainActivity, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_DENIED) 
               {
                   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) 
                   {
                       ActivityCompat.requestPermissions(this@MainActivity, arrayOf(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();

8
投票

我刚刚添加到清单中:

<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);
    }

JETPACK COMPOSE 更新

如果你使用的是 jetpack compose 你可以这样处理:

在 rememberMultiplePermissionState 函数中创建您的权限列表

rememberMultiplePermissionsState(
            permissions = listOf(
                Manifest.permission.BLUETOOTH_CONNECT,
                Manifest.permission.BLUETOOTH_SCAN
            )
        )

然后观察生命周期事件和恢复启动权限请求

val lifecycleOwner = LocalLifecycleOwner.current
DisposableEffect(key1 = lifecycleOwner,
    effect = {
        val observer = LifecycleEventObserver { _, event ->
            if(event == Lifecycle.Event.ON_START) {
                permissionsState.launchMultiplePermissionRequest()
            }
        }
        lifecycleOwner.lifecycle.addObserver(observer)

        onDispose {
            lifecycleOwner.lifecycle.removeObserver(observer)
        }
    })

观察权限状态

permissionsState.permissions.forEach { permissionState ->
            when(permissionState.permission) {
                Manifest.permission.ACCESS_FINE_LOCATION -> {
                    when {
                        permissionState.hasPermission -> {}
                    }
                }
            }
        }
    }

1
投票

如果您希望您的应用启动设备发现或操作 蓝牙设置,必须声明BLUETOOTH_ADMIN权限 除了蓝牙权限。大多数应用程序需要此权限 仅用于发现本地蓝牙设备的能力。不要使用 此权限授予的其他能力,除非该应用是 根据用户请求修改蓝牙设置的“电源管理器”。 在您的应用程序清单文件中声明蓝牙权限

来自 developer android 我们看到你必须添加

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

在你的清单文件中,但你没有添加它来发现其他设备我认为这是你问题的来源


1
投票

我在切换到 Android 12 时遇到错误,Android 清单中缺少 BLUETOOTH_ADVERTISING

基本上,我只是在调用

checkSelfPermission(Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED
的条件中添加了
startAdvertising


1
投票

它发生在 Android 12 和 Android 13 上。添加新权限无法解决我的问题: 我已经为蓝牙和 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 中毫无问题地运行。


1
投票

在 android 12 中,添加以下行后对我来说工作正常。

<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s"/>

0
投票

我不确定他们是否宣布了有关蓝牙更改的任何内容,但如果没有其他帮助,他们最近介绍了这个,除非您做更复杂的事情,否则这可能对您的用例有所帮助。

https://developer.android.com/guide/topics/connectivity/companion-device-pairing#kotlin

在较新的版本中,如果这可以满足您的所有需求,您也不再需要位置权限。

关于样本:你可以不包括这两行:

.setNamePattern(Pattern.compile("My device"))
.addServiceUuid(ParcelUuid(UUID(0x123abcL, -1L)), null)

我用它来搜索设备没有任何问题,连接工作类似


0
投票

[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) {

            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[]{android.Manifest.permission.BLUETOOTH_ADVERTISE}, 3);        
                }
            });
            builder.show();
        }
        i++; 
    }
}

-1
投票

这是一个平台错误。谷歌在新的 Android 12 Beta 版本中修复了该错误。


-1
投票

在扫描 BLE 时询问运行时权限以访问精确位置。

© www.soinside.com 2019 - 2024. All rights reserved.