代码之家  ›  专栏  ›  技术社区  ›  Deusnominus

我无法使用“requestPermissionLauncher.launch(permissions)”显示权限窗口

  •  0
  • Deusnominus  · 技术社区  · 9 月前

    我正在尝试请求我的应用程序所需的权限,但无法显示权限窗口。 这是我的堆肥:

    @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.ACCES_CARSE_LOCATION,android.prmission.ACCESS_FINE_LOCATION、android.pemission.ACCESS_BACKGROUND_LOCATION和android.ppermission.BLUETOOTH,android.permission.BLUETTOTH_SCAN,android.permission.BLUETOOTH_AVERTISE,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 回复  |  直到 9 月前
        1
  •  0
  •   NehaK    9 月前

    看起来您已经正确设置了权限请求逻辑,但权限对话框没有出现。以下是可能发生这种情况的一些潜在原因以及如何解决它们:

    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上的POST_NOTIFICATIONS权限(API 33)

    这个 POST_NOTIFICATIONS 仅在Android 13(API 33级)及更高版本上需要权限。如果您在API级别较低的设备上进行测试,则可能不需要此权限,尝试请求此权限可能会导致问题。 解决方案:确保 POST_通知 仅在Android 13+设备上请求权限。

    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
    }
    

    我希望这能有所帮助。