蓝牙权限在 jetpack compose 中无法正常工作

2024-05-27

我在用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>

MainActivity.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 语句在用户第一次安装应用程序时运行。那么我该如何正确处理..


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

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


当用户拒绝权限时,您可以显示合理的消息,并且shouldShowRequestPermissionRationale()函数返回真。这shouldShowRequestPermissionRationale()如果用户拒绝了权限并且用户未选中“不再询问”复选框,则函数返回 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
            )
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

蓝牙权限在 jetpack compose 中无法正常工作 的相关文章

随机推荐