热门标签 | HotTags
当前位置:  开发笔记 > Android > 正文

Android5.0+屏幕录制实现的示例代码

这篇文章主要介绍了Android5.0+屏幕录制实现的示例代码,从5.0开始,系统提供给了app录制屏幕的一系列方法,不需要root权限,只需要用户授权即可录屏,相对来说较为简单,感兴趣的小伙伴们可以参考一下

前言

Android 从 4.0 开始就提供了手机录屏方法,但是需要 root 权限,比较麻烦不容易实现。但是从 5.0 开始,系统提供给了 app 录制屏幕的一系列方法,不需要 root 权限,只需要用户授权即可录屏,相对来说较为简单。本文是在参考了网络上其他录屏资料后完成的, 感谢 。以下将介绍开发录屏功能的一系列步骤以及实现过程中所遇到的一些需要注意的事项。

实现步骤

1、在清单文件中声明需要的权限

因为录制用到麦克风,所以需要加上 AUDIO 权限,



如果开发的 app targetApi 在 6.0 以上时,还需要动态获取权限。

public static void checkPermission(AppCompatActivity activity) {
  if (Build.VERSION.SDK_INT >= 23) {
   int checkPermission =
     ContextCompat.checkSelfPermission(activity, Manifest.permission.RECORD_AUDIO)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_PHONE_STATE)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)
       + ContextCompat.checkSelfPermission(activity, Manifest.permission.READ_EXTERNAL_STORAGE);
   if (checkPermission != PackageManager.PERMISSION_GRANTED) {
    //动态申请
    ActivityCompat.requestPermissions(activity, new String[]{
      Manifest.permission.RECORD_AUDIO,
      Manifest.permission.READ_PHONE_STATE,
      Manifest.permission.READ_EXTERNAL_STORAGE,
      Manifest.permission.WRITE_EXTERNAL_STORAGE}, 123);
    return;
   } else {
    return;
   }
  }
  return;
 }

2、获取用户录制屏幕授权

这里先介绍 MediaProjectionManager , MediaProjectionManager 是系统提供的一种服务,当我们拿到这个服务对象,可以创建一个 Intent ,通过这个 Intent 可以启动一个弹框样式的 Activity,如果用户授权了,那我们便可以继续下一步屏幕录制。需要说明的是,Intent 是去启动另一个 Activity 的,有极少极少的机型是没有对应的授权Activity 的,所以这里需要多加判断,防止应用奔溃。

MediaProjectionManager mediaProjectiOnManager= (MediaProjectionManager) activity.
       getSystemService(Context.MEDIA_PROJECTION_SERVICE);
     if (mediaProjectionManager != null){
      Intent intent = mediaProjectionManager.createScreenCaptureIntent();
      PackageManager packageManager = activity.getPackageManager();
      if (packageManager.resolveActivity(intent,PackageManager.MATCH_DEFAULT_ONLY) != null){
       //存在录屏授权的Activity 
       activity.startActivityForResult(intent,requestCode);
      }else {
       Toast.makeText(activity,R.string.can_not_record_tip,Toast.LENGTH_SHORT).show();
      }
     }

3、在 onActivityResult 对用户的授权做处理

即使用户授权了,同意录制操作,仍然需要捕获异常,因为有可能会出现这样一种情况,就是用户在同意录屏的时候系统也正在录屏,录屏操作冲突了。

@Override
 protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK){
   try {
    ScreenUtil.setUpData(resultCode,data);
   } catch (Exception e) {
    e.printStackTrace();
   }
  } else {
   ToastUtil.show(this,"拒绝录屏");
  }
 }

