android辅助功能截屏,Android 截屏的三种方法

第一种 调用“su”命令执行截屏

执行“su”命令,需要设置为系统程序,android:sharedUserId="android.uid.system",需要root权限。

方法如下:

/**

* 屏幕截图

* 适用于lanucher版

*/

public static void shotScreen() {

//adb截图方法

new Thread(new Runnable() {

@Override

public void run() {

Log.e("whh0914", "开始屏幕截图...");

String filepath = "/sdcard/screenShot.png";

try {

RootCmdUtils.execRootCmdSilent("screencap -p " + filepath);

} catch (Exception e) {

Log.e("whh0914", "屏幕截图出现异常:" + e.toString());

}

}

}).start();

}

/**

* 执行命令但不关注结果输出

*/

public static int execRootCmdSilent(String cmd) {

int result = -1;

DataOutputStream dos = null;

try {

Process p = Runtime.getRuntime().exec("su");

dos = new DataOutputStream(p.getOutputStream());

dos.writeBytes(cmd + "\n");

dos.flush();

dos.writeBytes("exit\n");

dos.flush();

p.waitFor();

result = p.exitValue();

} catch (Exception e) {

e.printStackTrace();

} finally {

if (dos != null) {

try {

dos.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

return result;

}

否则会报

java.io.IOException: Cannot run program : error=13, Permission denied

优缺点:命令行简单方便,对于复杂的页面或存在帧流(surfaceView等控件)也能轻松获取截屏,但是运行到手机上,由于硬件限制,系统权限基本难拿到,容易出异常而导致方法失效,因此该方法依硬件权限按需取

第二种 原生的截图方法,获取View的缓存作为截屏结果

/**

* 屏幕截图

*/

public static void screenShot1(Activity activity, ScreenShotReqBean screenShotReqBean) {

String filepath = "/sdcard/screenShot.png";

Bitmap bitmap = null;

try {

Log.e("whh0914", "111开始屏幕截图...");

//截图

activity.getWindow().getDecorView().setDrawingCacheEnabled(true);

bitmap = activity.getWindow().getDecorView().getDrawingCache();

//保存图片

FileOutputStream fos = new FileOutputStream(filepath);

bitmap.compress(Bitmap.CompressFormat.PNG, 50, fos);

} catch (Exception e) {

Log.e("whh0914", "111屏幕截图出现异常:" + e.toString());

}

}

优缺点:原生的截图方法,依赖于界面的内容,如果界面中包含webView、surfaceView等控件,截图出来该控件区域出现一片黑,无法达到截图到帧的效果。因此该方法按界面控件按需取。

第三种 通过 MediaProjectionManager 获取截图

public static final int EVENT_SCREENSHOT = 22;//截图事件

private MediaProjectionManager mediaProjectionManager;

private MediaProjection mediaProjection;

private Image image;

public void takeScreenShot() {

mediaProjectionManager = (MediaProjectionManager)

getApplication().getSystemService(Context.MEDIA_PROJECTION_SERVICE);

startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), EVENT_SCREENSHOT);

}

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

Log.e("whh0914", "onActivityResult...requestCode=" + requestCode + ",resultCode=" + resultCode);

if (requestCode == EVENT_SCREENSHOT) {

super.onActivityResult(requestCode, resultCode, data);

Log.e("whh0914", "captureScreen...");

DisplayMetrics displayMetrics = new DisplayMetrics();

WindowManager windowManager = (WindowManager) this.getSystemService(WINDOW_SERVICE);

windowManager.getDefaultDisplay().getMetrics(displayMetrics);

int width = displayMetrics.widthPixels;

int height = displayMetrics.heightPixels;

Log.e("whh0914", "displayMetrics width=" + width + ", height=" + height);

ImageReader mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);

mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data);

VirtualDisplay virtualDisplay = mediaProjection.createVirtualDisplay("screen-mirror", width, height,

displayMetrics.densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);

new Handler().postDelayed(new Runnable() {

@Override

public void run() {

try {

image = mImageReader.acquireLatestImage();

if (image != null) {

final Image.Plane[] planes = image.getPlanes();

final ByteBuffer buffer = planes[0].getBuffer();

int width = image.getWidth();

int height = image.getHeight();

Log.e("whh0914", "image width=" + width + ", height=" + height);

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.createScaledBitmap(bitmap, bitmap.getWidth(), bitmap.getHeight(), false);

if (bitmap != null) {

Log.e("whh0914", "屏幕截图成功!");

BitmapUtil.saveBitmap(bitmap, "/sdcard/screenShot.png");

}

bitmap.recycle();

}

} catch (Exception e) {

Log.e("whh0914", "截图出现异常:" + e.toString());

} finally {

if (image != null) {

image.close();

}

if (mImageReader != null) {

mImageReader.close();

}

if (virtualDisplay != null) {

virtualDisplay.release();

}

//必须代码,否则出现BufferQueueProducer: [ImageReader] dequeueBuffer: BufferQueue has been abandoned

mImageReader.setOnImageAvailableListener(null, null);

mediaProjection.stop();

}

}

}, 100);

}

}

优缺点:完美地解决了方法一、方法二存在的问题,完美!无需root权限,不用考虑界面中surfaceView等控件渲染问题。

每天进步一点点。。。(2020-07-09)

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值