如何在自定义Permission类中重写onRequestPermissionsResult而非MainActivity?
解决Permission类中处理权限请求结果的问题
你遇到的核心问题是onRequestPermissionsResult是Activity/Fragment的专属方法,没法直接在自定义的Permission类里重写。不过我们可以通过两种优雅的方式把权限回调逻辑封装到Permission类中,不用在MainActivity里写一堆处理代码:
方法一:使用Jetpack Activity Result API(推荐)
这是Android官方现在主推的权限请求方式,完全不需要重写onRequestPermissionsResult,直接把回调逻辑封装到Permission类里,代码更解耦。
步骤1:在Permission类中封装权限请求逻辑
import android.app.Activity import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.core.app.ActivityCompat class Permission(private val activity: Activity) { // 初始化权限请求Launcher private val requestPermissionLauncher: ActivityResultLauncher<String> = activity.registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> // 权限请求结果直接在这里处理! if (isGranted) { // 麦克风权限已授予,执行你的逻辑 onMicrophonePermissionGranted() } else { // 权限被拒绝,处理拒绝逻辑(比如提示用户去设置开启) onMicrophonePermissionDenied() } } fun askMicrophonePermission() { val permission = android.Manifest.permission.RECORD_AUDIO when { ActivityCompat.checkSelfPermission(activity, permission) == android.content.pm.PackageManager.PERMISSION_GRANTED -> { // 已经有权限,直接执行逻辑 onMicrophonePermissionGranted() } activity.shouldShowRequestPermissionRationale(permission) -> { // 需要向用户解释为什么需要这个权限 showPermissionRationale() } else -> { // 发起权限请求 requestPermissionLauncher.launch(permission) } } } // 可以把这些逻辑写成开放方法,让外部也能自定义,或者直接在内部实现 private fun onMicrophonePermissionGranted() { // 这里写权限授予后的逻辑,比如初始化麦克风 println("麦克风权限已授予") } private fun onMicrophonePermissionDenied() { // 这里写权限拒绝后的逻辑,比如弹出提示引导用户去设置开启 println("麦克风权限被拒绝") } private fun showPermissionRationale() { // 向用户解释权限用途,比如弹个Dialog println("需要麦克风权限来录制音频,请允许") } }
步骤2:在MainActivity中调用
class MainActivity : AppCompatActivity() { private lateinit var permissionManager: Permission override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) permissionManager = Permission(this) // 调用请求麦克风权限的方法 permissionManager.askMicrophonePermission() } }
这种方式的优点是:完全不用处理onRequestPermissionsResult,权限请求和结果处理都封装在Permission类里,MainActivity只需要调用方法即可,代码更干净。
方法二:使用接口回调(兼容旧版本)
如果你需要兼容AndroidX之前的版本,或者习惯用老的requestPermissions方法,可以通过定义一个回调接口,把Activity的onRequestPermissionsResult结果转发给Permission类处理。
步骤1:定义回调接口并封装Permission类
import android.app.Activity import android.content.pm.PackageManager import androidx.core.app.ActivityCompat class Permission(private val activity: Activity) { private val RECORD_AUDIO_REQUEST_CODE = 1001 private var permissionCallback: PermissionCallback? = null // 定义回调接口 interface PermissionCallback { fun onPermissionGranted() fun onPermissionDenied() } fun setPermissionCallback(callback: PermissionCallback) { this.permissionCallback = callback } fun askMicrophonePermission() { val permission = android.Manifest.permission.RECORD_AUDIO if (ActivityCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(activity, arrayOf(permission), RECORD_AUDIO_REQUEST_CODE) } else { permissionCallback?.onPermissionGranted() } } // 让Activity调用这个方法,把权限结果传过来 fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { if (requestCode == RECORD_AUDIO_REQUEST_CODE) { if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) { permissionCallback?.onPermissionGranted() } else { permissionCallback?.onPermissionDenied() } } } }
步骤2:在MainActivity中转发结果
class MainActivity : AppCompatActivity() { private lateinit var permissionManager: Permission override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) permissionManager = Permission(this) permissionManager.setPermissionCallback(object : Permission.PermissionCallback { override fun onPermissionGranted() { println("麦克风权限已授予") } override fun onPermissionDenied() { println("麦克风权限被拒绝") } }) // 调用请求权限 permissionManager.askMicrophonePermission() } // 必须重写这个方法,但只是把结果转发给Permission类,不用写业务逻辑 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) permissionManager.onRequestPermissionsResult(requestCode, permissions, grantResults) } }
这种方式需要在MainActivity里重写onRequestPermissionsResult,但只是做转发,业务逻辑还是在Permission类里,也能达到你的需求。
总结
推荐优先使用方法一的Activity Result API,因为它是官方推荐的现代写法,代码更简洁,不需要处理回调转发,而且能更好地和Jetpack组件集成。如果是旧项目需要兼容,再考虑方法二的接口回调方式。
内容的提问来源于stack exchange,提问作者Greg
相关产品推荐
相关产品推荐

