简体   繁体   English

蓝牙权限在 Jetpack Compose 中无法正常工作

[英]Bluetooth Permission not working correctly in jetpack compose

I am using com.google.accompanist:accompanist-permissions:0.25.1 in my project.我在我的项目中使用com.google.accompanist:accompanist-permissions:0.25.1 I am trying to request bluetooth permission in runtime which is requesting.我正在尝试在请求的运行时请求蓝牙权限。 I want to know how user know that permission is disable permanently.我想知道用户如何知道权限被永久禁用。

Manifest.xml清单.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-feature android:name="android.hardware.bluetooth_le" android:required="false"/>
    <!-- Request legacy Bluetooth permissions on older devices. -->
    <uses-permission
        android:name="android.permission.BLUETOOTH"
        android:maxSdkVersion="30" />
    <uses-permission
        android:name="android.permission.BLUETOOTH_ADMIN"
        android:maxSdkVersion="30" />
    <uses-permission
        android:name="android.permission.BLUETOOTH_SCAN"
        android:usesPermissionFlags="neverForLocation"
        tools:targetApi="s" />
    <!-- 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" />
    <uses-feature android:name="android.hardware.bluetooth" android:required="false"/>

    <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.Permission"
        tools:targetApi="31">
        <activity
            android:name=".MainActivity"
            android:exported="true"
            android:label="@string/app_name"
            android:theme="@style/Theme.Permission">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

            <meta-data
                android:name="android.app.lib_name"
                android:value="" />
        </activity>
    </application>

</manifest>

MainActivity.kt主活动.kt

package com.vivek.permission

import android.Manifest
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.rememberMultiplePermissionsState
import com.vivek.permission.ui.theme.PermissionTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PermissionTheme {
                // A surface container using the 'background' color from the theme
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(MaterialTheme.colorScheme.background)
                ) {
                    ExampleScreenWithAccompanist()
                }
            }
        }
    }
}

val permissionsList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    listOf(
        Manifest.permission.BLUETOOTH,
        Manifest.permission.BLUETOOTH_ADMIN,
        Manifest.permission.BLUETOOTH_SCAN,
        Manifest.permission.BLUETOOTH_CONNECT,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
} else {
    listOf(
        Manifest.permission.BLUETOOTH,
        Manifest.permission.BLUETOOTH_ADMIN,
        Manifest.permission.ACCESS_COARSE_LOCATION,
    )
}

@OptIn(ExperimentalPermissionsApi::class)
@Composable
fun ExampleScreenWithAccompanist() {
    val multiplePermissionsState = rememberMultiplePermissionsState(permissions = permissionsList)
    Text(text = "we need your permission", color = Color.White)
    when {
        multiplePermissionsState.allPermissionsGranted -> {
            Text(text = " Permission Granted", color = Color.White)
        }
        multiplePermissionsState.shouldShowRationale -> {
            Text(text = " Permission ShouldShowRationale", color = Color.White)
        }
        !multiplePermissionsState.allPermissionsGranted && !multiplePermissionsState.shouldShowRationale -> {
            Text(
                text = "Permission permanently denied ,you can enable it by going to app setting",
                color = Color.White
            )
        }
    }

    Button(onClick = { multiplePermissionsState.launchMultiplePermissionRequest() }) {
        Text(text = "Give permission", color = Color.White)
    }
}

My 3 when statement run when user install first time the application.我的 3 when 语句在用户第一次安装应用程序时运行。 So how can i handle properly..那么我该如何正确处理..

Try:尝试:

// MainActivity.kt

package com.vivek.permission

import android.Manifest
import android.content.pm.PackageManager
import android.os.Build
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import com.vivek.permission.ui.theme.PermissionTheme

class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            PermissionTheme {
                // A surface container using the 'background' color from the theme
                Column(
                    modifier = Modifier
                        .fillMaxSize()
                        .background(MaterialTheme.colorScheme.background)
                ) {
                    ExampleScreenWithAccompanist()
                }
            }
        }
    }
}

val permissionsList = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
    listOf(
        Manifest.permission.BLUETOOTH,
        Manifest.permission.BLUETOOTH_ADMIN,
        Manifest.permission.BLUETOOTH_SCAN,
        Manifest.permission.BLUETOOTH_CONNECT,
        Manifest.permission.ACCESS_COARSE_LOCATION,
        Manifest.permission.ACCESS_FINE_LOCATION
    )
} else {
    listOf(
        Manifest.permission.BLUETOOTH,
        Manifest.permission.BLUETOOTH_ADMIN,
        Manifest.permission.ACCESS_COARSE_LOCATION,
    )
}

@Composable
fun ExampleScreenWithAccompanist() {
    val requestPermissionLauncher =
        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
            permissions.entries.forEach {
                if (it.value) {
                    Text(text = " Permission Granted", color = Color.White)
                } else {
                    Text(
                        text = "Permission permanently denied ,you can enable it by going to app setting",
                        color = Color.White
                    )
                }
            }
        }

    Button(onClick = { requestPermissionLauncher.launch(permissionsList.toTypedArray()) }) {
        Text(text = "Give permission", color = Color.White)
    }
}

Explanation: In the above code, I have used the registerForActivityResult() function to register the activity result.说明:在上面的代码中,我使用了registerForActivityResult() function 来注册活动结果。 The registerForActivityResult() function takes two parameters, the first one is the ActivityResultContracts.RequestMultiplePermissions() and the second one is the lambda function. The lambda function takes the Map<String, Boolean> as a parameter. registerForActivityResult() function 有两个参数,第一个是ActivityResultContracts.RequestMultiplePermissions()第二个是 lambda function。 lambda function 以Map<String, Boolean>为参数。 The Map<String, Boolean> contains the permission name as a key and the permission status as a value. Map<String, Boolean>包含作为键的权限名称和作为值的权限状态。 The permission status is true if the permission is granted and false if the permission is denied.如果授予权限,则权限状态为 true,如果拒绝权限,则为 false。


You can show the rational message when the user has denied the permission and the shouldShowRequestPermissionRationale() function returns true.当用户拒绝权限并且shouldShowRequestPermissionRationale() function 返回 true 时,您可以显示理性消息。 The shouldShowRequestPermissionRationale() function returns true if the user has denied the permission and the user has not selected the “Don't ask again” checkbox. shouldShowRequestPermissionRationale() function 如果用户拒绝了权限并且用户没有选中“不再询问”复选框,则返回 true。 The following code shows how to show the rational message.以下代码显示了如何显示理性消息。

if (ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.ACCESS_FINE_LOCATION
        ) == PackageManager.PERMISSION_GRANTED
    ) {
        // You can use the API that requires the permission.
    }
    else {
        if (ActivityCompat.shouldShowRequestPermissionRationale(
                this,
                Manifest.permission.ACCESS_FINE_LOCATION
            )
        ) {
            // You can show the rational message.
        } else {
            // You can directly ask for the permission.
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                1
            )
        }
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM