I'm developing an application for taking screenshots in the device. In this application, we can draw anything on the screen. For this I am using Canvas, Paint and Path to do this.
I'm using this code to take screenshots:
public void saveScreenshot()
{
if (ensureSDCardAccess())
{
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
onDraw(canvas);
File file = new File(mScreenshotPath + "/" + System.currentTimeMillis() + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.close();
} catch (FileNotFoundException e) {
Log.e("Panel", "FileNotFoundException", e);
} catch (IOException e) {
Log.e("Panel", "IOEception", e);
}
}
}
/**
* Helper method to ensure that the given path exists.
* TODO: check external storage state
*/
private boolean ensureSDCardAccess() {
File file = new File(mScreenshotPath);
if (file.exists()) {
return true;
} else if (file.mkdirs()) {
return true;
}
return false;
}
However, when the following line is run:
Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
my application closes with the following exception:
11-28 15:05:46.291: E/AndroidRuntime(8209): java.lang.IllegalArgumentException: width and height must be > 0
If I change the height and width, the screenshot is taken, but it's empty:
Why is that happening? What am I doing wrong?
You can do it like this,
Give the id for your main Layout & after you display the content on the screen write the below code on some Listener say button click or menu item or any such Listener(make sure you call these line after your layout is display else it will give a blank screen).
View content = findViewById(R.id.myLayout);
content.setDrawingCacheEnabled(true);
getScreen(content);
method getScreen(content)
private void getScreen(View content)
{
Bitmap bitmap = content.getDrawingCache();
File file = new File("/sdcard/test.png");
try
{
file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
bitmap.compress(CompressFormat.PNG, 100, ostream);
ostream.close();
}
catch (Exception e)
{
e.printStackTrace();
}
}
Also don't for to add permission for writing file to SDCard.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
</uses-permission>
Exception is because the height and width of Bitmap
you are creating is zero
try below code to get height and width
Display display = getWindowManager().getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
In case there is no access to getWindowManager
Display display = ((WindowManager) context.getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay();
int width = display.getWidth();
int height = display.getHeight();
getWidth(), getHeight() required to be called with context, if your are trying it outside Activity it will fail. Try getApplicationContext.getWidth().
Could you show more of your code pls? It seems like you are calling width and height have not positive integer values. You could debug this by printing the values of width and height.
I faced a similar issue and the solution was:
You get width and heigh before your view is drown so check first if width or heigh equal zero:
if (getWidth() == 0 || getHeight() == 0) {
initRemote(remote);
isViewInitialized=false;
}
isViewInitialized is a member value.
Then put this code in OnSizeChanged
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
if(!isViewInitialized&&){
// this is the right place to take snapshot :)
}
}
I have wrapped the screenshot code into a very simple library. It allows you to take screenshots and store them to the disk if you want.
https://github.com/abdallahalaraby/Blink