How To Programmatically Take A Screenshot in Android
How To Programmatically Take A Screenshot in Android
x Dismiss
Sign up
How can I take a screenshot of a selected area of phone-screen not by any program but
from code?
android screenshot
3 Not from emulator. I need to make screenshot of part of my programm, and do smth with it in the same
programm. – shtpavel Apr 18 '10 at 8:25
17 Answers
Here is the code that allowed my screenshot to be stored on sd card and used later for
whatever your needs are:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now +
".jpg";
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
And this is how you can open the recently generated image:
View v1 = getActivity().getWindow().getDecorView().getRootView();
instead of
View v1 = getWindow().getDecorView().getRootView();
on takeScreenshot() function
18 this just takes a screenshot of your own program (right?) – Team Pannous Jan 19 '12 at 15:01
21 Hi, Can you describe what is mCurrentUrlMask? I have tried this code but it is always giving me
NullPointerException at Bitmap.createBitmap(v1.getDrawingCache()), Can anybody tell what I am doing
wrong.? Any help is appreciated. Thanks. – Mitesh Sardhara Apr 29 '13 at 19:30
6 Can you please tell me what is, mCurrentUrlMask? – Jayesh Sojitra Oct 25 '13 at 11:12
5 This answer takes a screenshot of just the app - not the "phone screen" as asked in the question - or am I
doing something wrong. – AlikElzin-kilaka Dec 16 '15 at 3:48
Call this method, passing in the outer most ViewGroup that you want a screen shot of:
5 This is seems to be cleaner code than the accepted answer. Does it perform as well? – jophde Nov 30 '14 at
5:55
2 I've used it for a while in a few different apps and haven't had any issues. – JustinMorris Dec 4 '14 at 20:43
1 If you want to get a screenshot of the phone, where your app is in the background, what do you pass as the
view ?` – AlikElzin-kilaka Dec 15 '15 at 12:06
This answer takes a screenshot of just the app - not the "phone screen" as asked in the question - or am I
doing something wrong. – AlikElzin-kilaka Dec 16 '15 at 3:49
3 Yes you need root access. Please check the Note at the heading – Viswanath Lekshmanan Nov 14 '14 at
9:19
Hi, I got a System.err : java.io.IOException: Error running exec(). Command: [su] Working
Directory: null Environment: null , my device is android 5.0 – Eddy Jun 23 '15 at 9:14
EDIT: have mercy with the downvotes. It was true in 2010 when I answered the
question.
All the programs which allow screenshots work only on rooted phones.
It looks that these days it's possible on Androids with Tegra based chipset – GDR Dec 27 '11 at 23:05
1 My tablet running 4.0.3 allows screen shots, not rooted, Acer Iconia A500... – FabianCook Sep 4 '12 at
21:07
4.0.3 - then it's probably one of these new-school tegra tablets – GDR Sep 5 '12 at 11:32
2 Strictly speaking, along with root ADB's "shell" user account has always had permission to do this as that
was the intended use case. What was not historically available (except on occasional builds as a mistake)
was a way for application user id's to do so. – Chris Stratton Apr 30 '15 at 19:20
Mualig answer is very good, but I had the same problem Ewoks describes, I'm not getting the
background. So sometimes is good enough and sometimes I get black text over black
background (depending on the theme).
This solution is heavily based in Mualig code and the code I've found in Robotium. I'm
discarding the use of drawing cache by calling directly to the draw method. Before that I'll try to
get the background drawable from current activity to draw it first.
// Some constants
final static String SCREENSHOTS_LOCATIONS =
Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
I have a listview with android:cacheColorHint="#00000000" in my activity , and I use this code to screenshot ,
I still got a black background , because I found that background that get from theme is black , how can I deal
with this listview? – Wangchao0721 Sep 22 '12 at 14:47
Activity activity = getCurrentActivity giving Eroor undefined method. – Shabbir Dhangot Aug 26 '14 at 7:14
On adb shell using below command you can take screen shot.
This command does not required any root permission so same you can perform from java
code of android application also.
Process process;
process = Runtime.getRuntime().exec("input keyevent 120");
Here we have used. KEYCODE_SYSRQ its value is 120 and used for System Request / Print
Screen key.
The output picture will be saved here: /sdcard/Pictures/Screenshots – CJBS Apr 29 '15 at 23:00
1 will it works on marshmallow ? or will it works in service background @JeegarPatel – Karandeep Atwal Dec
6 '16 at 19:31
1 not worked programmatically, but works from shell. Tried with nougat. – mehmet6parmak Jan 29 at 20:43
As a reference, one way to capture the screen (and not just your app activity) is to capture the
framebuffer (device /dev/graphics/fb0). To do this you must either have root privileges or your
app must be an app with signature permissions ("A permission that the system grants only if
the requesting application is signed with the same certificate as the application that declared
the permission") - which is very unlikely unless you compiled your own ROM.
Each framebuffer capture, from a couple of devices I have tested, contained exactly one
screenshot. People have reported it to contain more, I guess it depends on the frame/display
size.
I tried to read the framebuffer continuously but it seems to return for a fixed amount of bytes
read. In my case that is (3 410 432) bytes, which is enough to store a display frame of 854*480
RGBA (3 279 360 bytes). Yes, the frame, in binary, outputted from fb0 is RGBA in my device.
This will most likely depend from device to device. This will be important for you to decode it =)
In my device /dev/graphics/fb0 permissions are so that only root and users from group
graphics can read the fb0.
graphics is a restricted group so you will probably only access fb0 with a rooted phone using
su command.
Android apps have the user id (uid) = app_## and group id (guid) = app_## .
adb shell has uid = shell and guid = shell, which has much more permissions than an app.
You can actually check those permissions at /system/permissions/platform.xml
This means you will be able to read fb0 in the adb shell without root but you will not read it
within the app without root.
1 This works (worked?) on some phones, but note that GPU based phones don't necessarily provide a linear
framebuffer to the applications processor. – Chris Stratton Mar 27 '14 at 14:51
1 I tried this.but it takes screenshot of the running app alone. Its cant help if i want to take screenshot of the
homescreen. do you how to take screenshot of the homescreen withthat code? – Jana Oct 15 '10 at 7:14
1 @Janardhanan.S: This is what the question is asking for. Can you elaborate with a new answer instead of
asking a separate question. – trgraglia Feb 8 '11 at 8:28
3 Same Problem with me.. "Native Service Not Running!!" – Yogesh Maheshwari Aug 17 '12 at 10:57
1 Same with me "Native Service Not Running!!".... can anybody add the help text here? – Pankaj Kumar Jun
20 '13 at 9:59
1 same here! "Native Service Not Running!!" and in their latest version 1.2 they use API LEVEL 19 classes,
like Socket for example. – user347187 Apr 15 '14 at 7:42
+ System.currentTimeMillis() + ".png"));
bmp.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
2 This answer takes a screenshot of just the app - not the "phone screen" as asked in the question - or am I
doing something wrong? – AlikElzin-kilaka Dec 16 '15 at 3:56
What about If I need screenshot of an item of listview? – Anshul Tyagi Feb 12 '16 at 10:20
i want to capture in from adapter any idea how can i do it? – Deep Dave Jun 18 '16 at 11:36
My solution is:
return returnedBitmap;
}
and
1 You should close the FileOutputStream in a finally block. If you encounter an exception now the stream will
not be closed. – Wotuu May 1 '14 at 9:31
1 why do you use v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight()); ? Doesn't that change the
view (v) ? – serj Jan 28 '16 at 16:23
Getting a bitmap cache from a layout or a view by doing something like First you gotta
then
Bitmap bm = layout.getDrawingCache()
Then you do whatever you want with the bitmap. Either turning it into an image file, or send the
bitmap's uri to somewhere else.
1 This is the best method if it is your app that you are writing to a bitmap. Also, beware of methods which have
delays before taking the cache... like Notify...() for list views. – trgraglia Mar 6 '11 at 19:13
Not just that. The layout must be displayed on the screen first. It's the "cache" you're getting afterall. Tried
hiding the view and taking screenshots in the background(in theory), but it didn't work. – Kevin Tan Mar 14
'11 at 8:51
By far more efficient than other solutions – sivi Aug 18 '15 at 12:03
@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);
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();
}
}
});
if(v!=null) {
screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(),
Config.ARGB_8888);
Canvas canvas = new Canvas(screenshot);
v.draw(canvas);
}
return screenshot;
}
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
ADD PERMISSION
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
This answer takes a screenshot of just the app - not the "phone screen" as asked in the question - or am I
doing something wrong? – AlikElzin-kilaka Dec 16 '15 at 3:59
For those who want to capture a GLSurfaceView, the getDrawingCache or drawing to canvas
method won't work.
You have to read the content of the OpenGL framebuffer after the frame has been rendered.
There is a good answer here
I have created a simple library that takes a screenshot from a View and either gives you a
Bitmap object or saves it directly to any path you want
https://github.com/abdallahalaraby/Blink
return bitmap;
}
drawing canvas with white color in case background is null did the trick for me. Thanks Oliver – Shaleen Jun
25 '15 at 10:57
1. 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;
}
3. method shareScreenShotM)() :
public void shareScreenShotM(View view, NestedScrollView scrollView){
4. 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;
}
5. method savePic():
public static File savePic(Bitmap bm){
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;
}
if you want to capture a view or layout like RelativeLayout or LinearLayout etc. just use
the code :