Android10以上MediaProjection截屏

2024-04-20 22:20

本文主要是介绍Android10以上MediaProjection截屏,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

起因

在系统升级到Android10以上之后,之前的截屏方式不能用了,而且必须将MediaProjection放在forground service里面跑才行。网上搜了一圈,都是语焉不详或者没有完整的一个代码应用。只能自己写一个,记录下

代码实现

新建一个ScreenRecorder.java


public class ScreenRecorder extends Service {@Nullable@Overridepublic IBinder onBind(Intent intent) {return null;}private MediaProjection mMediaProjection;private MediaProjectionManager mMediaProjectionManager;private int SERVICE_ID = 123;private String NOTIFICATION_CHANNEL_ID = "Screen Capture channel";public static final String ACTION_START = "RecordService:Start";public static final String ACTION_SNAPSHOT = "RecordService:Snapshot";public static final String ACTION_STOP = "RecordService:Stop";public static final String EXTRA_RESULT_DATA = "RecordService:Extra:ResultData";@Overridepublic void onCreate() {super.onCreate();createNotificationChannel();startForeground(SERVICE_ID, new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID).build());mMediaProjectionManager = (MediaProjectionManager) getApplicationContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);}@Overridepublic int onStartCommand(final Intent intent, int flags, int startId) {if (intent != null) {if (intent.getAction() != null) {switch (intent.getAction()) {case ACTION_START:Log.d(TAG, "onStartCommand: start recorder");mMediaProjection = mMediaProjectionManager.getMediaProjection(Activity.RESULT_OK,Objects.requireNonNull(intent.getParcelableExtra(EXTRA_RESULT_DATA)));startCapture();return START_STICKY;case ACTION_SNAPSHOT:
//                        stopSelf();snapshot();break;case ACTION_STOP:Log.d(TAG, "onStartCommand: close imagereader");if (mImageReader != null){try{mImageReader.close();}catch (Exception exception){Log.e(TAG, "onStartCommand: "+ exception.getMessage() );}}stopSelf();return START_NOT_STICKY;}}}return super.onStartCommand(intent, flags, startId);}private void createNotificationChannel() {NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,"ScreenRecorder",NotificationManager.IMPORTANCE_DEFAULT);NotificationManager manager = getSystemService(NotificationManager.class);manager.createNotificationChannel(notificationChannel);}private ImageReader mImageReader;private void startCapture() {DisplayMetrics displayMetrics = new DisplayMetrics();WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);windowManager.getDefaultDisplay().getMetrics(displayMetrics);int screenWidth = displayMetrics.widthPixels;int screenHeight = displayMetrics.heightPixels;mImageReader = ImageReader.newInstance(screenWidth, screenHeight, PixelFormat.RGBA_8888, 2);mMediaProjection.createVirtualDisplay("mediaprojection", screenWidth, screenHeight,displayMetrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);}private void snapshot(){if (mImageReader != null){Image image = mImageReader.acquireLatestImage();int width = image.getWidth();int height = image.getHeight();final Image.Plane[] planes = image.getPlanes();final ByteBuffer buffer = planes[0].getBuffer();int pixelStride = planes[0].getPixelStride();int rowStride = planes[0].getRowStride();int rowPadding = rowStride - pixelStride * width;Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height,Bitmap.Config.ARGB_8888);bitmap.copyPixelsFromBuffer(buffer);bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);//保存图片到本地CommonLib.saveMyBitmap("snapshot", bitmap);image.close();}}
}

AndroidManifest.xml中注册

<!--   申请权限 />-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<service android:name=".ScreenRecorder"android:exported="true"android:foregroundServiceType="mediaProjection"/>

Activity中调用

