繁体   English   中英

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

[英]Bluetooth Permission not working correctly in jetpack compose

我在我的项目中使用com.google.accompanist:accompanist-permissions:0.25.1 我正在尝试在请求的运行时请求蓝牙权限。 我想知道用户如何知道权限被永久禁用。

清单.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>

主活动.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)
    }
}

我的 3 when 语句在用户第一次安装应用程序时运行。 那么我该如何正确处理..

尝试:

// 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)
    }
}

说明:在上面的代码中,我使用了registerForActivityResult() function 来注册活动结果。 registerForActivityResult() function 有两个参数,第一个是ActivityResultContracts.RequestMultiplePermissions()第二个是 lambda function。 lambda function 以Map<String, Boolean>为参数。 Map<String, Boolean>包含作为键的权限名称和作为值的权限状态。 如果授予权限,则权限状态为 true,如果拒绝权限,则为 false。


当用户拒绝权限并且shouldShowRequestPermissionRationale() function 返回 true 时,您可以显示理性消息。 shouldShowRequestPermissionRationale() function 如果用户拒绝了权限并且用户没有选中“不再询问”复选框,则返回 true。 以下代码显示了如何显示理性消息。

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