android - Black edges around the taken screenshot -


i'm following example :

package com.mtsahakis.mediaprojectiondemo;  import android.app.activity; import android.content.context; import android.content.intent; import android.graphics.bitmap; import android.graphics.bitmap.compressformat; import android.graphics.pixelformat; import android.graphics.point; import android.hardware.display.displaymanager; import android.hardware.display.virtualdisplay; import android.media.image; import android.media.imagereader; import android.media.projection.mediaprojection; import android.media.projection.mediaprojectionmanager; import android.os.bundle; import android.os.handler; import android.os.looper; import android.util.displaymetrics; import android.util.log; import android.view.display; import android.view.orientationeventlistener; import android.view.view; import android.view.view.onclicklistener; import android.widget.button;  import java.io.file; import java.io.fileoutputstream; import java.io.ioexception; import java.nio.bytebuffer;   public class screencaptureimageactivity extends activity {      private static final string tag = screencaptureimageactivity.class.getname();     private static final int request_code = 100;     private static string store_directory;     private static int images_produced;     private static final string screencap_name = "screencap";     private static final int virtual_display_flags = displaymanager.virtual_display_flag_own_content_only | displaymanager.virtual_display_flag_public;     private static mediaprojection smediaprojection;      private mediaprojectionmanager mprojectionmanager;     private imagereader mimagereader;     private handler mhandler;     private display mdisplay;     private virtualdisplay mvirtualdisplay;     private int mdensity;     private int mwidth;     private int mheight;     private int mrotation;     private orientationchangecallback morientationchangecallback;      private class imageavailablelistener implements imagereader.onimageavailablelistener {         @override         public void onimageavailable(imagereader reader) {             image image = null;             fileoutputstream fos = null;             bitmap bitmap = null;              try {                 image = mimagereader.acquirelatestimage();                 if (image != null) {                     image.plane[] planes = image.getplanes();                     bytebuffer buffer = planes[0].getbuffer();                     int pixelstride = planes[0].getpixelstride();                     int rowstride = planes[0].getrowstride();                     int rowpadding = rowstride - pixelstride * mwidth;                      // create bitmap                     bitmap = bitmap.createbitmap(mwidth + rowpadding / pixelstride, mheight, bitmap.config.argb_8888);                     bitmap.copypixelsfrombuffer(buffer);                      // write bitmap file                     fos = new fileoutputstream(store_directory + "/myscreen_" + images_produced + ".png");                     bitmap.compress(compressformat.jpeg, 100, fos);                      images_produced++;                     log.e(tag, "captured image: " + images_produced);                 }              } catch (exception e) {                 e.printstacktrace();             } {                 if (fos!=null) {                     try {                         fos.close();                     } catch (ioexception ioe) {                         ioe.printstacktrace();                     }                 }                  if (bitmap!=null) {                     bitmap.recycle();                 }                  if (image!=null) {                     image.close();                 }             }         }     }      private class orientationchangecallback extends orientationeventlistener {         public orientationchangecallback(context context) {             super(context);         }          @override         public void onorientationchanged(int orientation) {             synchronized (this) {                 final int rotation = mdisplay.getrotation();                 if (rotation != mrotation) {                     mrotation = rotation;                     try {                         // clean                         if(mvirtualdisplay != null) mvirtualdisplay.release();                         if(mimagereader != null) mimagereader.setonimageavailablelistener(null, null);                          // re-create virtual display depending on device width / height                         createvirtualdisplay();                     } catch (exception e) {                         e.printstacktrace();                     }                 }             }         }     }      private class mediaprojectionstopcallback extends mediaprojection.callback {         @override         public void onstop() {             log.e("screencapture", "stopping projection.");             mhandler.post(new runnable() {                 @override                 public void run() {                     if(mvirtualdisplay != null) mvirtualdisplay.release();                     if(mimagereader != null) mimagereader.setonimageavailablelistener(null, null);                     if(morientationchangecallback != null) morientationchangecallback.disable();                     smediaprojection.unregistercallback(mediaprojectionstopcallback.this);                 }             });         }     }      /****************************************** activity lifecycle methods ************************/     @override     protected void oncreate(bundle savedinstancestate) {         super.oncreate(savedinstancestate);         setcontentview(r.layout.activity_main);          // call projection manager         mprojectionmanager = (mediaprojectionmanager) getsystemservice(context.media_projection_service);          // start projection         button startbutton = (button)findviewbyid(r.id.startbutton);         startbutton.setonclicklistener(new onclicklistener() {              @override             public void onclick(view v) {                 startprojection();             }         });          // stop projection         button stopbutton = (button)findviewbyid(r.id.stopbutton);         stopbutton.setonclicklistener(new onclicklistener() {              @override             public void onclick(view v) {                 stopprojection();             }         });          // start capture handling thread         new thread() {             @override             public void run() {                 looper.prepare();                 mhandler = new handler();                 looper.loop();             }         }.start();     }      @override     protected void onactivityresult(int requestcode, int resultcode, intent data) {         if (requestcode == request_code) {             smediaprojection = mprojectionmanager.getmediaprojection(resultcode, data);              if (smediaprojection != null) {                 file externalfilesdir = getexternalfilesdir(null);                 if (externalfilesdir != null) {                     store_directory = externalfilesdir.getabsolutepath() + "/screenshots/";                     file storedirectory = new file(store_directory);                     if (!storedirectory.exists()) {                         boolean success = storedirectory.mkdirs();                         if (!success) {                             log.e(tag, "failed create file storage directory.");                             return;                         }                     }                 } else {                     log.e(tag, "failed create file storage directory, getexternalfilesdir null.");                     return;                 }                  // display metrics                 displaymetrics metrics = getresources().getdisplaymetrics();                 mdensity = metrics.densitydpi;                 mdisplay = getwindowmanager().getdefaultdisplay();                  // create virtual display depending on device width / height                 createvirtualdisplay();                  // register orientation change callback                 morientationchangecallback = new orientationchangecallback(this);                 if (morientationchangecallback.candetectorientation()) {                     morientationchangecallback.enable();                 }                  // register media projection stop callback                 smediaprojection.registercallback(new mediaprojectionstopcallback(), mhandler);             }         }     }      /****************************************** ui widget callbacks *******************************/     private void startprojection() {         startactivityforresult(mprojectionmanager.createscreencaptureintent(), request_code);     }      private void stopprojection() {         mhandler.post(new runnable() {             @override             public void run() {                 if (smediaprojection != null) {                     smediaprojection.stop();                 }             }         });     }      /****************************************** factoring virtual display creation ****************/     private void createvirtualdisplay() {         // width , height         point size = new point();         mdisplay.getsize(size);         mwidth = size.x;         mheight = size.y;          // start capture reader         mimagereader = imagereader.newinstance(mwidth, mheight, pixelformat.rgba_8888, 2);         mvirtualdisplay = smediaprojection.createvirtualdisplay(screencap_name, mwidth, mheight, mdensity, virtual_display_flags, mimagereader.getsurface(), null, mhandler);         mimagereader.setonimageavailablelistener(new imageavailablelistener(), mhandler);     } } 

to take screenshot on android ver >=21.

the problem example once take screenshot , there black edges on top , right & bottom of image.

i can't see problem since given width , height both virtualdisplay , bitmap correct, i'm missing here?

problem size of virtual display.

mdisplay.getsize(size); 

may return different real size of device if device have virtual navigation bar (usually swipe bottom of screen display it).

mdisplay.getrealsize(size); 

will fix problem black edges.


Comments

Popular posts from this blog

sequelize.js - Sequelize group by with association includes id -

android - Robolectric "INTERNET permission is required" -

java - Android raising EPERM (Operation not permitted) when attempting to send UDP packet after network connection -