I am trying to take screenshot of my app screen programatically. The Layout file has some ImageButtons and a Textview field. When the capture screen happens, the resulted image contains the buttons too. Is there a way to take screenshot without the imagebuttons?
Below are the code snippet and layout files
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:ads="http://schemas.android.com/apk/res-auto"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="xyz.abc.def.MainActivity">
<include
layout="#layout/buttons_layout"
android:id="#+id/includedLayout"
android:visibility="visible"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="Hello World!"
android:id="#+id/text1"
android:gravity="center"
android:textSize="32dp"
android:shadowColor="#edeff2"
android:textStyle="bold"
android:shadowDx="0.0"
android:shadowDy="0.0"
android:shadowRadius="25"
/>
</RelativeLayout>
button_layout.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:id="#+id/buttonLayout"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="right"
>
<ImageButton
android:id="#+id/refreshButton"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_margin="10dp"
android:background="#drawable/refresh"
/>
<ImageButton
android:id="#+id/shareButton"
android:layout_width="35dp"
android:layout_height="35dp"
android:layout_margin="10dp"
android:background="#drawable/share"
/>
</LinearLayout>
</LinearLayout>
Code to take screenshot
private void captureScreen() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
String filePath = Environment.getExternalStorageDirectory() + File.separator +now+".jpg";
View view = findViewById(R.id.activity_main);
view.setDrawingCacheEnabled(true);
mBitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
File imagePath = new File(filePath);
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
sendScreen(filePath);
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
Any help will be appreciated. Thanks :)
If it is just the text view you want as I can see it is full screen.
Try using
View view = findViewById(R.id.text1); // instead of R.id.activity_main
view.setDrawingCacheEnabled(true);
Basically point is keep those views in separate container whose screen shot you want and then get the drawable of that particular container.
You can make the image button invisible just before taking the screenshot and then make it visible.
private void captureScreen() {
//make unwanted views invisible
findViewById(R.id.refreshButton).setVisibility(View.INVISIBLE);
findViewById(R.id.shareButton).setVisibility(View.INVISIBLE);
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
String filePath = Environment.getExternalStorageDirectory() + File.separator +now+".jpg";
View view = findViewById(R.id.activity_main);
view.setDrawingCacheEnabled(true);
mBitmap = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
File imagePath = new File(filePath);
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
mBitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
fos.flush();
fos.close();
sendScreen(filePath);
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
//make those views visible again
findViewById(R.id.refreshButton).setVisibility(View.VISIBLE);
findViewById(R.id.shareButton).setVisibility(View.VISIBLE);
}
Related
I have recently started using ConstraintLayout and am loving it. But have come across a problem to be solved. Need to take a screenshot of a part view of the layout and that is easy in relative or linear layout as we make a layout around the view needed screenshot which is not the case in ConstraintLayout.
This is my view :
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white">
<View
android:id="#+id/sharable_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#+id/tv_streak_best"
app:layout_constraintLeft_toLeftOf="#id/total_distance_steps_left_guideline"
app:layout_constraintRight_toRightOf="#id/total_distance_steps_right_guideline"
app:layout_constraintTop_toTopOf="parent" />
<ProgressBar
android:id="#+id/streak_progress"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="0dp"
android:layout_height="0dp"
android:max="360"
android:progress="0"
android:progressDrawable="#drawable/progress_gradient_bg"
android:secondaryProgress="360"
app:layout_constraintBottom_toBottomOf="#id/streak_bottom_guideline"
app:layout_constraintDimensionRatio="1"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<com.sharesmile.share.views.LBTextView
android:id="#+id/tv_streak_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0"
android:textColor="#color/clr_5d"
android:textSize="58sp"
app:layout_constraintBottom_toBottomOf="#id/streak_progress"
app:layout_constraintLeft_toLeftOf="#id/streak_progress"
app:layout_constraintRight_toRightOf="#id/streak_progress"
app:layout_constraintTop_toTopOf="#id/streak_progress"
app:layout_constraintVertical_bias="0.35" />
<com.sharesmile.share.views.LBITextView
android:id="#+id/tv_streak_count_days"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:text="#string/day_streak"
android:textColor="#color/clr_5d"
android:textSize="20sp"
app:layout_constraintLeft_toLeftOf="#id/streak_progress"
app:layout_constraintRight_toRightOf="#id/streak_progress"
app:layout_constraintTop_toBottomOf="#+id/tv_streak_count" />
<LinearLayout
android:id="#+id/streak_goal_icons_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="3dp"
android:orientation="horizontal"
app:layout_constraintLeft_toLeftOf="#id/tv_streak_count_days"
app:layout_constraintRight_toRightOf="#id/tv_streak_count_days"
app:layout_constraintTop_toBottomOf="#id/tv_streak_count_days">
</LinearLayout>
... more code here
</android.support.constraint.ConstraintLayout>
Now I wish to take screen shot of the progressbar and few elements below it. I tried to create a view around it and take screenshot of that but it doesn't work. What can be done to take the screenshot?
You can use
tools:visibility="gone"
to hide the view as below
<View
android:id="#+id/sharable_container"
android:layout_width="0dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="#+id/tv_streak_best"
app:layout_constraintLeft_toLeftOf="#id/total_distance_steps_left_guideline"
app:layout_constraintRight_toRightOf="#id/total_distance_steps_right_guideline"
app:layout_constraintTop_toTopOf="parent"
tools:visibility="gone" />
add below as attribute at root view
xmlns:tools="http://schemas.android.com/tools"
Do not need to hide/show your view
private void captureScreen(View v) {
v.setDrawingCacheEnabled(true);
Bitmap bitmap = v.getDrawingCache();
String extr = Environment.getExternalStorageDirectory().toString();
File file = new File(extr, "fff" + ".jpg");
FileOutputStream f = null;
try {
f = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, f);
f.flush();
f.close();
MediaStore.Images.Media.insertImage(getContentResolver(), bitmap, "Screen", "screen");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
pass your view to above function
captureScreen(view you want to take a screen shot);
I want to display an image to be fullscreen :
public class PhotoPleinEcranActivity extends Activity {
private Bundle data;
private ImageView img;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.photo_plein_ecran);
img = (ImageView)findViewById(R.id.zoom);
BitmapFactory.Options bfOptions = new BitmapFactory.Options();
bfOptions.inDither = true; //Disable Dithering mode
bfOptions.inPurgeable = true; //Tell to gc that whether it needs free memory, the Bitmap can be cleared
bfOptions.inInputShareable = true; //Which kind of reference will be used to recover the Bitmap data after being clear, when it will be used in the future
bfOptions.inTempStorage = new byte[32 * 1024];
data = getIntent().getExtras();
FileInputStream fs = null;
Bitmap bm;
try {
fs = new FileInputStream(new File(data.getString("path")));
if(fs != null) {
bm = BitmapFactory.decodeFileDescriptor(fs.getFD(), null, bfOptions);
img.setImageBitmap(bm);
}
} catch (IOException e) {
} finally {
if(fs != null) {
try {
fs.close();
} catch (IOException e) {
}
}
}
}
}
The layout :
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
android:paddingTop="0dip"
android:paddingBottom="0dip"
android:orientation="horizontal">
<ImageView
android:id="#+id/zoom"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
android:paddingTop="0dip"
android:paddingBottom="0dip"
/>
</LinearLayout>
Manifest file :
<activity
android:name="com.ambre.impots.PhotoPleinEcranActivity"
android:label="#string/galleryPhotos"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
</activity>
At runtime there is a grey field at the bottom of the image ( I surrounded the grey field by a yellow color ) :
So how to make that grey field disappear ?
This will solve your problem.
Add below line in ImageView.
android:scaleType="fitXY"
add android:scaleType="fitXY" to your ImageView, fitXY, will fill width and height independently to match the destination
add property scaleType to fitXY like this
<ImageView
android:id="#+id/zoom"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginTop="0dip"
android:layout_marginBottom="0dip"
android:paddingTop="0dip"
android:paddingBottom="0dip"
android:scaleType="fitXY" />
Change your image view like this
<ImageView
android:id="#+id/zoom"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_marginBottom="0dip"
android:layout_marginTop="0dip"
android:adjustViewBounds="true"
android:paddingBottom="0dip"
android:paddingTop="0dip"
android:scaleType="fitXY" />
The webview on my application becomes quite long. I want the user to be able to save the webview as image to enable sharing.
It is working right now but the code generates a long image. I want make the height\width propotional before saving e.g. 800\600 etc.
Not sure how to do it??
This is how I am saving the jpg:
Picture picture = webview.capturePicture();
Bitmap b = Bitmap.createBitmap(picture.getWidth(), picture.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
picture.draw(c);
FileOutputStream fos = null;
try {
File file = new File(pathName);
file.createNewFile();
fos = new FileOutputStream(file);
if (fos != null) {
b.compress(Bitmap.CompressFormat.JPEG, 90, fos);
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
}
}
and the layout is like this:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:id="#+id/a_layout"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<LinearLayout
android:id="#+id/fullscreen_content_controls"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true">
<Button
android:id="#+id/reload"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="#string/reload" />
</LinearLayout>
<WebView
android:layout_width="fill_parent"
android:id="#+id/webview"
android:layout_above="#id/fullscreen_content_controls"
android:layout_alignParentTop="true"
android:layout_height="fill_parent" />
</RelativeLayout>
I am working with map and trying to create marker as Drawable object from my layout file.
I need my marker view to change depends on the the type of point, and hence i declared my first image as static and my second image as dynamic(Change dynamically),but it is not working.
My layout file
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
<ImageView
android:id="#+id/marker"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="#drawable/marker" >
</ImageView>
<ImageView
android:id="#+id/category"
android:layout_width="10dp"
android:layout_height="10dp"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:src="#drawable/category_for_children" />
</RelativeLayout>
My code:
Resources res = getResources();
try {
marker = Drawable.createFromXml(res, res.getXml(R.layout.marker_on_map));
} catch (NotFoundException e) {
e.printStackTrace();
} catch (XmlPullParserException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Drawable.createFromXml is not for loading Layouts or View into drawable!!
see this sample of its usage:
http://spearhend.blogspot.com/2012/04/load-android-drawable-from-xml.html
I have an ImageView (image_view) in an xml and I have the layout gravity set to center and the scale set to center_inside....but when I pass my compressed bmp to the image_view, it puts it on the middle-left of the screen (in portrait mode)...any ideas on a workaround?
here is me setting it to the image view:
ImageView imageView = (ImageView) findViewById(R.id.image_view);
imageView.setImageBitmap(bitmap565);
I also compress it in an output stream:
try {
FileOutputStream fos = new FileOutputStream(filepath);
bitmap565.compress(CompressFormat.JPEG, 90, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Thanks all!
<ImageButton android:id="#+id/ImageButton01" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#drawable/results" android:layout_gravity="top|center"></ImageButton><ImageView
android:screenOrientation="portrait"
android:layout_width="fill_parent"
android:id="#+id/image_view"
android:layout_gravity="center" android:layout_weight="1.0" android:layout_height="wrap_content" android:scaleType="centerInside"/>
<Button
android:screenOrientation="portrait"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal" android:layout_width="fill_parent" android:textStyle="bold" android:id="#+id/detect_face" android:text="Detect"/>
you can solve your problem just using FrameLayout.
Your ImageView's layout_width is set to fill_parent, so layout_gravity won't affect its horizontal position within its parent. Try using gravity instead of layout_gravity, or wrap_content instead of fill_parent.