Android Permission 权限申请,EasyPermission和其他三方库

在Android的实际开发中,经常会因为需求的实现,需要申请用户权限。

今天总结下Android中常用的权限申请。

一、基本介绍和流程

Android中的权限申请是通过应用程序与操作系统之间的交互实现的。在Android中,每个应用程序都被赋予了一组预定义的权限,这些权限定义了应用程序可以执行的操作范围,例如访问摄像头、读取联系人、发送短信等。

当应用程序需要执行需要特定权限的操作时,它必须在运行时向操作系统请求这些权限。以下是Android中的权限申请流程:

  1. 权限声明:在应用程序的清单文件(AndroidManifest.xml)中,开发者需要声明应用程序所需的权限。这些权限声明描述了应用程序需要的访问级别。例如,如果应用程序需要访问设备的摄像头,开发者需要在清单文件中声明相应的权限。

  2. 运行时权限请求:对于一些敏感权限(如访问设备位置、读取联系人等),Android要求应用程序在运行时动态请求这些权限。当应用程序需要执行需要特定权限的操作时,它会向操作系统发起权限请求。

  3. 用户授权:当应用程序发起权限请求时,操作系统会弹出一个对话框,显示权限请求的详细信息,并询问用户是否同意授予该权限。用户可以选择允许或拒绝权限请求。

  4. 权限回调:一旦用户对权限请求做出了响应,系统会将结果通知给应用程序。应用程序可以处理用户的授权结果并相应地执行相应操作。这通常涉及检查权限是否被授予,如果权限被拒绝,则可以采取其他适当的行动。

二、简单的实现 相机和文件读写权限

manifest文件:

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

kotlin核心方法:

companion object {
        private const val RC_CAMERA_AND_LOCATION = 123
        const val PERMISSION_REQUEST_CODE = 100
    }
//在onCreate里定义一个按钮添加点击事件
normal.setOnClickListener {
            // 请求相机和文件读写权限
            if (checkPermissions()) {//检查权限
                //返回true 则进行接下来的逻辑
                ToastUtils.showShort("已经获得权限normal")
            } else {
                //没有权限,申请权限
                requestPermissions()
            }
        }


    private fun requestPermissions() {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(
                Manifest.permission.CAMERA,
                Manifest.permission.WRITE_EXTERNAL_STORAGE
            ),
            PERMISSION_REQUEST_CODE
        )
    }

    private fun checkPermissions(): Boolean {
        val cameraPermission = ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.CAMERA
        )
        val storagePermission = ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.WRITE_EXTERNAL_STORAGE
        )
        return cameraPermission == PackageManager.PERMISSION_GRANTED &&
                storagePermission == PackageManager.PERMISSION_GRANTED
    }
//权限申请回掉
 override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == PERMISSION_REQUEST_CODE) {
            var allPermissionsGranted = true
            for (result in grantResults) {
                if (result != PackageManager.PERMISSION_GRANTED) {
                    allPermissionsGranted = false
                    break
                }
            }
            if (allPermissionsGranted) {
                //进行
            } else {
                // 权限未授予,可以执行一些其他操作,如显示权限被拒绝的提示信息等
                Log.d(TAG, "Permissions denied")
            }
        }
}

这是自己实现的,很简单,检查权限,请求权限和权限回调全是用的系统的方法。但是现在的权限申请拒绝了的时候,很多手机会默认不在询问,导致用户一次拒绝过后,第二次进来,我们再次请求权限时用户根本不会看见权限授权弹窗,得写个方法去打开用户手机系统的权限设置页才行。

思来想去,偷个懒吧,用三方库

三、EasyPermissions

emmmm,实现起来很简单

1.build.gradle配置三方库(app下的)

dependencies {
    // For developers using AndroidX in their applications
    implementation 'pub.devrel:easypermissions:3.0.0'
 
    // For developers using the Android Support Library
    implementation 'pub.devrel:easypermissions:2.0.1'
}

2.业务代码(很简单,照着官方文档走就是了)

优点就是方便,且权限被拒绝后,下次申请回弹窗,用户点击后跳转设置页




class MainActivity : AppCompatActivity(), EasyPermissions.PermissionCallbacks {


    private lateinit var easyPermissionsTv: TextView
    private lateinit var permissionsDispatcherTv: TextView
    private lateinit var rxPermissionsTv: TextView
    private lateinit var dexterTv: TextView
    private lateinit var normal: TextView
    var perms =
        arrayOf(
            android.Manifest.permission.CAMERA,
            android.Manifest.permission.ACCESS_FINE_LOCATION
        )

