已关闭,该问题需要details or clarity,目前不接受回答。
**想要改进此问题?**通过editing this post添加详细信息并澄清问题。
6天前关闭。
Improve this question
要在Android应用程序中使用低功耗蓝牙,需要在Manifest中包含多个权限,并在运行时检查用户是否已批准这些权限
问题是有6个可能的权限,但试图检查所有的权限将失败!这是因为运行时权限从来没有授予某些版本的Android。
这6个权限是
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
非常感谢@Kozmotronik提供的简单解决方案,只需检查每个版本Android所需的权限
以下代码检查所需的权限,如果尚未授予权限,则将其添加到列表中。然后请求缺少的权限。
private fun checkAndRequestMissingPermissions() {
// check required permissions - request those which have not already been granted
val missingPermissionsToBeRequested = ArrayList<String>()
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.BLUETOOTH)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_ADMIN) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.BLUETOOTH_ADMIN)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
// For Android 12 and above require both BLUETOOTH_CONNECT and BLUETOOTH_SCAN
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.BLUETOOTH_CONNECT)
if (ContextCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.BLUETOOTH_SCAN)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// FINE_LOCATION is needed for Android 10 and above
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.ACCESS_FINE_LOCATION)
} else {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
missingPermissionsToBeRequested.add(Manifest.permission.ACCESS_COARSE_LOCATION)
}
if (missingPermissionsToBeRequested.isNotEmpty()) {
writeToLog("Missing the following permissions: $missingPermissionsToBeRequested")
ActivityCompat.requestPermissions(this, missingPermissionsToBeRequested.toArray(arrayOfNulls<String>(0)), REQUEST_MULTIPLE_PERMISSIONS)
} else {
writeToLog("All required permissions GRANTED !")
}
}
然后onRequestPermissionsResult()可以检查用户是否批准了所需的权限
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == REQUEST_MULTIPLE_PERMISSIONS) {
for (idx in permissions.indices) {
var result = if (grantResults[idx] == PackageManager.PERMISSION_GRANTED) "Granted" else "Denied"
writeToLog("REQUEST_MULTIPLE_PERMISSIONS Permission ${permissions[idx]} $result}")
}
}
}
Android在允许访问某些BLE功能之前需要进行权限检查。如果不授予权限,则仍必须进行检查,但可以通过添加Android版本检查来使其工作。
举个例子
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_SCAN) != PackageManager.PERMISSION_GRANTED) {
writeToLog("Scan permission denied")
} else {
bluetoothScanner.startScan(filters, scanSettings, scanCallback)
writeToLog("Bluetooth Scan Started")
}
最近@Kozmotronik改进了他的答案,如下所示
2条答案
按热度按时间but5z9lq1#
Google通过添加新的
BLUETOOTH_CONNECT
和BLUETOOTH_SCAN
权限使Android变得更加严格。如果您尝试访问任何需要这些权限的BLE API,您将在运行时获得SecurityException
。因此我们需要检查清单文件中设置为android.intent.action.MAIN
的Activity中的权限。我称之为MainActivity
。不幸的是,我还没有使用Kotlin编写代码。所以我会用Java写例子。主活动
到目前为止,我们已经根据设备的SDK请求了所有需要的权限。现在我们需要阻止API调用路径以能够检查权限。在实现蓝牙扫描的某个地方放置一个函数,如下面的代码示例中的
startScanning()
,而不是直接使用BleScanner.scan()
API。以下所有函数必须在同一个Activity或片段中。执行扫描的其他Activity或片段
这种逻辑本质上有点混乱,但它是健壮的,并且已经在Google Play商店中呈现的real application中运行。然而,它不是100%完整的代码,因为您需要将其背后的想法适应您的应用程序。
tyg4sfes2#
在我之前的回答中,我展示了如何使用旧的requestPermissions来请求运行时权限,并最终使用onRequestPermissionsResult回调来处理所请求的权限。
在这个答案中,我将基于前面的代码示例,展示如何使用名为ActivityResultLauncher的较新API来处理请求相同权限的问题。
作为奖励,我还添加了一个示例,显示如何请求用户启用BLE硬件并使用相同的API处理结果。
因此,最终您将能够使用ActivityResultLauncher API请求所需的运行时BLE权限和BLE硬件激活。
进入代码之前请注意,代码的位置可能会因应用程序而异,具体取决于其结构。这就是为什么开发人员有责任将代码仔细放置在适当的源文件中,以使其无问题运行。
如果您在将示例应用到项目中时遇到问题,请随时询问。