android taking screenshot of offscreen page
Well I have achieved what I want. These are the steps I used.
Start activity B with startActivityForResult() instead of
startActivity().Intent bIntent = new Intent(A.this,B.class);
startActivityForResult(bIntent,B_REQUEST_CODE);In onCreate of activity B take mainLayout of B and enable its
drawing cachefinal LinearLayout layout = (LinearLayout)
findViewById(R.id.app_parent_layout);
layout.setDrawingCacheEnabled(true);
layout.setDrawingCacheQuality(LinearLayout.DRAWING_CACHE_QUALITY_HIGH);In activity B wait till its layout is drawn completely(This is very
important). For that in onCreate() of activity B, get mainLayout of
B, use ViewTreeObserver to get a call back when its layout is drawn
completely.ViewTreeObserver vto = layout.getViewTreeObserver();
vto.addOnGlobalLayoutListener(new OnGlobalLayoutListener() {
@Override
public void onGlobalLayout() {
layout.getViewTreeObserver().removeGlobalOnLayoutListener(this);
getDrawingBitmap();
}
});Now getDrawingBitmap() gets called when layout is drawn completely.
There take your screenshot.public void getDrawingBitmap(){
LinearLayout mainLayout = (LinearLayout)
findViewById(R.id.app_parent_layout);
Bitmap b = mainLayout.getDrawingCache();
File file = saveBitmapAsFile(b);
Intent resultIntent = new Intent();
resultIntent.putExtra("FullFileName",file.getAbsolutePath());
setResult(Activity.RESULT_OK,resultIntent);
finish();
}Here I am taking bitmap and saving it as a file and returning the
filename as a result code. I am sure there are better method to send
the bitmap to parent activity than saving as a file and sending
filename. But I have a requirement anyway to save bitmap for
sometime. So For me this is the easier method. After setting result
finish activity.Now on Activity A onActivityResult() retrieve the filename.
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == B_REQUEST_CODE){
if (resultCode == Activity.RESULT_OK) {
String newText = data.getStringExtra("FullFileName");
File dir = new File (newText);
}
}
}
screenshot of all Views in ViewPager
If you don't set offScreenPageLimit(totalPages)
, ViewPager
will initially only load 1 more page other than you see. That means other pages will not be even created until you swipe there. That also means you cannot take screenshot of a screen/layout that is not created/inflated yet. And yes, it is not a good practice memorywise to set offscreen page limit to a number that ViewPager
loads all pages at start.
Answer: No, if you mind your memory consumption. Otherwise, yes.
Taking a screenshot of a specific layout in Android
Thanks to you guys, I've finally found out what was wrong.
View v = view.getRootView();
should not be used because it will call the root view which I do not want. I mistakenly thought this did not make a difference because I had entered the wrong resource ID.
MeasureSpec
somehow did not give a good account of the width and height. So I ended up using another method:
...
ScrollView z = (ScrollView) findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
...
As ScrollView's total height can be determined by the single child element that it has.
After making these changes, I am now able to take a screenshot of a nested ScrollView and all its contents, visible or not. For anyone interested, here is the block of code including the saving of the bitmap:
View u = findViewById(R.id.scroll);
u.setDrawingCacheEnabled(true);
ScrollView z = (ScrollView) findViewById(R.id.scroll);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
u.layout(0, 0, totalWidth, totalHeight);
u.buildDrawingCache(true);
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
u.setDrawingCacheEnabled(false);
//Save bitmap
String extr = Environment.getExternalStorageDirectory().toString() + File.separator + "Folder";
String fileName = new SimpleDateFormat("yyyyMMddhhmm'_report.jpg'").format(new Date());
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(getContentResolver(), b, "Screen", "screen");
}catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Take a screenshot of a whole View
Actually I found the answer:
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
Capture screenshot of a HorizontalScrollView including offscreen elements
Found a SIMPLE way to do it.
XML
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:layout_gravity="center_vertical">
<HorizontalScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:id="@+id/def"
>
<Button
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="capture"
android:onClick="click"/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/black"
android:id="@+id/img"/>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/a"/>
</LinearLayout>
</HorizontalScrollView>
</LinearLayout>
Acivity Code:
public class CaptureBeyondActivity extends Activity {
/** Called when the activity is first created. */
LinearLayout def;
ImageView img;
HorizontalScrollView hsv;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
def = (LinearLayout)findViewById(R.id.def);
img = (ImageView)findViewById(R.id.img);
}
public void click(View v) {
Bitmap bitmap;
def.setDrawingCacheEnabled(true);
def.buildDrawingCache(true);
bitmap = Bitmap.createBitmap(def.getWidth(), def.getHeight(),
Config.ARGB_8888);
def.layout(0, 0, def.getLayoutParams().width,
def.getLayoutParams().height);
Canvas c = new Canvas(bitmap);
def.draw(c);
def.setDrawingCacheEnabled(false);
if(bitmap!=null){
img.setImageBitmap(bitmap);
img.invalidate();
}
}}
Here I have placed some elements in a HorizontalScrollView. OnClick of the button a screenshot is taken and the second image is replaced by the screenshot taken.
It takes screenshots of the offscreen elements also. You can further enhance the code and save the final bitmap image on SD card.
Related Topics
How to Compile a Static Library Using the Android Ndk
How to Use the Android Accelerometer
Can't Upgrade Android Sdk Tools
Don't Keep Activities - What Is It For
Adding Watermark Bitmap Over Video in Android: 4.3's Mediamuxer or Ffmpeg
How to Delete Other Applications Cache from Our Android App
How to Resolve Dependency for ':App@Debug/Compileclasspath': Could Not Resolve
How to Pause Flash Content in an Android Webview When My Activity Isn't Visible
How to Measure Textview Height Based on Device Width and Font Size
How to Programmatically Add a Submenu Item to the New Material Design Android Support Library
Java.Lang.Securityexception: !@Too Many Alarms (500) Registered from Pid 10790 Uid 10206
How to Make an Fm Radio Application in Android
Android Sdk Cut/Trim Video File
Mylib.So Has Text Relocations. This Is Wasting Memory and Is a Security Risk. Please Fix