3

如何使用导航组件管理权限请求代码?

我引用了太多的网站和堆栈链接,但都不起作用,仍然显示已弃用的 Waring 在此处输入图像描述

谷歌参考链接: https ://developer.android.com/training/permissions/requesting#manage-request-code-yourself

代码::在片段中使用以下代码

  private fun checkMultiplePermissions() {
        // check permission first
        if (ActivityCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // request the permission
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)
        } else {
            proceedAfterPermission()  // has the permission.
        }
    }
    override fun onRequestPermissionsResult(requestCode: Int,
                                            permissions: Array<String>, grantResults: IntArray) {
        myLog("log", "location code : $requestCode")
        when (requestCode) {
            100 -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted.
                    proceedAfterPermission() // permission was granted.
                    myLog("log", "location granted")
                } else {
                    // permission denied.
                    myLog("log", "location denied")
                }
                return
            }
        }
    }

Fragment.kt:完整代码

import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.core.content.ContextCompat
import androidx.fragment.app.Fragment

class FragmentPermission : Fragment() {
    private var binding: FragmentPermisionBinding ?= null

    // Kotlin
    //implementation "androidx.fragment:fragment-ktx:1.3.4"

    //https://developer.android.com/training/permissions/requesting#manage-request-code-yourself

    //    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        binding = FragmentPermisionBinding.inflate(inflater, container, false)


        if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // request the permission
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)
        } else {
            //proceedAfterPermission()  // has the permission.
        }
        
        
        return binding!!.root
    }


    override fun onRequestPermissionsResult(requestCode: Int,
                                            permissions: Array<String>, grantResults: IntArray) {
        myLog("location3", "location code : $requestCode")
        when (requestCode) {
            100 -> {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    // permission was granted.
                    //proceedAfterPermission() // permission was granted.
                    myLog("location3", "location granted")
                } else {
                    // permission denied.
                    myLog("location3", "location denied")
                }
                return
            }
        }
    }

    override fun onDestroyView() {
        super.onDestroyView()
        binding=null
    }
}
4

3 回答 3

5
requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), 100)

此方法已弃用。使用 registerForActivityResult(ActivityResultContract, ActivityResultCallback) 为 ActivityResultContract 传入一个 ActivityResultContracts.RequestMultiplePermissions 对象并在回调中处理结果。

requestPermissions()API 已弃用,取而代之的是 registerForActivityResult(ActivityResultContract, ActivityResultCallback)传入一个ActivityResultContracts.RequestMultiplePermissions对象ActivityResultContract并在回调中处理结果。

首先,新 API 需要activity-ktx模块级别的依赖项: build.gradle

implementation 'androidx.activity:activity-ktx:1.3.0-beta01'

然后ActivityResultCallback需要实现回调并作为registerForActivityResult. 此接口具有处理用户对权限请求对话框的响应的回调。

要显示权限对话框,请在函数返回launch()的实例上调用方法。ActivityResultLauncherregisterForActivityResult

因此,创建一个ActivityResultLauncher& 实现回调的实例来处理用户响应:

private val requestPermission =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        
        if (isGranted) { // Do something if permission granted
            Log.d("LOG_TAG", "permission granted by the user")

        } else { // Do something as the permission is not granted
            Log.d("LOG_TAG", "permission denied by the user")
        }
    }

然后使用launch函数请求权限:

if (ContextCompat.checkSelfPermission(
        requireContext(),
        Manifest.permission.ACCESS_FINE_LOCATION
    ) != PackageManager.PERMISSION_GRANTED
) {
    requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}

更新

一次请求多个权限:您需要将权限数组传递给launch()。ActivityResultCallback返回 aMap<String, Boolean>以权限为键,其授权状态为值:

然后使用ActivityResultContracts.RequestMultiplePermissions()如下:

private val requestMultiplePermissions =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        permissions.entries.forEach {
            Log.e("LOG_TAG", "${it.key} = ${it.value}")
        }
    }

// Usage:
requestMultiplePermissions.launch(
    arrayOf(
        Manifest.permission.READ_CONTACTS,
        Manifest.permission.ACCESS_FINE_LOCATION,
        Manifest.permission.CAMERA
    )
)