4、初始化 MediaRecorder、创建 VirtualDisplay

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
 private void setUpMediaRecorder() {

  mRecordFilePath = getSaveDirectory() + File.separator+ System.currentTimeMillis() + ".mp4";
  if (mMediaRecorder == null){
   mMediaRecorder = new MediaRecorder();
  }
  //设置音频来源
  mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
  //设置视频来源
  mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
  //输出的录屏文件格式
  mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
  //录屏文件路径
  mMediaRecorder.setOutputFile( mRecordFilePath );
  //视频尺寸
  mMediaRecorder.setVideoSize(mRecordWidth, mRecordHeight);
  //音视频编码器
  mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
  mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
  //比特率
  mMediaRecorder.setVideoEncodingBitRate((int) (mRecordWidth * mRecordHeight * 3.6));
  //视频帧率
  mMediaRecorder.setVideoFrameRate(20);

  try {
   mMediaRecorder.prepare();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }

这一步是整个录屏操作最为关键的一步!我们初始化了 MediaRecorder,设置了是否录上声音、录屏文件格式、录屏文件路径、音视频的编码器、比特率、视频帧率等

然后将在步骤 3 中的 resultCode 以及 data 作为必要的参数通过 MediaProjectionManager 创建 VirtualDisplay。VirtualDisplay 可以理解为虚拟的呈现器,它可以捕获屏幕上的内容,并将其捕获的内容渲染到 Surface 上(Surace 由 MediaRecorder 提供,通过 getSurface() 方法得到),MediaRecorder 再进一步将其封装处理为 Mp4 文件。

经过以上步骤 prepare 之后,当再次调用 MediaRecorder.start() 就可以开始录屏了,这里同意也需要注意的时,调用 start() 方法开始录屏之后,不能立即调用 stop()方法停止录屏,否则会奔溃。测试在测试录屏功能时立马停止录屏,应用奔溃,一直找不到原因。直到看到了源码( API 26 )里的注释

所以为了反正奔溃,在 stop 的时候捕获异常,并且置空 MediaRecorder,下次录屏的时候再重新生成 MediaRecorder。

最后

由于知识水平有限,难免有错误遗漏,欢迎指正!项目地址为 屏幕录制

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。


推荐阅读
  • 深度兴趣网络在点击率预测中的应用研究
    本文探讨了一种名为深度兴趣网络(Deep Interest Network, DIN)的新方法,该方法通过捕捉用户的历史行为和当前上下文之间的交互来提高点击率预测的准确性。DIN模型不仅考虑了用户的静态偏好,还动态地调整了对不同商品的兴趣权重,从而实现了更加个性化的推荐。 ... [详细]
  • Only2 Labs 是一家专注于视觉设计的工作室,如果您对当前的设计感到不满,或者急需寻找一个可靠的设计合作伙伴,甚至是您的团队项目需要专业指导,Only2 Labs 都将竭诚为您提供帮助。 ... [详细]
  • 本文探讨了HDU 4035的问题,涉及一个由n个房间组成的迷宫,这些房间通过n-1条隧道相互连接,形成一棵树结构。任务是从起点1号房间出发,计算到达出口所需经过的平均隧道数量,考虑了在每个房间中可能发生的三种情况及其相应概率。 ... [详细]
  • 本文探讨了在iOS应用中实现类似Android Snack Bar功能的方法,并特别关注如何确保Snack Bar正确显示在键盘下方。 ... [详细]
  • SQL注入实验:SqliLabs第38至45关解析
    本文深入探讨了SqliLabs项目中的第38至45关,重点讲解了堆叠注入(Stacked Queries)的应用技巧及防御策略。通过实际案例分析,帮助读者理解如何利用和防范此类SQL注入攻击。 ... [详细]
  • KKCMS代码审计初探
    本文主要介绍了KKCMS的安装过程及其基本功能,重点分析了该系统中存在的验证码重用、SQL注入及XSS等安全问题。适合初学者作为入门指南。 ... [详细]
  • 使用Inno Setup将EXE与JRE封装为Windows安装程序
    本文详细介绍了如何利用Inno Setup工具将EXE文件及Java运行环境(JRE)整合为适用于Windows操作系统的安装程序。我们将提供必要的软件下载链接,并逐步指导您完成整个打包过程。 ... [详细]
  • 本文探讨了为何采用RESTful架构及其优势,特别是在现代Web应用开发中的重要性。通过前后端分离和统一接口设计,RESTful API能够提高开发效率,支持多种客户端,并简化维护。 ... [详细]
  • 本文提供了中国三大主要通信运营商(中国联通、中国电信和中国移动)的官方邮箱服务网站链接,帮助用户快速访问并管理个人邮件,同时介绍了如何设置短信提醒功能。 ... [详细]
  • Linux环境下Memcached安装指南
    本文详细介绍如何在Linux虚拟机上安装Memcached,包括必要的依赖库安装,以及使用Xshell进行文件传输的具体步骤。 ... [详细]
  • 使用Adobe Illustrator打造独特的家族徽章:牡鹿图腾设计教程
    本文详细介绍了一种基于《权力的游戏》灵感,运用Adobe Illustrator创作独特家族图腾——牡鹿徽章的方法。本教程不仅展示了具体的步骤,还提供了多种技巧,帮助读者创作出既具个人特色又符合设计原则的作品。 ... [详细]
  • 本文探讨了Windows Presentation Foundation (WPF)如何通过扩展Microsoft Build Engine (MSBuild)来增强其构建能力,特别是在处理WPF特有的任务时。 ... [详细]
  • CGroups: 资源管理和控制
    CGroups(Control Groups)是Linux内核提供的一个功能,旨在限制、记录和隔离进程组使用的物理资源,如CPU、内存和I/O等。它通过精细的资源管理,支持现代容器技术如Docker的资源限制需求。 ... [详细]
  • 本文介绍了Android中常见的动画类型及其应用场景,通过具体的代码示例展示了如何在Activity跳转时添加平滑过渡效果,提升用户体验。 ... [详细]
  • 本文介绍了如何在 Linux 系统上构建网络路由器,特别关注于使用 Zebra 软件实现动态路由功能。通过具体的案例,展示了如何配置 RIP 和 OSPF 协议,以及如何利用多路由器查看工具(MRLG)监控网络状态。 ... [详细]
author-avatar
lifetime8_797
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有