You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在自定义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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 03:46:00