如何将Android相机运行时权限逻辑拆分至多个文件
拆分Android相机运行时权限逻辑到多个文件的方案
我来帮你把相机权限的运行时逻辑拆分成更清晰的多个文件,这样代码结构更整洁,也方便后续复用。咱们可以按照「常量定义+扩展函数+权限助手类+业务Activity」的方式来拆分:
1. 权限常量统一管理:PermissionConstants.kt
先把权限相关的常量单独抽出来,避免硬编码,方便后续维护:
package com.example.hasan.runtime.feature.constants import android.Manifest object PermissionConstants { const val PERMISSION_REQUEST_CAMERA = 0 val CAMERA_PERMISSION = Manifest.permission.CAMERA }
2. Context权限扩展函数:PermissionExtensions.kt
把权限检查、请求、合理性提示这些通用逻辑封装成Context的扩展函数,让调用更简洁:
package com.example.hasan.runtime.feature.extensions import android.content.Context import android.content.pm.PackageManager import android.support.v4.app.ActivityCompat import android.support.v4.content.ContextCompat import android.support.design.widget.Snackbar import android.view.View // 检查权限是否已授予 fun Context.isPermissionGranted(permission: String): Boolean { return ContextCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED } // 请求权限(需在Activity中调用) fun Context.requestPermission(permission: String, requestCode: Int) { ActivityCompat.requestPermissions(this as android.app.Activity, arrayOf(permission), requestCode) } // 判断是否需要显示权限申请的合理性提示 fun Context.shouldShowPermissionRationale(permission: String): Boolean { return ActivityCompat.shouldShowRequestPermissionRationale(this as android.app.Activity, permission) } // View的Snackbar扩展函数 fun View.showSnackbar( messageResId: Int, duration: Int, actionResId: Int? = null, action: (() -> Unit)? = null ) { val snackbar = Snackbar.make(this, messageResId, duration) actionResId?.let { action?.let { act -> snackbar.setAction(it) { act() } } } snackbar.show() }
3. 相机权限助手类:CameraPermissionHelper.kt
把相机权限的具体请求逻辑、回调处理封装成单独的助手类,让Activity不用处理这些细节:
package com.example.hasan.runtime.feature.helpers import android.app.Activity import android.widget.Toast import com.example.hasan.runtime.feature.constants.PermissionConstants import com.example.hasan.runtime.feature.extensions.isPermissionGranted import com.example.hasan.runtime.feature.extensions.requestPermission import com.example.hasan.runtime.feature.extensions.shouldShowPermissionRationale import com.example.hasan.runtime.feature.extensions.showSnackbar class CameraPermissionHelper(private val activity: Activity, private val layout: android.view.View) { // 处理相机权限逻辑,传入权限通过后的回调 fun handleCameraPermission(onPermissionGranted: () -> Unit) { when { activity.isPermissionGranted(PermissionConstants.CAMERA_PERMISSION) -> { layout.showSnackbar( R.string.camera_permission_available, Snackbar.LENGTH_INDEFINITE, R.string.ok ) { onPermissionGranted() } } activity.shouldShowPermissionRationale(PermissionConstants.CAMERA_PERMISSION) -> { // 显示权限必要性的提示,引导用户授权 layout.showSnackbar( R.string.camera_permission_rationale, Snackbar.LENGTH_INDEFINITE, R.string.grant_permission ) { activity.requestPermission( PermissionConstants.CAMERA_PERMISSION, PermissionConstants.PERMISSION_REQUEST_CAMERA ) } } else -> { // 首次请求权限 activity.requestPermission( PermissionConstants.CAMERA_PERMISSION, PermissionConstants.PERMISSION_REQUEST_CAMERA ) } } } // 处理权限请求的回调 fun onRequestPermissionsResult(requestCode: Int, grantResults: IntArray): Boolean { if (requestCode == PermissionConstants.PERMISSION_REQUEST_CAMERA) { if (grantResults.isNotEmpty() && grantResults[0] == android.content.pm.PackageManager.PERMISSION_GRANTED) { Toast.makeText(activity, "相机权限已授予", Toast.LENGTH_SHORT).show() return true } else { Toast.makeText(activity, "相机权限被拒绝,无法使用相机功能", Toast.LENGTH_SHORT).show() return false } } return false } }
4. 简化后的MainActivity.kt
现在MainActivity只需要专注业务逻辑,权限相关的事情交给助手类处理:
package com.example.hasan.runtime.feature import android.os.Bundle import android.support.v7.app.AppCompatActivity import android.widget.Toast import com.example.hasan.runtime.feature.constants.PermissionConstants import com.example.hasan.runtime.feature.helpers.CameraPermissionHelper import kotlinx.android.synthetic.main.activity_main.* class MainActivity : AppCompatActivity() { private lateinit var cameraPermissionHelper: CameraPermissionHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) cameraPermissionHelper = CameraPermissionHelper(this, main_layout) btn_cam.setOnClickListener { showCamera() } } private fun showCamera() { cameraPermissionHelper.handleCameraPermission { startCamera() } } private fun startCamera() { // 这里可以替换成实际启动相机的逻辑 Toast.makeText(this, "权限通过,准备启动相机", Toast.LENGTH_LONG).show() } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if (cameraPermissionHelper.onRequestPermissionsResult(requestCode, grantResults)) { // 如果权限被授予,直接启动相机 startCamera() } } }
这样拆分后,代码结构更清晰:
- 常量统一管理,避免硬编码错误
- 扩展函数可以在整个项目中复用
- 权限助手类封装了所有相机权限的逻辑,Activity只需要关注业务
- 后续如果要添加其他权限(比如存储),只需要新增对应的Helper类即可
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

