iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >Android 实现屏幕录制和截屏
  • 102
分享到

Android 实现屏幕录制和截屏

android截屏录屏 2023-08-18 17:08:48 102人浏览 独家记忆
摘要

在移动开发中,实现屏幕录制和截屏是常见的需求。对于 Android 应用而言,实现屏幕录制和截屏可以帮助开发者更好地测试和调试自己的应用,同时还能够提供一些特定场景下的用户体验。 屏幕录制 Android 应用程序可以通过使用 MediaP

移动开发中,实现屏幕录制和截屏是常见的需求。对于 Android 应用而言,实现屏幕录制和截屏可以帮助开发者更好地测试和调试自己的应用,同时还能够提供一些特定场景下的用户体验。

屏幕录制

Android 应用程序可以通过使用 MediaProjection api 来实现屏幕录制功能。使用此 API 可以获取指定屏幕的图像帧,并进行相关处理或保存为视频文件。

下面是一些简要的实现步骤:

  1. 获取 MediaProjection 对象:调用 MediaProjectionManager.createScreenCaptureIntent() 方法,启动屏幕捕获 Intent,并在 onActivityResult() 方法中获取 MediaProjection 对象。

  2. 创建虚拟显示器:使用 DisplayManager.createVirtualDisplay() 方法创建虚拟显示器,并将其与 MediaProjection 对象进行绑定。虚拟显示器将模拟真实屏幕并捕获图像帧。

  3. 获取屏幕截图:使用 MediaProjection.createVirtualDisplay() 的返回值创建 Surface 实例,并将其传递到 ImageReader.newInstance() 方法中,用于捕获指定屏幕的图像帧。

  4. 处理和编码每一帧图像:使用 ImageReader.acquireNextImage() 方法获取每一帧图像,并将其转换为 Bitmap 或 byte[] 形式。之后,可对图像进行自定义处理、压缩和编码操作,例如使用 MediaCodec 进行 H.264 编码等。

  5. 保存为视频文件:将每一帧图像数据按照音视频格式进行封装,写入 MP4 文件中。

需要注意的是,在 Android 5.0 以上版本中,启动屏幕捕获 Intent 需要授权,而且用户会受到屏幕被录制的通知。因此,要想隐藏通知,需要使用 SystemUI 系统应用程序或自己编写(需要 root 权限)。

在 Android 应用程序中实现屏幕录制,可以使用 MediaProjection API。具体实现步骤如下:

  1. 获取 MediaProjection 对象

在 Activity 中启动屏幕捕获 Intent,并在 onActivityResult() 方法中获取 MediaProjection 对象。

private static final int REQUEST_CODE = 1;private MediaProjectionManager mMediaProjectionManager;private MediaProjection mMediaProjection;private void startScreenCapture() {    mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);    startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {        mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);        startRecord();    }}
  1. 创建虚拟显示器

调用 MediaProjection.createVirtualDisplay() 方法创建一个虚拟显示器,该方法接受的参数包括显示器名称、显示器宽度、显示器高度、显示器 dpi、显示标识符等,并返回一个 VirtualDisplay 对象。

