-
添加权限和服务声明
xml<uses-permission android:name="android.permission.FOREGROUND_SERVICE" /> <service android:name=".ScreenService" android:enabled="true" android:exported="true" android:foregroundServiceType="mediaProjection"></service>
-
创建屏幕录制的 Service
kotlinimport android.app.* import android.content.Context import android.content.Intent import android.graphics.BitmapFactory import android.hardware.display.DisplayManager import android.hardware.display.VirtualDisplay import android.media.CamcorderProfile import android.media.MediaRecorder import android.media.projection.MediaProjection import android.media.projection.MediaProjectionManager import android.os.Build import android.os.IBinder import android.util.DisplayMetrics import android.util.Log import android.view.WindowManager import androidx.core.app.NotificationCompat import java.io.IOException class ScreenService : Service() { private var mContext:Context?=null private var projectionManager:MediaProjectionManager?=null private var mMediaProjection:MediaProjection?=null override fun onBind(intent: Intent): IBinder { TODO("Return the communication channel to the service.") } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { mContext = this var resultCode = intent?.getIntExtra("resultCode", -1) var path = intent?.getStringExtra("path") var resultData: Intent? = intent?.getParcelableExtra("data") startNotification(); projectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager mMediaProjection = resultCode?.let { resultData?.let { it1 -> projectionManager?.getMediaProjection(it, it1) } } path?.let { startRecording(it) } return super.onStartCommand(intent, flags, startId) } private var NOTIFICATION_CHANNEL_ID="id"; private var NOTIFICATION_CHANNEL_NAME="channel"; private var NOTIFICATION_CHANNEL_DESC="desc"; private fun startNotification() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { var notificationIntent = Intent(mContext, ScreenService::class.java) var pendingIntent: PendingIntent?=null pendingIntent = if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.S) { PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_IMMUTABLE); } else { PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_ONE_SHOT); } var notificationBuilder = mContext?.let { NotificationCompat.Builder(it, NOTIFICATION_CHANNEL_ID) .setLargeIcon(BitmapFactory.decodeResource(mContext!!.resources, R.drawable.ic_launcher_foreground)) .setSmallIcon(R.drawable.ic_launcher_foreground) .setContentTitle("start record") .setContentText("=== start record ===") .setContentIntent(pendingIntent) }; var notification = notificationBuilder?.build(); var channel = NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationManager.IMPORTANCE_DEFAULT); channel.description = NOTIFICATION_CHANNEL_DESC; var notificationManager = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager notificationManager.createNotificationChannel(channel) startForeground(1, notification); } } private var isScreenRecoding = false private var mMediaRecorder: MediaRecorder?=null private var mVirtualDisplay: VirtualDisplay? = null private fun startRecording(filePath:String) { if (!isScreenRecoding){ try { // 创建 MediaRecorder 并设置参数 val metrics = DisplayMetrics() val windowManager: WindowManager = mContext?.getSystemService(WINDOW_SERVICE) as WindowManager windowManager.defaultDisplay.getMetrics(metrics) mMediaRecorder = MediaRecorder() mMediaRecorder?.setVideoSource(MediaRecorder.VideoSource.SURFACE) mMediaRecorder?.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4) mMediaRecorder?.setOutputFile(filePath) mMediaRecorder?.setVideoSize(metrics.widthPixels, metrics.heightPixels) mMediaRecorder?.setVideoEncoder(MediaRecorder.VideoEncoder.H264) mMediaRecorder?.setVideoEncodingBitRate(1920*1080 * 3) mMediaRecorder?.setVideoFrameRate(30) // 准备 MediaRecorder mMediaRecorder?.prepare() // 创建 VirtualDisplay 以获取屏幕内容 mVirtualDisplay = mMediaProjection?.createVirtualDisplay( "ScreenRecord", metrics.widthPixels, metrics.heightPixels, metrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mMediaRecorder?.surface, null, null ) // 开始录制 mMediaRecorder?.start() isScreenRecoding = true Log.i(ScreenUtil.TAG,"开始录屏 $filePath") } catch (e: IOException) { Log.e(ScreenUtil.TAG, "录屏失败: " + e.message) e.printStackTrace() } } } public fun stopRecording() { if (isScreenRecoding) { try { // 停止录制 mMediaRecorder?.stop() mMediaRecorder?.reset() mMediaRecorder?.release() mMediaRecorder = null // 停止 VirtualDisplay mVirtualDisplay?.release() // 停止 MediaProjection mMediaProjection?.stop() Log.i(ScreenUtil.TAG,"结束录屏") } catch (e: Exception) { Log.e(ScreenUtil.TAG, "停止录屏失败: " + e.message) e.printStackTrace() } isScreenRecoding = false } } override fun onDestroy() { stopRecording() super.onDestroy() } }
-
启动和停止录制
kotlinprivate var mProjectionManager: MediaProjectionManager? = null var screenService:Intent?=null fun start(){ mProjectionManager = getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager // 请求录屏权限 startActivityForResult(mProjectionManager?.createScreenCaptureIntent(), 500); } fun stop(){ stopService(screenService) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) if (requestCode == 500){ screenService = Intent(mConext, ScreenService::class.java) screenService?.let { it.putExtra("resultCode", resultCode); it.putExtra("data", data); it.putExtra("path", "screen.mp4"); startForegroundService(it) } } }
Android 实现屏幕录制
菠萝加点糖2024-08-03 23:39
相关推荐
m0_548514773 小时前
2024.12.10——攻防世界Web_php_include凤邪摩羯3 小时前
Android-性能优化-03-启动优化-启动耗时凤邪摩羯3 小时前
Android-性能优化-02-内存优化-LeakCanary原理解析喀什酱豆腐4 小时前
Handlem0_748232925 小时前
Android Https和WebViewm0_748251725 小时前
Android webview 打开本地H5项目(Cocos游戏以及Unity游戏)m0_748254667 小时前
go官方日志库带色彩格式化zhangphil7 小时前
Android使用PorterDuffXfermode模式PorterDuff.Mode.SRC_OUT橡皮擦实现“刮刮乐”效果,Kotlin(2)爱学测试的李木子8 小时前
从0到1搭建 Android 自动化 python+appium 环境咸芝麻鱼8 小时前
Android Studio | 连接手机设备后,启动App时出现:Waiting For DebuggerApplication (App名)...