Bootstrap

Android 实现屏幕录制并剥离环境音量实现

Android 从 4.0 开始就提供了手机录屏方法,但是需要 root 权限,比较麻烦不容易实现。但是从 5.0 开始,系统提供给了 App 录制屏幕的一系列方法,不需要 root 权限,只需要用户授权即可录屏,相对来说较为简单。

基本上根据 官方文档 便可以写出录屏的相关代码。

屏幕录制的基本实现步骤
在 Manifest 中申明权限
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
获取 MediaProjectionManager 并申请权限
private val mediaProjectionManager by lazy {
    activity.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as? MediaProjectionManager }
private var mediaProjection: MediaProjection? = null
if (mediaProjectionManager == null) {
   
    Log.d(TAG, "mediaProjectionManager == null,当前手机暂不支持录屏")
    showToast(R.string.phone_not_support_screen_record)
    return
}
// 申请相关权限
PermissionUtils.permission(PermissionConstants.STORAGE, PermissionConstants.MICROPHONE)
        .callback(object : PermissionUtils.SimpleCallback {
   
            override fun onGranted() {
   
                Log.d(TAG, "start record")
                mediaProjectionManager?.apply {
   
                	// 申请相关权限成功后,要向用户申请录屏对话框
                    val intent = this.createScreenCaptureIntent()
                    if (activity.packageManager.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY) != null) {
   
                        activity.startActivityForResult(intent, REQUEST_CODE)
                    } else {
   
                        showToast(R.string.phone_not_support_screen_record)
                    }
                }
            }
            override fun onDenied() {
   
                showToast(R.string.permission_denied)
            }
        })
        .request()
重写 onActivityResult() 对用户授权进行处理
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
   
    if (requestCode == REQUEST_CODE) {
   
        if (resultCode == Activity.RESULT_OK) {
   
            mediaProjection = mediaProjectionManager!!.getMediaProjection(resultCode, data)
            // 实测,部分手机上录制视频的时候会有弹窗的出现,所以我们需要做一个 150ms 的延迟
            Handler().postDelayed({
   
                if (initRecorder()) {
   
                    mediaRecorder?.start()
                } else {
   
                    showToast(R.string.phone_not_support_screen_record)
                }
            }, 150)
        } else {
   
            showToast(R.string.phone_not_support_screen_record)
        }
    }
}

private fun initRecorder(): Boolean {
   
;