private static final int DISPLAY_FLAGS =        DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC |        DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |        DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR;private static final int RECORD_WIDTH = 1280;private static final int RECORD_HEIGHT = 720;private static final int RECORD_DPI = 320;private VirtualDisplay mVirtualDisplay;private void startRecord() {    // 创建 ImageReader 对象,用于从虚拟显示器中获取图像帧    ImageReader imageReader = ImageReader.newInstance(RECORD_WIDTH, RECORD_HEIGHT, PixelFORMat.RGBA_8888, 2);    // 创建虚拟显示器,指定虚拟显示器的名称、宽度、高度、dpi 等参数    mVirtualDisplay = mMediaProjection.createVirtualDisplay(            "ScreenCapture",            RECORD_WIDTH, RECORD_HEIGHT, RECORD_DPI,            DISPLAY_FLAGS,            imageReader.getSurface(), null, mHandler);}
  1. 从 ImageReader 中获取图像帧并编码

调用 ImageReader.acquireLatestImage() 方法从 ImageReader 对象中获取最新一帧的图像数据,并将其转换为 Bitmap 对象。然后使用 MediaCodec API 将 Bitmap 编码为 H.264 格式的视频流。

private static final String MIME_TYPE = "video/avc";private static final int FRAME_RATE = 30;private static final int I_FRAME_INTERVAL = 1;private static final int BIT_RATE = RECORD_WIDTH * RECORD_HEIGHT * 4 * 5; // 视频编码码率(比特率),计算方式参考 H.264 的标准private static final int TIMEOUT_US = 10000;private MediaCodec mEncoder;private Surface mSurface;private void startEncode() {    try {        // 创建 MediaCodec 对象,指定编码器类型、编码格式、采样率、比特率等参数        mEncoder = MediaCodec.createEncoderByType(MIME_TYPE);        MediaFormat mediaFormat = MediaFormat.createVideoFormat(MIME_TYPE, RECORD_WIDTH, RECORD_HEIGHT);        mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface);        mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, BIT_RATE); // 比特率        mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, FRAME_RATE); // 帧率        mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, I_FRAME_INTERVAL); // I帧间隔        // 配置 MediaCodec 对象并启动        mEncoder.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE);        mSurface = mEncoder.createInputSurface();        mEncoder.start();        // 获取 ImageReader 中的图像数据并编码        while (true) {            Image image = mImageReader.acquireLatestImage();            if (image == null) {                continue;            }            // 将 Image 转化为 Bitmap 对象            Image.Plane[] planes = image.getPlanes();            int width = image.getWidth();            int height = image.getHeight();            ByteBuffer buffer = planes[0].getBuffer();            int pixelStride = planes[0].getPixelStride();            int rowStride = planes[0].getRowStride();            int padding = rowStride - pixelStride * width;            Bitmap bitmap = Bitmap.createBitmap(width + padding / pixelStride, height, Bitmap.Config.ARGB_8888);            bitmap.copyPixelsFromBuffer(buffer);            bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);            // 编码 Bitmap 数据            long pts = System.nanoTime() / 1000;            int inputIndex = mEncoder.dequeueInputBuffer(TIMEOUT_US);            if (inputIndex >= 0) {                Surface surface = mEncoder.createInputSurface();                canvas canvas = surface.lockCanvas(null);                canvas.drawBitmap(bitmap, new Matrix(), null);                surface.unlockCanvasAndPost(canvas);                mEncoder.queueInputBuffer(inputIndex, 0, 0, pts, 0);            }            image.close();        }    } catch (Exception e) {        e.printStackTrace();    }}

需要注意的是,在使用 MediaProjection API 进行屏幕录制时,需要获取用户的授权。同时在录制过程中,还需要处理好多个线程之间的同步关系,避免出现数据异常等情况。

截屏

在 Android 应用程序中实现屏幕截屏,通常可以使用以下两种方式:

  1. 使用 MediaProjection API:MediaProjection API 是 Android Framework 提供的一种机制,允许应用获取指定屏幕的图像帧,并进行相关处理或保存为视频文件。在屏幕截屏方面,开发者可以使用 MediaProjection.createVirtualDisplay() 方法创建虚拟显示器,并使用 ImageReader.acquireLatestImage() 方法获取最新的一帧图像,进而将其保存为图片文件。

具体实现过程如下:

// 在 Activity 中启动屏幕捕获 Intent,并在 onActivityResult() 方法中获取 MediaProjection 对象private void startScreenCapture() {    mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);    startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {    if (requestCode == REQUEST_MEDIA_PROJECTION && resultCode == RESULT_OK) {        mMediaProjection = mMediaProjectionManager.getMediaProjection(resultCode, data);        // 创建虚拟显示器        mVirtualDisplay = mMediaProjection.createVirtualDisplay(                "ScreenCapture",                mScreenWidth, mScreenHeight, mScreenDensity,                DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,                mImageReader.getSurface(), null, mHandler);    }}// 在需要截屏的时候调用private void takeScreenShot() {    Image image = mImageReader.acquireLatestImage();    ByteBuffer buffer = image.getPlanes()[0].getBuffer();    byte[] bytes = new byte[buffer.capacity()];    buffer.get(bytes);    Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);    // 将 Bitmap 保存为本地文件    File file = new File(Environment.getExternalStorageDirectory(), "screenshot.png");    FileOutputStream outputStream = null;    try {        outputStream = new FileOutputStream(file);        bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);        Log.d(TAG, "ScreenShot Saved");    } catch (FileNotFoundException e) {        e.printStackTrace();    } finally {        image.close();        if (outputStream != null) {            try {                outputStream.close();            } catch (IOException e) {                e.printStackTrace();            }        }    }}

需要注意的是,在 Android 5.0 及以上版本中,启动屏幕捕获 Intent 需要授权,而且用户会受到屏幕被录制的通知。如果要想避免这种情况,需要使用 SystemUI 系统应用程序或自己编写(需要 root 权限)。

  1. 使用 View 的 draw() 方法:在 View 的绘制过程中,可以通过调用 View 的 draw(Canvas canvas) 方法来获取其绘制区域的内容,并将其保存为图片文件。具体实现方式如下:
// 创建一个 ViewView view = getWindow().getDecorView();// 创建 Bitmap 并将 View 绘制到画布上Bitmap bm = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bm);view.draw(canvas);// 将 Bitmap 保存到本地文件中File saveDir = Environment.getExternalStorageDirectory();File file = new File(saveDir, "screenshot.png");OutputStream outputStream = new FileOutputStream(file);bm.compress(Bitmap.CompressFormat.PNG, 100, outputStream);outputStream.close();

需要注意的是,该方法只适用于当前应用程序内部界面的截图。如果想要截取其他应用程序、系统界面或整个屏幕的截图,则需要使用 MediaProjection API 实现。

长截屏

实现长截屏的方法一般是通过将多个屏幕截图拼接在一起。下面是一些实现长截屏的步骤以及相关代码示例:

  1. 获取屏幕宽度和高度
DisplayMetrics metrics = getResources().getDisplayMetrics();int width = metrics.widthPixels;int height = metrics.heightPixels;
  1. 创建一个空的 Bitmap 对象用于保存所截取的屏幕内容
Bitmap longScreenshot = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
  1. 获取当前屏幕的 View 对象并将其绘制到 Bitmap 中
View screenshotView = getWindow().getDecorView().getRootView();Canvas canvas = new Canvas(longScreenshot);screenshotView.draw(canvas);
  1. 循环获取当前 View 的滚动位置并将其截取下来,然后将其拼接到 longScreenshot 中
while (scrollY < totalHeight) {    scrollView.scrollTo(0, scrollY);    Bitmap bitmap = Bitmap.createBitmap(scrollView.getWidth(), scrollView.getHeight(), Bitmap.Config.ARGB_8888);    Canvas canvas = new Canvas(bitmap);    scrollView.draw(canvas);    canvas.drawBitmap(bitmap, 0, scrollY, null);    scrollY += scrollView.getHeight();}longScreenshot.compress(Bitmap.CompressFormat.PNG, 100, outputStream);

完整代码示例请参考:

private void takeLongScreenshot() {    // 获取屏幕宽度和高度    DisplayMetrics metrics = getResources().getDisplayMetrics();    int width = metrics.widthPixels;    int height = metrics.heightPixels;        // 创建一个空的 Bitmap 对象用于保存所截取的屏幕内容    Bitmap longScreenshot = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        // 获取当前屏幕的 View 对象并将其绘制到 Bitmap 中    View screenshotView = getWindow().getDecorView().getRootView();    Canvas canvas = new Canvas(longScreenshot);    screenshotView.draw(canvas);        // 循环获取当前 View 的滚动位置并将其截取下来,然后将其拼接到 longScreenshot 中    int scrollY = screenshotView.getHeight();    ScrollView scrollView = findViewById(R.id.scroll_view);    int totalHeight = scrollView.getChildAt(0).getHeight();    while (scrollY < totalHeight) {        scrollView.scrollTo(0, scrollY);        Bitmap bitmap = Bitmap.createBitmap(scrollView.getWidth(), scrollView.getHeight(), Bitmap.Config.ARGB_8888);        Canvas canvas1 = new Canvas(bitmap);        scrollView.draw(canvas1);        canvas.drawBitmap(bitmap, 0, scrollY, null);        scrollY += scrollView.getHeight();    }        // 将拼接后的长截屏保存到文件中    try {        FileOutputStream outputStream = new FileOutputStream(getExternalFilesDir(null) + "/long_screenshot.png");        longScreenshot.compress(Bitmap.CompressFormat.PNG, 100, outputStream);        outputStream.flush();        outputStream.close();    } catch (IOException e) {        e.printStackTrace();    }}

需要注意的是,由于手机屏幕宽度和高度有限,因此一些页面可能无法完全截取。同时,由于 Android 系统版本和不同厂商的定制系统可能存在差异,因此上述代码并不能保证在所有情况下都能正常工作。

来源地址:https://blog.csdn.net/weixin_44008788/article/details/130409441

--结束END--

本文标题: Android 实现屏幕录制和截屏

本文链接: https://www.lsjlt.com/news/374467.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Android 实现屏幕录制和截屏
    在移动开发中,实现屏幕录制和截屏是常见的需求。对于 Android 应用而言,实现屏幕录制和截屏可以帮助开发者更好地测试和调试自己的应用,同时还能够提供一些特定场景下的用户体验。 屏幕录制 Android 应用程序可以通过使用 MediaP...
    99+
    2023-08-18
    android 截屏 录屏
  • Android 截屏实现、屏幕截图、MediaProjection、ImageReader
    1. 第一步:调起系统捕获屏幕的Intent MainActivity:public void goCaptureIntent() { //第一步.调起系统捕获屏幕的Intent mMediaProjectionManager ...
    99+
    2023-10-08
    android 图像处理 service_mash android-studio android studio
  • C++实现屏幕截图(全屏截图)
    上回分享了一个全屏截图的代码,保存为BMP, C++实现屏幕截图(全屏截图):https://www.jb51.net/article/140184.htm 实际使用的过程中我发现截...
    99+
    2024-04-02
  • python实现屏幕截图
    由于在我的一个程序中想要添加一个截图功能,今天看一下利用Python怎样截图,功能实现都挺简单了,直接上代码 from PIL import ImageGrab im = ImageGrab.grab() im.save(addr,'jp...
    99+
    2023-01-31
    截图 屏幕 python
  • android如何实现视频截屏&手机录屏
    这篇文章主要介绍android如何实现视频截屏&手机录屏,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!问题在android中有时候我们需要对屏幕进行截屏操作,单一的截屏操作好解决可以通过activity的顶层...
    99+
    2023-05-30
    android
  • [python小工具]实现屏幕录制
      用python实现屏幕录制 PIL 即pollow 的安装命令如下: pip install pillow 其中cv2的安装是下面这条命令 pip install opencv-python #python + opencv 实...
    99+
    2023-01-31
    小工具 屏幕 python
  • Android 10.0 系统禁用截屏和录屏功能
    1.前言  在10.0的产品开发中,在对于一些产品开发需求中,对系统截屏和录屏功能 要求去掉这些功能,不让用户截屏和录屏 保护 一个app的资源,所以就需要在系统中做限制不让截屏录屏 2.系统禁用截屏和录屏功能的核心类 framework...
    99+
    2023-09-11
    android java framework 禁止截图功能 禁止录屏功能
  • Android实现截屏功能
    导言 目前截屏的方法很多,root不适用,要么其他方法就是有局限性,而其中官方给出的方案最好—MediaProjection 介绍 Android 5.0以后开放的录屏API,取视频...
    99+
    2024-04-02
  • Android屏幕及view的截图实例详解
    Android屏幕及view的截图实例详解屏幕可见区域的截图 整个屏幕截图的话可以用View view = getWindow().getDecorView();public static Bitmap getNormalViewScree...
    99+
    2023-05-31
    android view截图 roi
  • 怎么用Python实现屏幕截图
    本文小编为大家详细介绍“怎么用Python实现屏幕截图”,内容详细,步骤清晰,细节处理妥当,希望这篇“怎么用Python实现屏幕截图”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。一、序言在csdn上有很多纯cop...
    99+
    2023-06-28
  • 用Python实现屏幕截图详解
    目录一、序言二、环境配置三、屏幕截屏源码与解析四、结语一、序言 在csdn上有很多纯copy,这给我复现带来了很大的麻烦,所以我想根据我的个人找截图的经历记录下来,给未来的自己看,免...
    99+
    2024-04-02
  • Python 实现Mac 屏幕截图详解
    目录前言pyscreenshotgithub地址Python 安装用例代码截图效果总结前言 最近想做个小玩意,需要在mac端实现屏幕截图,搜了下网上中文资源都比较老旧,于是查了下,发...
    99+
    2024-04-02
  • Android中关于屏幕的三个小众知识(宽屏适配、禁止截屏和保持屏幕常亮)
    前言宽屏适配、禁止截屏和保持屏幕常亮,这三个与屏幕有关的 Android 开发小众知识,说不定什么时候就派上用场。宽屏适配Android的屏幕适配一直以来都在折磨着我们Android开发者,越来越多的手机厂商趋向于全面屏设计,比如今年出厂的...
    99+
    2023-05-30
  • 原生JS实现简单屏幕截图
    目录了解 HTML5 中的 Canvas获取屏幕截图结论在 Web 开发中,截图是一项非常有用的技术。可以使用截图来记录当前屏幕状态,生成缩略图或进行屏幕分享等操作。在本文中,我将介...
    99+
    2023-05-15
    JS 屏幕截图 JS 原生截图
  • go语言怎么实现屏幕截图
    今天小编给大家分享一下go语言怎么实现屏幕截图的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。借助第三方库安装go ...
    99+
    2023-06-30
  • Python做屏幕录制工具的实现示例
    目录思路实现录制监听键盘事件主体控制视频信息女朋友是一个软件测试人员,在工作中经常会遇到需要录屏记录自己操作,方便后续开发同学定位。因为录屏软件动不动就开始收费,所以她经常更换录屏软...
    99+
    2024-04-02
  • Android 屏幕实现上下翻转
    Android 屏幕实现上下翻转通常我们的应用只会设计成横屏或者竖屏,锁定横屏或竖屏的方法是在manifest.xml文件中设定属性android:screenOrientation为"landscape"或"portrait": <...
    99+
    2023-05-31
    android 翻转 roi
  • win10屏幕录制如何录制桌面
    这篇文章主要介绍了win10屏幕录制如何录制桌面的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇win10屏幕录制如何录制桌面文章都会有所收获,下面我们一起来看看吧。win10屏幕录制方法:同时按下键盘上的Win...
    99+
    2023-07-01
  • Android滚动截屏如何实现
    要实现Android滚动截屏,可以使用以下步骤:1. 获取屏幕的宽度和高度。可以通过以下代码获取:```DisplayMetrics...
    99+
    2023-08-24
    Android
  • 怎么通过Linux命令实现屏幕录制和回放
    这篇文章将为大家详细讲解有关怎么通过Linux命令实现屏幕录制和回放,文章内容质量较高,因此小编分享给大家做个参考,希望大家阅读完这篇文章后对相关知识有一定的了解。相信大多数人都没有听说过在Linux系统中通过命令行也能实现屏幕录制和回放,...
    99+
    2023-06-28
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作