我是靠谱客的博主 淡定电脑,最近开发中收集的这篇文章主要介绍SurfaceControl.screenshot()用法 | SurfaceControl.screenshot()使用后返回null的解决方案,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

前言

SurfaceControl.screenshot()是系统的截屏方法,属于系统API,对用户不开放,因此要使用的话需要系统的签名(platform.keystore文件)才能调用到。
在高版本的android上(例如android 11),如果没有系统签名,即使用反射也会报找不到方法的异常,但是有系统签名的话,直接调用就行。



旧方法使用

网上不少教程展示的是旧的调用方式,这些调用方式在高版本中已经不适用了,如下:

  1. 使用反射调用截屏
//获取屏幕尺寸
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
//调用screenshot()
try {
Class<?> demo = Class.forName("android.view.SurfaceControl");
Method method = demo.getDeclaredMethod("screenshot", int.class,int.class);
mScreenBitmap = (Bitmap) method.invoke(null,(int) dims[0],(int) dims[1]);
} catch (Exception e) {
e.printStackTrace();
}
//显示bitmap
ImageView image = findViewById(R.id.image);
image.setImageBitmap(mScreenBitmap);
  1. 直接调用screenshot方法截屏
//获取屏幕尺寸
DisplayMetrics mDisplayMetrics = new DisplayMetrics();
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels};
//调用screenshot()
Bitmap mScreenBitmap = SurfaceControl.screenshot((int) dims[0],(int) dims[1]);
//显示bitmap
ImageView image = findViewById(R.id.image);
image.setImageBitmap(mScreenBitmap);


新方法使用

在后期的android版本中,已经取消了screenshot(width, height)方法,因此只传入两个int值的方式行不通了

在剩下的screenshot()构造参数中,使用起来最方便的就是screenshot(Rect sourceCrop, int width, int height, int rotation)这个方法。
对于参数说明如下:

参数作用
sourceCrop要捕获到位图中的屏幕部分;如果不需要裁剪,调用者可以传入new Rect()
width返回位图的所需宽度;原始屏幕将缩小到该大小;如果不需要缩放,调用者可以传入0
height返回位图的所需高度;原始屏幕将缩小到该大小;如果不需要缩放,调用者可以传入0
rotation将自定义顺时针旋转应用于屏幕截图,即Surface.ROTION_0,90,180,270。默认情况下,SurfaceFlinger将始终以其原始纵向方向拍摄屏幕截图,因此这对于返回独立于设备方向的屏幕截图非常有用

因此,在新的android系统上,我们可以这样写:

//调用screenshot()
//参数传入默认的,表示直接截全屏并且不缩放,不裁剪,不旋转
Bitmap mScreenBitmap = SurfaceControl.screenshot(new Rect(), 0, 0, Surface.ROTATION_0);
//显示bitmap
ImageView image = findViewById(R.id.image);
image.setImageBitmap(mScreenBitmap);

由于此方法不依赖于Activity,所以可以用来实现后台截屏的效果。但是要注意的是,调用此方法需要系统的签名(platform.keystore),或者增加android:sharedUserId="android.uid.system"



screenshot()始终返回null的解决方案

如果你调用后不报错,但同时返回的bitmap又一直为null,则可能是权限问题。解决方案如下:

  1. AndroidManifest.xml增加android:sharedUserId="android.uid.system"
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx"
android:sharedUserId="android.uid.system">
...
  1. 如果你不想将app变成系统应用,可以在AndroidManifest.xml中增加单独的权限
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.xxx">
<!-- 增加此权限 -->
<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />
...

以上两个方法使用一种就行

最后

以上就是淡定电脑为你收集整理的SurfaceControl.screenshot()用法 | SurfaceControl.screenshot()使用后返回null的解决方案的全部内容,希望文章能够帮你解决SurfaceControl.screenshot()用法 | SurfaceControl.screenshot()使用后返回null的解决方案所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部