Android 权限申请分享

要求:

1.不用三方框架,减小安装包的大小

2.请求权限的时候,显示请求内容,配合应用市场上架要求

代码实现

调用的代码

kotlin 复制代码
//初始化
private val readLauncher = PermissionInfoLauncher(Manifest.permission.READ_CONTACTS) {
    "读取联系人".toast()
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    installSplashScreen()
    setContentView(binding.root)

    //注册
    lifecycle.addObserver(readLauncher)
    binding.btnReadContacts.setOnClickListener {
        //具体调用
        readLauncher.request(this)
    }
}

override fun onDestroy() {
    super.onDestroy()
    //解除绑定
    lifecycle.removeObserver(readLauncher)
}

核心实现类,其中 PermissionInfoDialog 、SettingPermissionDialog 是显示信息的弹框,跟设置的弹框,可以根据项目UI要求自行实现

注意Launcher 绑定,不能在OnCreate 中默认调用request,那时候Launcher还未初始化 如果遇到地图定位,在修改权限之后,还要重新自动定位,再加入

ini 复制代码
setLauncher = owner.registerForActivityResult(ActivityResultContracts.StartActivityForResult())

回调即可

kotlin 复制代码
class PermissionInfoLauncher(private val permission: String, private val function: () -> Unit) :
    DefaultLifecycleObserver {

    private lateinit var permissionLauncher: ActivityResultLauncher<String>

    @StringRes
    var infoRes: Int = R.string.permission_refuse_info_default

    @StringRes
    var setRes: Int = R.string.permission_set_default

    private val infoDialog: PermissionInfoDialog by lazy {
        PermissionInfoDialog.Builder().apply {
            content = CoreUtils.getApp().getString(infoRes)
        }.create()
    }

    override fun onCreate(owner: LifecycleOwner) {
        super.onCreate(owner)
        when (owner) {
            is FragmentActivity -> {
                permissionLauncher = owner.registerForActivityResult(ActivityResultContracts.RequestPermission()) { granted ->
                    infoDialog.dismiss()
                    if (granted) {
                        //处理业务逻辑
                        function()
                    } else {
                        val settingDialog = SettingPermissionDialog.Builder().apply {
                            content = owner.resources.getString(setRes)
                        }.create()
                        settingDialog.show(owner.supportFragmentManager)
                    }
                }
            }

            else -> {
                throw NullPointerException("${this.javaClass.name}观察的生命周期不是Activity或者Fragment")
            }
        }
    }

    override fun onDestroy(owner: LifecycleOwner) {
        super.onDestroy(owner)
        permissionLauncher.unregister()
    }

    fun request(activity: FragmentActivity) {
        infoDialog.show(activity.supportFragmentManager)
        if (::permissionLauncher.isInitialized) {
            permissionLauncher.launch(permission)
        }
    }
}
相关推荐
王码码203512 分钟前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
2501_9151063213 分钟前
app 上架过程,安装包准备、证书与描述文件管理、安装测试、上传
android·ios·小程序·https·uni-app·iphone·webview
vistaup29 分钟前
OKHTTP 默认构建包含 android 4.4 的TLS 1.2 以及设备时间不对兼容
android·okhttp
常利兵35 分钟前
ButterKnife在Android 35 + Gradle 8.+环境下的适配困境与现代化迁移指南
android
撩得Android一次心动35 分钟前
Android LiveData 全面解析:使用Java构建响应式UI【源码篇】
android·java·android jetpack·livedata
熊猫钓鱼>_>44 分钟前
移动端开发技术选型报告:三足鼎立时代的开发者指南(2026年2月)
android·人工智能·ios·app·鸿蒙·cpu·移动端
Rainman博11 小时前
WMS-窗口relayout&FinishDrawing
android
baidu_2474386113 小时前
Android ViewModel定时任务
android·开发语言·javascript
有位神秘人14 小时前
Android中Notification的使用详解
android·java·javascript
·云扬·14 小时前
MySQL Binlog落盘机制深度解析:性能与安全性的平衡艺术
android·mysql·adb