我使用的是三星 Note 8 (Android 9) 和三星 A50(Android 10)。
我正在进行 BLE 扫描,需要蓝牙和位置权限(Android >=23)。在开始 BLE 扫描之前,我不向应用程序提供位置权限。
在 Note 8 上开始扫描时,如果未给出位置权限,我会收到 onScanFailed() 回调,错误代码为 2 (SCAN_FAILED_APPLICATION_REGISTRATION_FAILED)。
在 A50 上开始扫描时,我没有收到任何回调。 从 adb 日志中我可以看到内部日志,例如
BluetoothUtils: Permission denial: Need ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATIONpermission to get scan results 07-28 21:03:35.720 2010 2650 D
我想确定由于缺少权限而发生扫描失败。我该怎么做?
注意-我正在构建一个Android库,而不是一个Android应用程序,所以请相应地提出建议。
可能有几件事。首先请注意,对于 BLE 扫描,您需要获得定位和蓝牙权限。因此,在您的开发环境中,您需要指定这一点。例如,在 android studio 中,您需要进入清单并专门授予蓝牙和位置权限。见下图:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
但是,这还不够,因为在您的手机应用程序中,您需要获得用户的许可。
当您运行 Android 时,您需要授予位置权限(并打开位置和蓝牙),然后扫描才能工作。
要允许定位,请访问:
总结一下,检查您的 IDE 是否启用了权限。然后检查应用程序(在手机上)用户已允许该权限。
package com.example.bleblue.common
import android.Manifest
import android.content.Context
import android.content.pm.PackageManager
import android.os.Build
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
object permissionHandler {
private val requiredPermissions: Array<String>
get() {
return when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU -> arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.POST_NOTIFICATIONS
)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S -> arrayOf(
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.BLUETOOTH_CONNECT,
Manifest.permission.ACCESS_FINE_LOCATION
)
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q -> arrayOf(
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
)
else -> arrayOf(
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
)
}
}
fun hasPermissions(context: Context): Boolean {
return requiredPermissions.all {
ContextCompat.checkSelfPermission(context, it) == PackageManager.PERMISSION_GRANTED
}
}
fun requestPermissions(activity: AppCompatActivity) {
val permissionsToRequest = requiredPermissions.filter {
ContextCompat.checkSelfPermission(activity, it) != PackageManager.PERMISSION_GRANTED
}.toTypedArray()
if (permissionsToRequest.isNotEmpty()) {
activity.requestPermissions(permissionsToRequest, REQUEST_CODE_REQUIRED_PERMISSIONS)
}
}
const val REQUEST_CODE_REQUIRED_PERMISSIONS = 1
}