-
添加权限和服务声明
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
相关推荐
每次的天空7 小时前
Android学习总结之算法篇四(字符串)x-cmd8 小时前
[250331] Paozhu 发布 1.9.0:C++ Web 框架,比肩脚本语言 | DeaDBeeF 播放器发布 1.10.0tangweiguo0305198711 小时前
Android BottomNavigationView 完全自定义指南:图标、文字颜色与选中状态遥不可及zzz12 小时前
Android 应用程序包的 adb 命令无知的前端13 小时前
Flutter 一文精通Isolate,使用场景以及示例_一条咸鱼_13 小时前
Android Compose 入门之字符串与本地化深入剖析(五十三)ModestCoder_14 小时前
将一个新的机器人模型导入最新版isaacLab进行训练(以unitree H1_2为例)robin_suli14 小时前
Spring事务的传播机制鸿蒙布道师15 小时前
鸿蒙NEXT开发对象工具类(TS)Harrison_zhu16 小时前
Ubuntu18.04 编译 Android7.1代码报错