In my Fragment's layout i have a ScrollView with a LinearLayout inside
<ScrollView
android:id="#+id/scrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<LinearLayout
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<!-- Other views -->
</LinearLayout>
</ScrollView>
So i need to create and share a picture of entire content of scrollview. All solutions i've tried take screenshot only of the visible area, and not of entire scrollview content. How can i do?
I hope this is work for you.. source here. this is not technically a screenshot code. but this code convert the whole layout view into bitmap
Bitmap bitmap = getBitmapFromView(scrollview, scrollview.getChildAt(0).getHeight(), scrollview.getChildAt(0).getWidth());
//create bitmap from the ScrollView
private Bitmap getBitmapFromView(View view, int height, int width) {
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return bitmap;
}
call below method getYourLayout() where you want to take snap of your layout. In this i attach layout in one dialog & take snapshop of root layout whithout showing dialog to user. All thing happens in background.
private void getYourLayout() {
try {
Dialog fb_event_info = new Dialog(YourActivity.this);
fb_event_info.requestWindowFeature(Window.FEATURE_NO_TITLE);
fb_event_info.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
fb_event_info.setContentView(R.layout.yourXmlLayoutFile);
final LinearLayout lnr_fb_info = (LinearLayout) fb_event_info.findViewById(R.id.container);
TextView tv_fb_event_name = (TextView) fb_event_info.findViewById(R.id.tv_fb_event_name);
tv_fb_event_name.setTypeface(Global.setCubanoFont(EventDetailActivity.this));
tv_fb_event_name.setText(tv_event_name.getText().toString());
lnr_fb_info.setDrawingCacheEnabled(true);
lnr_fb_info.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
lnr_fb_info.layout(0, 0, lnr_fb_info.getMeasuredWidth(), lnr_fb_info.getMeasuredHeight());
lnr_fb_info.buildDrawingCache(true);
bitmap = Bitmap.createBitmap(lnr_fb_info.getDrawingCache());
saveImage(bitmap);
} catch (Exception e) {
}
}
This Function is for Saving your Bitmap as file.
private void saveImage(Bitmap bitmap) {
try {
Log.e("----------in---", "saveImage....: ");
if (!rootFile.exists())
rootFile.mkdirs();
long time = System.currentTimeMillis();
fname = "mynight-" + time + ".png";
rootFile = new File(rootFile, fname);
Log.e("----------in---", "saveImage...1.: ");
try {
FileOutputStream Fout = new FileOutputStream(rootFile);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, Fout);
sendShareFb();
Fout.flush();
Fout.close();
} catch (Exception e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
Below function is for share your image on facebook.
private void sendShareFb() {
try {
Log.e("----------in---", "sendShareFb....: ");
Intent fbIntent = new Intent(Intent.ACTION_SEND);
File imageFile = new File(rootFile.toString());
fbIntent.putExtra(Intent.EXTRA_TEXT, "Share..");
fbIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(imageFile));
fbIntent.setType("image/jpeg/png");
PackageManager pm = getPackageManager();
List<ResolveInfo> lract = pm.queryIntentActivities(fbIntent, PackageManager.MATCH_DEFAULT_ONLY);
boolean resolved = false;
for (ResolveInfo ri : lract) {
if (ri.activityInfo.name.toLowerCase().contains("facebook")) {
fbIntent.setClassName(ri.activityInfo.packageName, ri.activityInfo.name);
resolved = true;
break;
}
}
if (!resolved) {
Toast.makeText(EventDetailActivity.this, "Vous ne semblez pas avoir Facebook installé sur cet appareil", Toast.LENGTH_SHORT).show();
}
startActivity(resolved ? fbIntent : Intent.createChooser(fbIntent, "Choose one"));
} catch (final ActivityNotFoundException e) {
e.printStackTrace();
}
}
Sure that this will Help you. Because this solution has fixed my problem many time.
Related
Basically, I want to take a screenshot of an entire scrollView. I've tried so many methods, but couldn't find the perfect one.
I've tried following:
public void takeScreenShot() {
mbitmap = getBitmapOFRootView();
createImage(mbitmap);
}
public void createImage(Bitmap bmp) {
String path = Environment.getExternalStorageDirectory().toString() + "/screenshot.jpg";
try {
FileOutputStream outputStream = new FileOutputStream(new File(path));
bmp.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public Bitmap getBitmapOFRootView() {
mScrollView.setDrawingCacheEnabled(true);
int totalHeight = mScrollView.getChildAt(0).getHeight();
int totalWidth = mScrollView.getChildAt(0).getWidth();
mScrollView.layout(0,0, totalWidth, totalHeight);
mScrollView.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(mScrollView.getDrawingCache());
mScrollView.setDrawingCacheEnabled(false);
return b;
}
This method almost works, but it's just showing me only 2 views and a button, other than that whole screen is black:
my xml contains so many views, it's view hierarchy is something like this:
<ScrollView>
<ConstraintLayout>
<Views>
....
<Views>
</ConstraintLayout>
</ScrollView>
I've referred so many StackOverflow post, but it didn't work.
So can anybody help me with it?
Update:
Finally found a solution for it. So, it was an issue with the background, solved it by drawing canvas over it. Like below:
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return bitmap;
You should be using a canvas for the same
public static Bitmap saveBitmapFromView(View view, int width, int height) {
Bitmap bmp = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bmp);
view.layout(0, 0, view.getLayoutParams().width, view.getLayoutParams().height);
view.draw(canvas);
return bmp;
}
Taking and Sharing screenshot in android programmatically
I've searched everywhere but found this one working
takeAndShareScreenshot()
private void takeAndShareScreenshot(){
Bitmap ss = takeScreenshot();
saveBitmap(ss);
shareIt();
}
takeScreenshot()
private Bitmap takeScreenshot() {
View view = // decore view of the activity/fragment;
view.setDrawingCacheEnabled(true);
return view.getDrawingCache();
}
saveBitmap()
private void saveBitmap(Bitmap bitmap) {
// path to store screenshot and name of the file
imagePath = new File(requireContext().getExternalFilesDir(Environment.DIRECTORY_PICTURES) + "/" + "name_of_file" + ".jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
shareIt()
private void shareIt() {
try {
Uri uri = Uri.fromFile(imagePath);
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.setType("image/*");
String shareBody = getString(R.string.share_body_text);
sharingIntent.putExtra(Intent.EXTRA_SUBJECT, R.string.subject);
sharingIntent.putExtra(Intent.EXTRA_TEXT, shareBody);
sharingIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(sharingIntent, "Share via"));
} catch (Exception e) {
e.printStackTrace();
}
}
Note:
In recent versions of android (>Marshmallow I guess), you may need `write
access to external directory`
Question is already asked here : create PDF of RecyclerView in FULL length
And I also have same Question as i haven't found solution yet, I want to Generate PDF of RecyclerView Content with full length. but did't found solution.
I have already tried all the available solutions and all the possible ways to generate PDF from RecycleView.
Solutions which i have already tried :
https://gist.github.com/PrashamTrivedi/809d2541776c8c141d9a
Take a screenshot of RecyclerView in FULL length
Convert Listview Items into a single Bitmap Image
Have tried all solutions which mentioned above but any of them not working with me and getting error, sometime width & height issue or sometime getting empty white bitmap as output don't know why.
Problem :
I have RecyclerView with HTML Content as well as Images in between contents.
Consider Following Screen as RecyclerView with content.
having content in RecyclerView same as above image with 100+ items.
RecyclerView Item Layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:fresco="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/leftImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:adjustViewBounds="true"
android:maxHeight="350dp"
fresco:actualImageScaleType="fitCenter"
fresco:placeholderImage="#color/white" />
<jp.wasabeef.richeditor.RichEditor
android:id="#+id/editor"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="#dimen/margin10dp"
android:layout_marginRight="#dimen/margin10dp"
android:layout_weight="1"
android:clickable="false"
android:focusable="false"
android:focusableInTouchMode="false" />
<com.facebook.drawee.view.SimpleDraweeView
android:id="#+id/rightImage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_weight="1"
android:adjustViewBounds="true"
android:maxHeight="350dp"
fresco:actualImageScaleType="fitCenter"
fresco:placeholderImage="#color/white" />
</LinearLayout>
Update
As I was working on PDF to generate PDF from views, and was not able to generate PDF so I have posted this question.
But Now, I found a solution to generate PDF by using Webview you can see my answer on this question has marked as accepted.
Based on solution what I found, I have created a library to generate PDF from any String or Any HTML Content.
PDF-Generator Library: PDF-Generator
Thanks
I was looking at all the answers here, but unfortunately, they didn't work for me. I took the method for creating Bitmap from StackOverflow. The method takes the recycler view as an argument and converts it into a Bitmap which is then used by the PdfDocument.pageInfo to make it work for your needs. I tried it and it works perfectly for all the layouts such as relative layout and linear layout. Hope this will help.
Bitmap recycler_view_bm = getScreenshotFromRecyclerView(mRecyclerView);
try {
pdfFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(pdfFile);
PdfDocument document = new PdfDocument();
PdfDocument.PageInfo pageInfo = new
PdfDocument.PageInfo.Builder(recycler_view_bm.getWidth(), recycler_view_bm.getHeight(), 1).create();
PdfDocument.Page page = document.startPage(pageInfo);
recycler_view_bm.prepareToDraw();
Canvas c;
c = page.getCanvas();
c.drawBitmap(recycler_view_bm,0,0,null);
document.finishPage(page);
document.writeTo(fOut);
document.close();
Snackbar snackbar = Snackbar
.make(equipmentsRecordActivityLayout, "PDF generated successfully.", Snackbar.LENGTH_LONG)
.setAction("Open", new View.OnClickListener() {
#Override
public void onClick(View view) {
openPDFRecord(pdfFile);
}
});
snackbar.show();
} catch (IOException e) {
e.printStackTrace();
}
}
public Bitmap getScreenshotFromRecyclerView(RecyclerView view) {
RecyclerView.Adapter adapter = view.getAdapter();
Bitmap bigBitmap = null;
if (adapter != null) {
int size = adapter.getItemCount();
int height = 0;
Paint paint = new Paint();
int iHeight = 0;
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
// Use 1/8th of the available memory for this memory cache.
final int cacheSize = maxMemory / 8;
LruCache<String, Bitmap> bitmaCache = new LruCache<>(cacheSize);
for (int i = 0; i < size; i++) {
RecyclerView.ViewHolder holder = adapter.createViewHolder(view, adapter.getItemViewType(i));
adapter.onBindViewHolder(holder, i);
holder.itemView.measure(View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
holder.itemView.layout(0, 0, holder.itemView.getMeasuredWidth(), holder.itemView.getMeasuredHeight());
holder.itemView.setDrawingCacheEnabled(true);
holder.itemView.buildDrawingCache();
Bitmap drawingCache = holder.itemView.getDrawingCache();
if (drawingCache != null) {
bitmaCache.put(String.valueOf(i), drawingCache);
}
height += holder.itemView.getMeasuredHeight();
}
bigBitmap = Bitmap.createBitmap(view.getMeasuredWidth(), height, Bitmap.Config.ARGB_8888);
Canvas bigCanvas = new Canvas(bigBitmap);
bigCanvas.drawColor(Color.WHITE);
for (int i = 0; i < size; i++) {
Bitmap bitmap = bitmaCache.get(String.valueOf(i));
bigCanvas.drawBitmap(bitmap, 0f, iHeight, paint);
iHeight += bitmap.getHeight();
bitmap.recycle();
}
}
return bigBitmap;
}
Here is a samble code of generating a PDF from a view
//create bitmap from view and returns it
private Bitmap getBitmapFromView(View view) {
ScrollView hsv = (ScrollView) findViewById(R.id.scrollViewP);
HorizontalScrollView horizontal = (HorizontalScrollView) findViewById(R.id.hsv);
int totalHeight = hsv.getChildAt(0).getHeight();
int totalWidth = horizontal.getChildAt(0).getWidth();
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth, totalHeight,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;
}
private static void addImage(Document document,byte[] byteArray)
{
Image image = null;
try
{
image = Image.getInstance(byteArray);
}
catch (BadElementException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (MalformedURLException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
// image.scaleAbsolute(150f, 150f);
try
{
document.add(image);
} catch (DocumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void CreatePDF()
{
File folder = new File(Environment.getExternalStorageDirectory()+File.separator+"PDF Folder");
folder.mkdirs();
Date date = new Date() ;
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(date);
final File myFile = new File(folder + timeStamp + ".pdf");
try {
OutputStream output = new FileOutputStream(myFile);
Document document = new Document(PageSize.A4);
try{
PdfWriter.getInstance(document, output);
document.open();
LinearLayout view2 = (LinearLayout)findViewById(R.id.MainLayout);
view2.setDrawingCacheEnabled(true);
Bitmap screen2= getBitmapFromView(view2);
ByteArrayOutputStream stream2 = new ByteArrayOutputStream();
screen2.compress(Bitmap.CompressFormat.JPEG,100, stream2);
byte[] byteArray2 = stream2.toByteArray();
addImage(document,byteArray2);
document.close();
AlertDialog.Builder builder = new AlertDialog.Builder(PaySlip.this, R.style.AppCompatAlertDialogStyle);
builder.setTitle("Success")
.setMessage("enter code herePDF File Generated Successfully.")
.setIcon(android.R.drawable.ic_dialog_alert)
.setPositiveButton(android.R.string.ok,new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(myFile), "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intent);
}
}).show();
//document.add(new Paragraph(mBodyEditText.getText().toString()));
}catch (DocumentException e)
{
//loading.dismiss();
e.printStackTrace();
}
}catch (FileNotFoundException e)
{
// loading.dismiss();
e.printStackTrace();
}
}
Where view is the instance of RecyclerView:
view.measure(
View.MeasureSpec.makeMeasureSpec(view.getWidth(), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
myBitmap = Bitmap.createBitmap(view.getWidth(), view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
After lots of workaround and solutions i got solution, and Best approach to achieve this,
Add your content in webview in html form, From webview we can directly do print using Android's PrintManager class.
Like this :
String documentName = "yourDocumentName"; // you can provide any name
// Get a PrintManager instance
PrintManager printManager = (PrintManager) context.getSystemService(PRINT_SERVICE);
// Get a print adapter instance
PrintDocumentAdapter printAdapter = webView.createPrintDocumentAdapter(documentName);
PrintJob printJob = printManager.print(documentName, printAdapter, new PrintAttributes.Builder().build());
Above is sample code to do print of webview content, using this we can also generate PDF too.
For more info and use refer this Printing HTML Document
Thanks.
My code is as follow :
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button upload = (Button) findViewById(R.id.screeshotdButton);
upload.setOnClickListener(new Button.OnClickListener() {
#Override
public void onClick(View v) {
folderCheck();
}
});
}
private void folderCheck(){
File folder = new File(Environment.getExternalStorageDirectory() + "/cloze_screenshots");
boolean success = true;
// If the folder cloze not exist, create one
if (!folder.exists()) {
success = folder.mkdir();
}else{
ScreenShot();
}
// If mkdir successful
if (success) {
ScreenShot();
} else {
Log.e("mkdir_fail","QQ");
}
}
private void ScreenShot(){
String filePath = Environment.getExternalStorageDirectory()+ "/cloze_screenshots/temp.png";
// create bitmap screen capture
Bitmap bitmap;
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
File imageFile = new File(filePath);
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
Toast.makeText(this, "Success", Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This code can take a fullscreen screenshot , but I want to take a screenshot on specific area (For example, the left block on the screen ) programmatically after I press the button.
Any code or suggestion will be appreciate.
You can wrap the contents in a layout for example LinearLayout and follow the above code for taking screenshot by using the methods on the wrapped layout.
Bitmap bitmap;
ViewGroup v1 = findViewById(R.id.layout_id);
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
Below method takes snapshot of given view which is adjustable by means of height and width then returns bitmap of it
public static Bitmap takeSnapshot(View givenView, int width, int height) {
Bitmap bm = Bitmap.createBitmap(width , height, Bitmap.Config.ARGB_8888);
Canvas snap = new Canvas(bm);
givenView.layout(0, 0, givenView.getLayoutParams().width, givenView.getLayoutParams().height);
givenView.draw(snap);
return bm; }
Here is my Screenshot class. The app is saving the screenshot in my gallery, which is what I want, but the image is completely black! If you had any suggestions to make this work, they would be much appreciated! Thanks!
public class Screenshot extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// set event listener for the Save Contact Button
Button button =
(Button) findViewById(R.id.button);
button.setOnClickListener(buttonClicked);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.screenshot, menu);
return true;
}
// responds to event generated when user clicks the Done Button
OnClickListener buttonClicked = new OnClickListener()
{
#Override
public void onClick(View v)
{
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
};
public void saveBitmap(Bitmap bitmap) {
LinearLayout mainLayout = (LinearLayout) findViewById(R.id.LinearLayout01);
Bitmap b = Bitmap.createBitmap(mainLayout.getWidth(), mainLayout.getHeight(),
Bitmap.Config.ARGB_8888);
MediaStore.Images.Media.insertImage(getContentResolver(), b, "image.png" , "screenshot");
}
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
}
and here is my main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="#+id/LinearLayout01"
>
<Button
android:id="#+id/button"
android:layout_height = "wrap_content"
android:layout_width ="wrap_content"
android:text = "take screenshot"
android:onClick = "DoIt"
/>
<ImageView
android:id="#+id/eiffelTowerImageView"
android:layout_width="200dip"
android:layout_height="200dip"
android:layout_toRightOf="#+id/colosseumImageView"
android:src="#drawable/eiffeltower" />
</LinearLayout>
This Code Works like a Charm for me
private static Bitmap takeScreenShot(Activity activity) {
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int statusBarHeight = frame.top;
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay()
.getHeight();
Bitmap b = Bitmap.createBitmap(b1, 0, statusBarHeight, width, height
- statusBarHeight);
view.destroyDrawingCache();
Log.e("Screenshot", "taken successfully");
return b;
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory()
+ "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(CompressFormat.JPEG, 100, fos);
Log.e("Screenshot", "saved successfully");
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
Get Activity in OnCreate()
Activity activity = (MainActivity) this;
Then Call these Function where ever you want
Bitmap bitmap = takeScreenShot(activity);
saveBitmap(bitmap);
Your solution will only work for taking a screenshot of your own app (since it uses the app's drawing cache), so if that's what you want to do, you'll have to make sure it's visible on the screen. Anything that your app doesn't have permission to view (like another app running behind it) will not show up or, as you're seeing, will show up black.
I suggest you look at this other screenshot question here to see the constraints under which you're working. Primarily, since you presumably don't have root permissions or a signature application (which would only be true if you compiled your own ROM), then you can't capture the framebuffer, which is what the native Android screenshot mechanism in 4.0+ can do for you if you press a specific key combination (on my Galaxy Nexus it's power+volume down).
Try this code :
public class MainActivity extends Activity {
Button btn_shoot;
int i = 0;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btn_shoot = (Button)findViewById(R.id.btn_shoot);
btn_shoot.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
View view = findViewById(R.id.relativelayout);
view = view.getRootView();
view.setDrawingCacheEnabled(true);
view.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
Bitmap bitmap = view.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bitmap);
ImageView iv = (ImageView) findViewById(R.id.imageView1);
iv.setBackgroundDrawable(bitmapDrawable);
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
//we check if external storage is available, otherwise display an error message to the user
File sdCard = Environment.getExternalStorageDirectory();
File directory = new File (sdCard.getAbsolutePath() + "/Tutorial_ScreenShot");
directory.mkdirs();
String filename = "screenshot" + i + ".jpg";
File yourFile = new File(directory, filename);
while (yourFile.exists()) {
i++;
filename = "screenshot" + i + ".jpg";
yourFile = new File(directory, filename);
}
if (!yourFile.exists()) {
if (directory.canWrite())
{
try {
FileOutputStream out = new FileOutputStream(yourFile, true);
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
Toast.makeText(MainActivity.this, "File exported to /sdcard/Tutorial_ScreenShot/screenshot" + i + ".jpg", Toast.LENGTH_SHORT).show();
i++;
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
else
{
Toast.makeText(MainActivity.this, "SD Card not available!", Toast.LENGTH_SHORT).show();
}
}
});
}
}
I use below code to convert, but it seems can only get the content in the display screen and can not get the content not in the display screen.
Is there a way to get all the content even out of scroll?
Bitmap viewBitmap = Bitmap.createBitmap(mScrollView.getWidth(),mScrollView.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(viewBitmap);
mScrollView.draw(canvas);
We can convert all the contents of a scrollView to a bitmap image using the code shown below
private void takeScreenShot()
{
View u = ((Activity) mContext).findViewById(R.id.scroll);
HorizontalScrollView z = (HorizontalScrollView) ((Activity) mContext).findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap b = getBitmapFromView(u,totalHeight,totalWidth);
//Save bitmap
String extr = Environment.getExternalStorageDirectory()+"/Folder/";
String fileName = "report.jpg";
File myPath = new File(extr, fileName);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(myPath);
b.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
MediaStore.Images.Media.insertImage(mContext.getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
The Pops answer is really good, but in some case you could have to create a really big bitmap which could trigger a OutOfMemoryException when you create the bitmap.
So I made a little optimization to be gently with the memory :)
public static Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
int height = Math.min(MAX_HEIGHT, totalHeight);
float percent = height / (float)totalHeight;
Bitmap canvasBitmap = Bitmap.createBitmap((int)(totalWidth*percent),(int)(totalHeight*percent), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(canvasBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
canvas.save();
canvas.scale(percent, percent);
view.draw(canvas);
canvas.restore();
return canvasBitmap;
}
This one works for me
To save the bitmap check runtime permission first
#OnClick(R.id.donload_arrow)
public void DownloadBitMap()
{
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
{
downloadData();
Log.e("callPhone: ", "permission" );
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
Toast.makeText(this, "need permission", Toast.LENGTH_SHORT).show();
}
}
To get bitmap
private void downloadData() {
ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
Bitmap bitmap = Bitmap.createBitmap(
iv.getChildAt(0).getWidth()*2,
iv.getChildAt(0).getHeight()*2,
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
c.scale(2.0f, 2.0f);
c.drawColor(getResources().getColor(R.color.colorPrimary));
iv.getChildAt(0).draw(c);
// Do whatever you want with your bitmap
saveBitmap(bitmap);
}
To save the bitmap
public void saveBitmap(Bitmap bitmap) {
File folder = new File(Environment.getExternalStorageDirectory() +
File.separator + "SidduInvoices");
boolean success = true;
if (!folder.exists()) {
success = folder.mkdirs();
}
if (success) {
// Do something on success
} else {
// Do something else on failure
}
File imagePath = new File(Environment.getExternalStorageDirectory() + "/SidduInvoices/Siddus.png");
if(imagePath.exists())
{
imagePath=new File(Environment.getExternalStorageDirectory() + "/SidduInvoices/Siddus"+custamername.getText().toString()+".png");
}
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
progressBar.cancel();
final File finalImagePath = imagePath;
new SweetAlertDialog(this, SweetAlertDialog.SUCCESS_TYPE)
.setTitleText("Saved")
.setContentText("Do you want to share this with whatsapp")
.setCancelText("No,cancel !")
.setConfirmText("Yes,share it!")
.showCancelButton(true)
.setConfirmClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sweetAlertDialog) {
sweetAlertDialog.cancel();
shareImage(finalImagePath);
}
})
.setCancelClickListener(new SweetAlertDialog.OnSweetClickListener() {
#Override
public void onClick(SweetAlertDialog sDialog) {
sDialog.cancel();
}
})
.show();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
You need get the total width and height of the scrollview, or you created viewBitmap is too small to contain the full content of the scrollview.
check this link
Android: Total height of ScrollView
The issue here is that the only actual pixel content that ever exists is that which is visible on the display screen. Android and other mobile platforms are very careful about memory use and one of the ways a scrolling view can maintain performance is to not draw anything that is offscreen. So there is no "full" bitmap anywhere -- the memory containing the content that moves offscreen is recycled.