从 android 中的 activity 获取屏幕截图?
Getting View from activity in android for screenshot?
我想尝试为 android 实现屏幕截图功能。为此,我想要 android 的 activity 的观点。我不允许使用 R.id.viewid
因为我将其作为库的一部分而不是应用程序来实现。所以我正在尝试使用 activity.getWindow().getDecorView
请让我知道获取 DecorView 是否是正确的方法?或者应该有其他方法。
MyActivity.java
@Override
protected void onResume(){
super.onResume();
String mPath = Environment.getExternalStorageDirectory().toString() + "/test";
Screenshot.takeScreenshot (this.getWindow().getDecorView(), mPath);
imageView.setImageBitmap(Screenshot.getBitmapScreenshot(this.getWindow().getDecorView()));
}
Screenshot.java
public static void takeScreenshot(View view, String filePath) {
Bitmap bitmap = getBitmapScreenshot(view);
File imageFile = new File(filePath);
imageFile.getParentFile().mkdirs();
try {
OutputStream fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap getBitmapScreenshot(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view's background
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
我遇到以下错误。
3795-3795/com.screenshot.nileshagrawal.screenshotapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.screenshot.nileshagrawal.screenshotapp, PID: 3795
java.lang.RuntimeException: Unable to resume activity {com.screenshot.nileshagrawal.screenshotapp/com.screenshot.nileshagrawal.screenshotapp.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2951)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
at com.screenshot.nileshagrawal.screenshotapp.Screenshot.getBitmapScreenshot(Screenshot.java:49)
at com.screenshot.nileshagrawal.screenshotapp.Screenshot.takeScreenshot(Screenshot.java:24)
at com.screenshot.nileshagrawal.screenshotapp.MainActivity.onResume(MainActivity.java:32)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1241)
at android.app.Activity.performResume(Activity.java:6019)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2940)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
尝试为此替换 getWindow().getDecorView
getWindow().getDecorView().findViewById(android.R.id.content)
我想剩下的就可以了
尝试将此方法放在 onPause() 中,因为视图已准备好在 onResume() 期间进行任何修改。因此,要么在 onResume 中设置一些延迟(使用处理程序以异步方式获取屏幕截图),要么屏幕截图是不是那么关键在 onPause() 中采用相同的方法并在 super.onPause() 调用之前调用该函数。在 Whosebug post 之一中,下面的示例代码正在运行。
我在 onPause() 中测试了相同的内容。
使用这个方法
public static String takeScreenshot(Activity activity) {
Bitmap bitmap = null;
Bitmap resultBitmap = null;
ByteArrayOutputStream bos = null;
String encodedImg = null;
Toast.makeText(activity.getBaseContext(), "Taking screenshot",
Toast.LENGTH_SHORT).show();
try {
View v1 = activity.getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
resultBitmap = Bitmap.createScaledBitmap(bitmap,
v1.getMeasuredWidth(), v1.getMeasuredHeight(), false);
v1.setDrawingCacheEnabled(false);
//MediaStore.Images.Media.insertImage(activity.getContentResolver(),
//resultBitmap, "myScreenshot2", "Test2");
bos = new ByteArrayOutputStream();
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 10, bos);
byte[] bitmapdata = bos.toByteArray();
encodedImg = new String(Base64.encode(bitmapdata, Base64.DEFAULT));
} catch (Exception e) {
Log.e(Constants.LOG_TAG, "Could not capture the screen image");
Log.e(Constants.LOG_TAG, e.toString());
Log.e(Constants.LOG_TAG, Arrays.toString(e.getStackTrace()));
} finally {
if (bitmap != null) {
bitmap.recycle();
}
if (resultBitmap != null) {
resultBitmap.recycle();
}
if (bos != null) {
bos.reset();
}
return encodedImg;
}
}
我想尝试为 android 实现屏幕截图功能。为此,我想要 android 的 activity 的观点。我不允许使用 R.id.viewid
因为我将其作为库的一部分而不是应用程序来实现。所以我正在尝试使用 activity.getWindow().getDecorView
请让我知道获取 DecorView 是否是正确的方法?或者应该有其他方法。
MyActivity.java
@Override
protected void onResume(){
super.onResume();
String mPath = Environment.getExternalStorageDirectory().toString() + "/test";
Screenshot.takeScreenshot (this.getWindow().getDecorView(), mPath);
imageView.setImageBitmap(Screenshot.getBitmapScreenshot(this.getWindow().getDecorView()));
}
Screenshot.java
public static void takeScreenshot(View view, String filePath) {
Bitmap bitmap = getBitmapScreenshot(view);
File imageFile = new File(filePath);
imageFile.getParentFile().mkdirs();
try {
OutputStream fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static Bitmap getBitmapScreenshot(View view) {
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
//Get the view's background
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
else
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}
我遇到以下错误。
3795-3795/com.screenshot.nileshagrawal.screenshotapp E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: com.screenshot.nileshagrawal.screenshotapp, PID: 3795
java.lang.RuntimeException: Unable to resume activity {com.screenshot.nileshagrawal.screenshotapp/com.screenshot.nileshagrawal.screenshotapp.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2951)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.view.View.getWidth()' on a null object reference
at com.screenshot.nileshagrawal.screenshotapp.Screenshot.getBitmapScreenshot(Screenshot.java:49)
at com.screenshot.nileshagrawal.screenshotapp.Screenshot.takeScreenshot(Screenshot.java:24)
at com.screenshot.nileshagrawal.screenshotapp.MainActivity.onResume(MainActivity.java:32)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1241)
at android.app.Activity.performResume(Activity.java:6019)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2940)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2982)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2365)
at android.app.ActivityThread.access0(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
尝试为此替换 getWindow().getDecorView
getWindow().getDecorView().findViewById(android.R.id.content)
我想剩下的就可以了
尝试将此方法放在 onPause() 中,因为视图已准备好在 onResume() 期间进行任何修改。因此,要么在 onResume 中设置一些延迟(使用处理程序以异步方式获取屏幕截图),要么屏幕截图是不是那么关键在 onPause() 中采用相同的方法并在 super.onPause() 调用之前调用该函数。在 Whosebug post 之一中,下面的示例代码正在运行。 我在 onPause() 中测试了相同的内容。
使用这个方法
public static String takeScreenshot(Activity activity) {
Bitmap bitmap = null;
Bitmap resultBitmap = null;
ByteArrayOutputStream bos = null;
String encodedImg = null;
Toast.makeText(activity.getBaseContext(), "Taking screenshot",
Toast.LENGTH_SHORT).show();
try {
View v1 = activity.getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
resultBitmap = Bitmap.createScaledBitmap(bitmap,
v1.getMeasuredWidth(), v1.getMeasuredHeight(), false);
v1.setDrawingCacheEnabled(false);
//MediaStore.Images.Media.insertImage(activity.getContentResolver(),
//resultBitmap, "myScreenshot2", "Test2");
bos = new ByteArrayOutputStream();
resultBitmap.compress(Bitmap.CompressFormat.JPEG, 10, bos);
byte[] bitmapdata = bos.toByteArray();
encodedImg = new String(Base64.encode(bitmapdata, Base64.DEFAULT));
} catch (Exception e) {
Log.e(Constants.LOG_TAG, "Could not capture the screen image");
Log.e(Constants.LOG_TAG, e.toString());
Log.e(Constants.LOG_TAG, Arrays.toString(e.getStackTrace()));
} finally {
if (bitmap != null) {
bitmap.recycle();
}
if (resultBitmap != null) {
resultBitmap.recycle();
}
if (bos != null) {
bos.reset();
}
return encodedImg;
}
}