我正在尝试请求我的应用程序所需的权限,但无法显示权限窗口。 这是我的可组合项:
@Composable
fun IntroScreen(
introViewModel: IntroViewModel = hiltViewModel(),
navController: NavController
){
val requestPermissionLauncher = rememberLauncherForActivityResult(
ActivityResultContracts.RequestMultiplePermissions()
) { permissionsMap ->
permissionsMap.forEach { (permission, isGranted) ->
Log.i("tag", "Permission: $permission, Granted: $isGranted")
}
}
val permissions = introViewModel.permissions
val permissionsState by introViewModel.permissionsState.collectAsState()
Column(
modifier = Modifier
.fillMaxWidth(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Button(onClick = {
Log.i("tag", "Permissions state: ${permissionsState.joinToString(separator = ", ")}")
val allPermissionsGranted = permissionsState.all { it }
Log.i("tag", "All permissions granted: $allPermissionsGranted")
if (!allPermissionsGranted) {
// Request permissions
Log.i("tag", "Requesting permissions inside if statement: ${permissions.joinToString(", ")}")
requestPermissionLauncher.launch(permissions)
} else {
Log.i("tag", "All permissions already granted")
}
}, shape = Shapes.small) {
Text(text = "Ask Permissions")
}
}
这是我的视图模型:
@HiltViewModel
class IntroViewModel @Inject constructor(private val context: Context, introInteractor:IntroInteractor):ViewModel(){
private val _permissionsState = MutableStateFlow(emptyList<Boolean>())
val permissionsState: StateFlow<List<Boolean>> get() = _permissionsState
val permissions = arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
Manifest.permission.BLUETOOTH,
Manifest.permission.BLUETOOTH_ADMIN,
Manifest.permission.BLUETOOTH_SCAN,
Manifest.permission.BLUETOOTH_ADVERTISE,
Manifest.permission.POST_NOTIFICATIONS,
Manifest.permission.CAMERA,
Manifest.permission.INTERNET
)
init {
updatePermissionsState()
}
fun updatePermissionsState() {
val permissionsStateList = permissions.map { permission ->
ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED
}
_permissionsState.value = permissionsStateList
}
}
我使代码尽可能简单。所有记录的语句都会返回预期的结果。互联网、蓝牙、蓝牙权限为真,其余为假。我尝试删除那些真实的,但我没有让窗口出现。 我的代码到达“requestPermissionLauncher.launch(permissions)”并且 launch() 的参数是正确的。为什么我无法显示该窗口?
这是启动器之前 if 语句内的日志结果: “在if语句中请求权限:android.permission.ACCESS_COARSE_LOCATION,android.permission.ACCESS_FINE_LOCATION,android.permission.ACCESS_BACKGROUND_LOCATION,android.permission.BLUETOOTH,android.permission.BLUETOOTH_ADMIN,android.permission.BLUETOOTH_SCAN,android.permission.BLUETOOTH_ADVERTISE,android .permission.POST_NOTIFICATIONS、android.permission.CAMERA、android.permission.INTERNET ”.
注意:我正在真正的 Galaxy A14 上进行测试,我的清单文件是:
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SPECIAL_USE"/>
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<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" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
<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.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="false"/>
看起来您已经正确设置了权限请求逻辑,但没有出现权限对话框。以下是发生这种情况的一些潜在原因以及解决方法:
1。检查Android版本兼容性
后台位置权限:在运行
Android 10 (API level 29) and higher
的设备上,应在授予前台位置权限(ACCESS_BACKGROUND_LOCATION
和 ACCESS_FINE_LOCATION
)后单独请求后台位置权限(ACCESS_COARSE_LOCATION
)。
一次请求所有位置权限可能会导致该对话框不出现。
解决方案:在授予前台位置权限后,尝试单独调用后台位置权限。
if (permissionsState[0] && permissionsState[1]) { // Assuming these indices are for ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION
requestPermissionLauncher.launch(arrayOf(Manifest.permission.ACCESS_BACKGROUND_LOCATION))
}
2。 Android 13 (API 33) 上的 POST_NOTIFICATIONS 权限
仅 Android 13(API 级别 33)及更高版本需要
POST_NOTIFICATIONS
权限。如果您在 API 级别较低的设备上进行测试,则可能不需要此权限,并且尝试请求它可能会导致问题。
解决方案:确保仅在 Android 13+ 设备上请求 POST_NOTIFICATIONS
权限。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
requestPermissionLauncher.launch(arrayOf(Manifest.permission.POST_NOTIFICATIONS))
}
3.已永久授予或拒绝许可
如果之前已授予或永久拒绝某个权限(使用“不再询问”选项),则不会出现该对话框。相反,您应该引导用户进入应用程序的设置以手动启用权限。
解决方案:检查是否有权限被永久拒绝并进行相应处理。
val shouldShowRequestPermissionRationale = permissions.any { permission ->
ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)
}
if (!shouldShowRequestPermissionRationale) {
// Guide the user to the app's settings
}
我希望这有帮助。