Android开发,动态请求权限(activate和fragment)

以请求一个保存图片的权限为例。

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

1.在AndroidMainfest文件中添加上面代码块内的权限

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.gallery">
    <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.Light.DarkActionBar">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

2.事件监听,弹出申请权限对话框

//保存图片事件, 动态申请权限
saveButton.setOnClickListener{
    if (Build.VERSION.SDK_INT < 29 && ContextCompat.checkSelfPermission(
            requireContext(),
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        ) != PackageManager.PERMISSION_GRANTED
    ) { 
    	//没有权限,弹出一个请求权限对话框
        requestPermissions(arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE), 1)
    } else { 
    	//已有权限,处理事件
        viewLifecycleOwner.lifecycleScope.launch {
            //lifecycleScope使协程的生命周期随着activity的生命周期变化
            savePhoto()
        }
    }
}

3.回调结果,用户是否允许使用权限

在类中,重载onRequestPermissionsResult函数

//请求权限对话框处理
override fun onRequestPermissionsResult(
    requestCode: Int,
    permissions: Array<out String>,
    grantResults: IntArray
) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    //处理返回结果
    when (requestCode) {
        1 -> {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //权限通过,执行事件
                viewLifecycleOwner.lifecycleScope.launch {
                    //lifecycleScope使协程的生命周期随着activity的生命周期变化
                    savePhoto()
                }
            } else {
                //用户不允许使用该权限,失败提示
                Toast.makeText(requireContext(), "存储失败", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

2020.3.7号更新:

  • 在Fragment中申请权限,不要使用ActivityCompat.requestPermissions, 直接使用Fragment的requestPermissions方法,否则会回调到Activity的onRequestPermissionsResult
  • 如果在Fragment中嵌套Fragment,在子Fragment中使用requestPermissions方法,onRequestPermissionsResult不会回调回来,建议使用getParentFragment().requestPermissions方法,
    这个方法会回调到父Fragment中的onRequestPermissionsResult,加入以下代码可以把回调透传到子Fragment
  • 参考链接:https://www.jianshu.com/p/b4a8b3d4f587

代码如下:

package com.example.image.vision

import android.Manifest
import android.content.pm.PackageManager
.....
import java.util.concurrent.TimeUnit

private const val REQUEST_CODE_PERMISSIONS = 10 // 权限标识符
private val REQUIRED_PERMISSIONS = arrayOf(Manifest.permission.CAMERA) // 相机权限

class CameraXFragment : Fragment() {

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View? {
        return inflater.inflate(R.layout.camera_x_fragment, container, false)
    }

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

        // 检查是否拥有权限
        if (allPermissionsGranted()) {
            Log.v(CameraXFragment::class.java.simpleName, "已有权限,执行")
            textureView.post { startCamera() }
        } else {
            Log.v(CameraXFragment::class.java.simpleName, "没有权限,请求权限")
            requestPermissions(REQUIRED_PERMISSIONS, REQUEST_CODE_PERMISSIONS)
        }
    }

    // 请求权限,结果回调
    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<String>, grantResults: IntArray
    ) {
        Log.v(CameraXFragment::class.java.simpleName, "执行回调结果")
        if (requestCode == REQUEST_CODE_PERMISSIONS) {
            if (allPermissionsGranted()) {
                textureView.post { startCamera() }
            } else {
                Toast.makeText(
                    requireContext(),
                    "Permissions not granted by the user.",
                    Toast.LENGTH_SHORT
                ).show()
                // 这里应该是返回上一层,或者跳转到该页面的时候,就先判断有没有权限
                activity?.finish()
            }
        }
    }

    // 检查是否权限,已有权限,返回true
    private fun allPermissionsGranted() = REQUIRED_PERMISSIONS.all {
        ContextCompat.checkSelfPermission(
            requireContext(), it
        ) == PackageManager.PERMISSION_GRANTED
    }
}

你可能感兴趣的:(Android)