如何通过代码而不是程序来截取手机屏幕的选定区域的截图?
当前回答
public class ScreenShotActivity extends Activity{
private RelativeLayout relativeLayout;
private Bitmap myBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout)findViewById(R.id.relative1);
relativeLayout.post(new Runnable() {
public void run() {
//take screenshot
myBitmap = captureScreen(relativeLayout);
Toast.makeText(getApplicationContext(), "Screenshot captured..!", Toast.LENGTH_LONG).show();
try {
if(myBitmap!=null){
//save image to SD card
saveImage(myBitmap);
}
Toast.makeText(getApplicationContext(), "Screenshot saved..!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public static Bitmap captureScreen(View v) {
Bitmap screenshot = null;
try {
if(v!=null) {
screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(screenshot);
v.draw(canvas);
}
}catch (Exception e){
Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
}
return screenshot;
}
public static void saveImage(Bitmap bitmap) throws IOException{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
}
添加权限
< uses-permission android: name = " android.permission.WRITE_EXTERNAL_STORAGE " / >
其他回答
调用这个方法,传入你想要屏幕截图的最外层ViewGroup:
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
注:仅适用于root phone
编程方式:adb shell /system/bin/screencap -p /sdcard/img.png
Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
然后将img.png读取为位图,并按照您的意愿使用。
如果你想从片段中截取截图,请遵循以下步骤:
Override onCreateView(): @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_one, container, false); mView = view; } Logic for taking screenshot: button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { View view = mView.findViewById(R.id.scrollView1); shareScreenShotM(view, (NestedScrollView) view); } method shareScreenShotM)(): public void shareScreenShotM(View view, NestedScrollView scrollView){ bm = takeScreenShot(view,scrollView); //method to take screenshot File file = savePic(bm); // method to save screenshot in phone. } method takeScreenShot(): public Bitmap takeScreenShot(View u, NestedScrollView z){ u.setDrawingCacheEnabled(true); int totalHeight = z.getChildAt(0).getHeight(); int totalWidth = z.getChildAt(0).getWidth(); Log.d("yoheight",""+ totalHeight); Log.d("yowidth",""+ totalWidth); u.layout(0, 0, totalWidth, totalHeight); u.buildDrawingCache(); Bitmap b = Bitmap.createBitmap(u.getDrawingCache()); u.setDrawingCacheEnabled(false); u.destroyDrawingCache(); return b; } method savePic(): public static File savePic(Bitmap bm){ ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes); File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + "/Foldername"); if (!sdCardDirectory.exists()) { sdCardDirectory.mkdirs(); } // File file = new File(dir, fileName); try { file = new File(sdCardDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); file.createNewFile(); new FileOutputStream(file).write(bytes.toByteArray()); Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath()); Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } return file; }
对于activity,您可以简单地使用View v1 = getWindow().getDecorView().getRootView();而不是mView
我已经创建了一个简单的库,从一个视图截图,要么给你一个位图对象,要么直接保存到任何你想要的路径
https://github.com/abdallahalaraby/Blink
作为参考,捕获屏幕(而不仅仅是应用程序活动)的一种方法是捕获帧缓冲区(device /dev/graphics/fb0)。要做到这一点,你必须拥有根权限,或者你的应用程序必须是一个具有签名权限的应用程序(“只有当请求应用程序与声明该权限的应用程序使用相同的证书进行签名时,系统才授予该权限”)-这是不太可能的,除非你编译了自己的ROM。
我测试过的几个设备上的每个framebuffer捕获都只包含一个截图。人们报告它包含更多,我猜这取决于框架/显示尺寸。
我尝试连续读取framebuffer,但它似乎返回了固定数量的读取字节。在我的例子中,这是(3 410 432)字节,这足以存储854*480 RGBA(3 279 360字节)的显示帧。是的,帧,二进制,从fb0输出是RGBA在我的设备。这很可能取决于不同的设备。这对你解码它很重要=)
在我的设备/dev/graphics/fb0权限是这样的,只有root和组图形的用户可以读取fb0。
图形是一个受限制的组,所以您可能只能使用su命令在根机中访问fb0。
Android应用程序的用户id (uid) = app_##,组id (guid) = app_##。
adb shell有uid = shell和guid = shell,它们拥有比app更多的权限。你可以在/system/permissions/platform.xml中查看这些权限
这意味着你将能够在没有根的adb shell中读取fb0,但如果没有根,你将无法在应用中读取它。
同样,在AndroidManifest.xml上给予READ_FRAME_BUFFER和/或ACCESS_SURFACE_FLINGER权限对常规应用没有任何作用,因为这些只对“签名”应用有效。
也检查这个关闭线程的更多细节。
推荐文章
- Android加载JS包失败
- Android Studio, logcat在应用程序关闭后清理
- 在android中从上下文获取活动
- 无法解析主机"<URL here>"没有与主机名关联的地址
- getActivity()在Fragment函数中返回null
- 按钮背景是透明的
- 在Mac OS X上哪里安装Android SDK ?
- 我如何获得图像缩放功能?
- 在Android应用程序中显示当前时间和日期
- BottomSheetDialogFragment的圆角
- 在应用程序启动时出现“无法获得BatchedBridge,请确保您的bundle被正确打包”的错误
- 我如何改变默认对话框按钮的文本颜色在安卓5
- 更改单选按钮的圆圈颜色
- 如何在android中复制一个文件?
- adb找不到我的设备/手机(MacOS X)