UPDATE I added the following code:
v1.setDrawingCacheEnabled(true);
v1.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v1.layout(0, 0, v1.getMeasuredWidth(), v1.getMeasuredHeight());
v1.buildDrawingCache(true);
Now I'm getting screenshots, but they're not what I need. For instance, one screen I need to capture consists of an LinearLayout containing an ImageView and a ListView. When the Activity loads during app execution, the list shows 10 items. The capture I'm getting only shows the top imageview and about 1.5 of the listitems. Is there something I can do to capture exactly what the screen shows? (I would post the shots I'm getting, but due to IP issues I'd have to redact basically everything, and posting a filled black rectangle is not super useful)
/update
I'm targeting Android 2.2 and trying to develop a class that be called from any activity to capture the current screen and store the image on the SD card (preferably as a PNG). I've found similar questions but there is an important difference here: I can't create a new View, and I can't build this code into every Activity (I can get away with adding one function call in each Activity).
So I need to
1) obtain the current Activity's View (which I'm doing with ((ViewGroup)findViewById(android.R.id.content)).getChildAt(0)) and
2) passing that View to a function in another class (defined below).
I've tried combining this and this but the bitmap I get is null after the .getDrawingCache() call so .compress bombs.
Here's the code:
public static void captureScreen(View v1){
View v1= v;
v1.setDrawingCacheEnabled(true);
Bitmap bm = v1.getDrawingCache();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, bytes);
} catch (Exception e1) {
Log.e("BM.Compress", e1.getMessage());
}
//create a new file name "test.jpg" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()
+ File.separator + context.getPackageName().replace(".", File.separator)
+ File.separator + "screenshots" + File.separator + "test.jpg");
//Log.d("CF", context.getPackageName());
try {
f.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//write the bytes in file
try {
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
LogCat:
06-06 16:37:14.613: D/AndroidRuntime(284): Shutting down VM
06-06 16:37:14.613: W/dalvikvm(284): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
06-06 16:37:14.768: E/AndroidRuntime(284): FATAL EXCEPTION: main
06-06 16:37:14.768: E/AndroidRuntime(284): java.lang.RuntimeException: Unable to start activity ComponentInfo{pkgname.pkgnameExpo/pkgname.pkgnameExpo.SplashActivity}: java.lang.NullPointerException: println needs a message
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.os.Handler.dispatchMessage(Handler.java:99)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.os.Looper.loop(Looper.java:123)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread.main(ActivityThread.java:4627)
06-06 16:37:14.768: E/AndroidRuntime(284): at java.lang.reflect.Method.invokeNative(Native Method)
06-06 16:37:14.768: E/AndroidRuntime(284): at java.lang.reflect.Method.invoke(Method.java:521)
06-06 16:37:14.768: E/AndroidRuntime(284): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-06 16:37:14.768: E/AndroidRuntime(284): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-06 16:37:14.768: E/AndroidRuntime(284): at dalvik.system.NativeStart.main(Native Method)
06-06 16:37:14.768: E/AndroidRuntime(284): Caused by: java.lang.NullPointerException: println needs a message
06-06 16:37:14.768: E/AndroidRuntime(284): at android.util.Log.println_native(Native Method)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.util.Log.e(Log.java:215)
06-06 16:37:14.768: E/AndroidRuntime(284): at pkgname.pkgnameExpo.Classes.CFunctions.captureScreen(CFunctions.java:432)
06-06 16:37:14.768: E/AndroidRuntime(284): at pkgname.pkgnameExpo.SplashActivity.onCreate(SplashActivity.java:38)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
06-06 16:37:14.768: E/AndroidRuntime(284): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
06-06 16:37:14.768: E/AndroidRuntime(284): ... 11 more
All I can tell from debug is that, before bm.compress is called, bm is null while v1 is not. Any ideas?
UPDATE Here's the new LogCat, which I think is telling me that it can't create the file?
06-06 22:13:55.975: I/System.out(12244): debugger has settled (1400)
06-06 22:13:58.351: E/BM.Compress(12244): nullfixnull
06-06 22:13:58.411: W/System.err(12244): java.io.IOException: No such file or directory
06-06 22:13:58.421: W/System.err(12244): at java.io.File.createNewFileImpl(Native Method)
06-06 22:13:58.432: W/System.err(12244): at java.io.File.createNewFile(File.java:1160)
06-06 22:13:58.432: W/System.err(12244): at pkgname.pkgnameExpo.Classes.CFunctions.captureScreen(CFunctions.java:441)
06-06 22:13:58.441: W/System.err(12244): at pkgname.pkgnameExpo.SplashActivity.onCreate(SplashActivity.java:38)
06-06 22:13:58.451: W/System.err(12244): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
06-06 22:13:58.451: W/System.err(12244): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
06-06 22:13:58.461: W/System.err(12244): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-06 22:13:58.461: W/System.err(12244): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-06 22:13:58.471: W/System.err(12244): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-06 22:13:58.471: W/System.err(12244): at android.os.Handler.dispatchMessage(Handler.java:99)
06-06 22:13:58.491: W/System.err(12244): at android.os.Looper.loop(Looper.java:123)
06-06 22:13:58.491: W/System.err(12244): at android.app.ActivityThread.main(ActivityThread.java:4627)
06-06 22:13:58.501: W/System.err(12244): at java.lang.reflect.Method.invokeNative(Native Method)
06-06 22:13:58.511: W/System.err(12244): at java.lang.reflect.Method.invoke(Method.java:521)
06-06 22:13:58.511: W/System.err(12244): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-06 22:13:58.522: W/System.err(12244): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-06 22:13:58.522: W/System.err(12244): at dalvik.system.NativeStart.main(Native Method)
06-06 22:13:58.531: W/System.err(12244): java.io.FileNotFoundException: /mnt/sdcard/pkgname/pkgnameExpo/screenshots/test.jpg (No such file or directory)
06-06 22:13:58.541: W/System.err(12244): at org.apache.harmony.luni.platform.OSFileSystem.openImpl(Native Method)
06-06 22:13:58.551: W/System.err(12244): at org.apache.harmony.luni.platform.OSFileSystem.open(OSFileSystem.java:152)
06-06 22:13:58.551: W/System.err(12244): at java.io.FileOutputStream.<init>(FileOutputStream.java:97)
06-06 22:13:58.561: W/System.err(12244): at java.io.FileOutputStream.<init>(FileOutputStream.java:69)
06-06 22:13:58.561: W/System.err(12244): at pkgname.pkgnameExpo.Classes.CFunctions.captureScreen(CFunctions.java:447)
06-06 22:13:58.571: W/System.err(12244): at pkgname.pkgnameExpo.SplashActivity.onCreate(SplashActivity.java:38)
06-06 22:13:58.571: W/System.err(12244): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
06-06 22:13:58.581: W/System.err(12244): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
06-06 22:13:58.581: W/System.err(12244): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
06-06 22:13:58.591: W/System.err(12244): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
06-06 22:13:58.591: W/System.err(12244): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
06-06 22:13:58.601: W/System.err(12244): at android.os.Handler.dispatchMessage(Handler.java:99)
06-06 22:13:58.601: W/System.err(12244): at android.os.Looper.loop(Looper.java:123)
06-06 22:13:58.612: W/System.err(12244): at android.app.ActivityThread.main(ActivityThread.java:4627)
06-06 22:13:58.612: W/System.err(12244): at java.lang.reflect.Method.invokeNative(Native Method)
06-06 22:13:58.621: W/System.err(12244): at java.lang.reflect.Method.invoke(Method.java:521)
06-06 22:13:58.631: W/System.err(12244): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
06-06 22:13:58.631: W/System.err(12244): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
06-06 22:13:58.641: W/System.err(12244): at dalvik.system.NativeStart.main(Native Method)