如何通过代码而不是程序来截取手机屏幕的选定区域的截图?
当前回答
捷径是
FrameLayout layDraw = (FrameLayout) findViewById(R.id.layDraw); /*Your root view to be part of screenshot*/
layDraw.buildDrawingCache();
Bitmap bmp = layDraw.getDrawingCache();
其他回答
你可以尝试这样做,
从布局或视图中获取位图缓存 首先你需要setDrawingCacheEnabled到一个布局(线性布局或相对布局,或视图)
然后
Bitmap bm = layout.getDrawingCache()
然后对位图做任何你想做的事情。要么将其转换为图像文件,要么将位图的uri发送到其他地方。
我的解决方案是:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
and
public void takeScreen() {
Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
File imageFile = new File(mPath);
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fout.close();
}
}
图像保存在外部存储文件夹中。
Mualig的回答很好,但我遇到了Ewoks描述的同样的问题,我没有得到背景。所以有时已经足够好了,有时我得到黑色背景上的黑色文本(取决于主题)。
这个解决方案主要基于Mualig代码和我在Robotium中找到的代码。通过直接调用draw方法,我放弃了绘图缓存的使用。在此之前,我将尝试从当前活动中首先绘制背景。
// Some constants
final static String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get device dimmensions
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
// Get root view
View view = mCurrentUrlMask.getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(size.x, size.y, Bitmap.Config.ARGB_4444);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Activity activity = getCurrentActivity();
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d(LOGTAG, "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
根据上面@JustinMorris和@NiravDangi的回答https://stackoverflow.com/a/8504958/2232148,我们必须把一个视图的背景和前景像这样组合起来:
public static Bitmap takeScreenshot(View view, Bitmap.Config quality) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), quality);
Canvas canvas = new Canvas(bitmap);
Drawable backgroundDrawable = view.getBackground();
if (backgroundDrawable != null) {
backgroundDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return bitmap;
}
质量参数取一个常数Bitmap。Config,通常是Bitmap.Config。RGB_565或Bitmap.Config.ARGB_8888。
只是扩展塔拉洛卡的答案。您必须添加以下行才能使其工作。我已将映像名称设置为静态。请确保您使用taraloca的时间戳变量,以防您需要动态图像名称。
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private void verifyStoragePermissions() {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}else{
takeScreenshot();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == REQUEST_EXTERNAL_STORAGE) {
takeScreenshot();
}
}
}
在AndroidManifest.xml文件中,以下条目是必须的:
< uses-permission android: name = " android.permission。READ_EXTERNAL_STORAGE " / > < uses-permission android: name = " android.permission。WRITE_EXTERNAL_STORAGE " / >
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件