    companion object {
        private const val RC_CAMERA_AND_LOCATION = 123
        const val PERMISSION_REQUEST_CODE = 100
    }


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        normal = findViewById(R.id.normalPermission)
        easyPermissionsTv = findViewById(R.id.EasyPermissions)
        permissionsDispatcherTv = findViewById(R.id.PermissionsDispatcher)
        dexterTv = findViewById(R.id.Dexter)
        rxPermissionsTv = findViewById(R.id.RxPermissions)


        easyPermissionsTv.setOnClickListener {
            requestCameraPermission()
        }

    }

    private fun requestCameraPermission() {
        if (EasyPermissions.hasPermissions(this, *perms)) {
            // 已经具有权限
            ToastUtils.showShort("已经获得权限")
            openCamera()
        } else {
            EasyPermissions.requestPermissions(
                PermissionRequest.Builder(this, RC_CAMERA_AND_LOCATION, *perms)
                    .setRationale("需要相机权限和位置权限")
                    .setPositiveButtonText("给")
                    .setNegativeButtonText("就不给")
                    .build()
            )
        }
    }

    @AfterPermissionGranted(RC_CAMERA_AND_LOCATION)
    private fun openCamera() {
        // 在此处执行打开相机的逻辑
    }

    override fun onRequestPermissionsResult(
        requestCode: Int, permissions: Array<out String>, grantResults: IntArray
    ) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

            //将结果转发到EasyPermissions
            EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this)

    }

    override fun onPermissionsGranted(requestCode: Int, perms: MutableList<String>) {
        ToastUtils.showShort("onPermissionsGranted")
    }

    override fun onPermissionsDenied(requestCode: Int, perms: MutableList<String>) {
        ToastUtils.showShort("onPermissionsDenied")
        if (EasyPermissions.somePermissionPermanentlyDenied(this, perms)) {
            AppSettingsDialog.Builder(this)
                .setRationale("老铁,没有相机权限和位置权限这事儿很难办啊")
                .setNegativeButton("就不给就不给")
                .setPositiveButton("给你给你给你")
                .build().show()
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == AppSettingsDialog.DEFAULT_SETTINGS_REQ_CODE) {
            ToastUtils.showShort("申请权限返回")
        }
    }
}

 关于文件读写权限,由于Android各个版本的异同,有些很烦的区别,且看stack overflow大神的讨论:

WRITE_EXTERNAL_STORAGE when targeting Android 10 - Stack Overflow

4、常用的权限申请框架

  1. EasyPermissions: EasyPermissions是一个轻量级的开源库,简化了Android权限申请的过程。它提供了简单的API,用于请求权限、处理权限回调和解释权限的目的。该库还支持批量请求权限和自定义权限弹窗。

  2. TedPermission: TedPermission是一个易于使用的权限申请库,它提供了简洁的API,并具有可自定义的权限弹窗。该库还支持批量请求权限和处理回调。

  3. RxPermissions: RxPermissions是一个基于RxJava的权限申请库,它提供了使用Observables的方式来请求和处理权限。这使得在响应式编程中更容易处理权限相关的操作。

  4. PermissionsDispatcher: PermissionsDispatcher是一个基于注解的权限申请库,它使用了Java注解处理器技术,通过生成相关代码来简化权限申请过程。使用该库,开发者可以在方法上添加注解来声明所需的权限,并自动生成相关的权限申请和回调代码。

  5. Dexter: Dexter是一个简单而灵活的权限申请库,它通过简洁的API和回调接口来处理权限请求和回调。该库还提供了自定义权限弹窗的功能。

开源库的链接我就不给了,自己去github搜一下,star数都很高,blankj的工具库里面其实也有PermissionUtils.

Android 中,应用程序需要向用户请求通知权限,以便能够在设备上显示通知。下面是一些步骤,可以帮助你申请通知权限: 1. 在 AndroidManifest.xml 文件中添加以下代码: ``` <uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> ``` 2. 在应用程序中请求通知权限。你可以使用以下代码: ``` if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); channel.setDescription(CHANNEL_DESCRIPTION); NotificationManager notificationManager = getSystemService(NotificationManager.class); notificationManager.createNotificationChannel(channel); } ``` 3. 显示通知。你可以使用以下代码: ``` NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.drawable.notification_icon) .setContentTitle("My notification") .setContentText("Hello World!") .setPriority(NotificationCompat.PRIORITY_DEFAULT); NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(notificationId, builder.build()); ``` 这些步骤应该可以帮助你申请通知权限并在应用程序中显示通知。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

&岁月不待人&

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值