将其应用于共享代码:

class FragmentPermission : Fragment() {
    private var binding: FragmentPermisionBinding ?= null

    //...
    
    private val requestPermission =
    registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        
        if (isGranted) { // permission is granted

            proceedAfterPermission()
            
        } else { 
            // handle permission denial 
        }
    }


    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?): View {
        binding = FragmentPermisionBinding.inflate(inflater, container, false)


    if (ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.ACCESS_FINE_LOCATION
        ) != PackageManager.PERMISSION_GRANTED
    ) {
        requestPermission.launch(Manifest.permission.ACCESS_FINE_LOCATION)
    } else {
        proceedAfterPermission()
    }      
        
        return binding!!.root
    }

//.... rest of your code

}
于 2021-06-12T01:23:30.330 回答
0

您缺少为以下功能传递参数活动

 public static void requestPermissions(final @NonNull Activity activity,
            final @NonNull String[] permissions, final @IntRange(from = 0) int requestCode)

如果不请求许可,请检查您是否已经获得许可。 在下面的代码中,您需要传递您的活动。

            if (ContextCompat.checkSelfPermission(
                    this.applicationContext,
                    Manifest.permission.ACCESS_FINE_LOCATION
                )
                == PackageManager.PERMISSION_GRANTED
            ) {
//already you have permission
            } else {
                ActivityCompat.requestPermissions(
                    this, arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                    PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION
                )
            }

要获得用户响应,请使用此功能。

    /**
     * Handles the result of the request for location permissions.
     */
    override fun onRequestPermissionsResult(
        requestCode: Int,
        permissions: Array<String>,
        grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        mLocationPermissionGranted = false
        when (requestCode) {
            PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION -> {

                // If request is cancelled, the result arrays are empty.
                if (grantResults.size > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED
                ) {
// user granted location call your function
                }
            }
        }
    }
于 2021-06-18T07:55:53.550 回答
0

带有 NavContoller 的 PermissionFragment。科特林。

class PermissionFragment : Fragment() {
private val PERMISSIONS_REQUIRED = arrayOf(
    Manifest.permission.CAMERA,
    Manifest.permission.NFC,
    Manifest.permission.ACCESS_FINE_LOCATION,
    Manifest.permission.ACCESS_COARSE_LOCATION
)
private var _binding: FragmentPermissionBinding? = null
private val binding get() = _binding!!

private val requestMultiplePermissions =
    registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { permissions ->
        permissions.entries.forEach {
            val granted = it.value
            val permission = it.key
            if (!granted) {

                val neverAskAgain = !ActivityCompat.shouldShowRequestPermissionRationale(
                    requireActivity(),
                    permission
                )
                if (neverAskAgain) {
                    //user click "never ask again"
                } else {
                    //show explain dialog
                }
                return@registerForActivityResult
            }
        }
        goHome()
    }

override fun onCreateView(
    inflater: LayoutInflater,
    container: ViewGroup?,
    savedInstanceState: Bundle?
): View? {
    _binding = FragmentPermissionBinding.inflate(inflater, container, false)
    return binding.root
}

override fun onViewStateRestored(savedInstanceState: Bundle?) {
    super.onViewStateRestored(savedInstanceState)

    /*don't call this in onCreateView(), NavController has not been created yet
    *
    * don't call this in onResume(), if user selected "never ask again" - checkAppPermission() can go to dead loop after dialog show */
    checkAppPermission()
}

private fun checkAppPermission() {
    PERMISSIONS_REQUIRED.forEach { permission ->
        if (ContextCompat.checkSelfPermission(requireContext(), permission) ==
            PackageManager.PERMISSION_DENIED
        ) {
            requestMultiplePermissions.launch(PERMISSIONS_REQUIRED)
            return
        }
    }
    goHome()
}

private fun goHome() {
    val navController = requireActivity().findNavController(R.id.nav_host_fragment_content_main)
    navController.navigate(R.id.nav_home)
}

}

于 2021-12-04T15:52:42.863 回答