 public void onCreate(Bundle bundle) {super.onCreate(bundle);requestCapturePermission();}
/**
* 申请权限
*/public void requestCapturePermission() {MediaProjectionManager mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);Intent intent = new Intent(mediaProjectionManager.createScreenCaptureIntent());startActivityForResult(intent, REQUESTRESULT);}
// 回调里面启动服务
@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if (resultCode == RESULT_OK) {Intent intent = new Intent(this, ScreenRecorder.class);intent.setAction(ScreenRecorder.ACTION_START);intent.putExtra(ScreenRecorder.EXTRA_RESULT_DATA, data);startForegroundService(intent);EnableTakePhotos = true;}
}

snapshot方法

private void startSnapshot(){Intent intent = new Intent(this, ScreenRecorder.class);intent.setAction(ScreenRecorder.ACTION_SNAPSHOT);startService(intent);
}

可以设置一个按钮,然后在点击事件里面调用startSnapshot()方法即可

这篇关于Android10以上MediaProjection截屏的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/921475

相关文章

Android6.0以上权限申请

说明: 部分1:出自:http://jijiaxin89.com/2015/08/30/Android-s-Runtime-Permission/ android M 的名字官方刚发布不久,最终正式版即将来临! android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响。惊讶的是android社区鲜有谈论这事儿,尽管这事很重要或许在不远的将来会引

Ubuntu 16.04安装python3.6及其以上版本

Ubuntu16.04 自带python2.7 和3.5,若需要安装高版本需要添加源 网络搜索几个源 sudo add-apt-repository ppa:jonathonf/python-3.6sudo apt-get updatesudo apt-get install python3.6 这个已不存在 会报错如下 Cannot add PPA: 'ppa:~jonathonf

在Webmin上默认状态无法正常显示 Mariadb V11.02及以上版本

OS: Armbian OS 24.5.0 Bookworm Mariadb V11.02及以上版本 Webmin:V2.202 小众问题,主要是记录一下。 如题 Webmin 默认无法 Mariadb V11.02及以上版本 如果对 /etc/webmin/mysql/config 文件作相应调整就可以再现Mariadb管理界面。 路径+文件:/etc/webmin/mysql/config

Mongodb最新版本安装(4.0以上)

最近学习Mongodb数据库 总结了一下心得分享给大家 一,首先需要去官网下载Mongodb  网址https://www.mongodb.com/download-center/community   如下图所示 选择版本号、对应的操作系统、安装包后 点击download  开始下载  下载完成后双击安装就行 安装步骤 1.双击之后如图所示 直接next 2.由于笔者没有保存这张

教你用Python快速生成各尺寸应用图标和截屏

作为独立开发者,App发布前,自然要自己制作图标、截屏,尤其是iOS,每次都要手动生成六七种尺寸的截屏,十几个尺寸的图标,尽管在Mac上有生成图标的应用,但是效果仍旧不尽如人意。 现在(其实肯定早就有人这么做了),用强大的Python就可以瞬间生成。 简单和大家说下原理。利用Python强大的文件、图像处理能力,自动缩放尺寸,生成所需图标和截屏。 有些注意点提醒下大家,截屏需要

xcode6以上空模板配置

这边提供一份空模板配置的文档: http://pan.baidu.com/s/1dDxxg9j 1.确定安装的Xcode在应用程序中得绝对路径。 2.打开终端,使用cd指令,进入目录 AddMissingTemplates-master(要找到你存放AddMissingTemplates-master的路径),然后运行里面的脚本AddMissingTemplates.sh就ok了。(运行方

反制裁来了,200层以上存储芯片率先量产,领先国外芯片巨头

现在,你所见证的是国产芯片领域少有的振奋人心的时刻。 这是一场非同寻常的诉讼。 一家中国芯片公司罕见地坐在了原告席上,对美国公司提起侵权诉讼。 这就是长江存储。 国内唯一一家成功赶超外国顶尖技术并实现大规模量产的芯片公司。 然而,它的辉煌战绩远不止于此。 在市值高达数千亿的闪存市场中,长江存储的专利申请数量已经超越了三星,跃居行业首位。 有底气数次控告美光侵权,顶着设备和材料

关于emjoy表情在android5.x以上系统触发jni错误的修改(基于cocos2dx2.1.5修改)

一直纠结着这个错误,后来看别人的文章找到灵感,于是完善了基于cocos2dx2.1.5修改的 具体报错:JNI DETECTED ERROR IN APPLICATION: input is not valid Modified UTF-8: illegal continuation byte 0xed 解决办法(基于coocs2dx2.1.5): 在CCImage.cpp里面的g

MySQL8.0 以上版本 “caching_sha2_password cannot be loaded” 问题解决办法

MySQL8 以上版本客户端登录 “caching_sha2_password cannot be loaded” 问题 解决办法1: 用root用户登录mysql,然后执行两行命令: ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '密码';FLUSH PRIVILEGES; 注: 1. docker部署的M

Android如何在应用层进行截屏及截屏源码分析(上)

最近在看framework层代码时发现其中有一个是测试截屏操作的专门的包,于是潜意识的驱使下就研究了这方面的知识,今天作个总结吧!以及我们在写上层应用时如何做截屏操作的,那么我们先来看看截屏的源码分析,其实截屏操作就java这部分是放在了系统SystemUI那里,用过android系统手机的同学应该都知道,一般的android手机按下音量减少键和电源按键就会触发截屏事件(国内定制机做个修改的这里就