Screenshot feature extraction for Android system

Source: Internet
Author: User

After the 4.0 version of Android Press the Power key and volume key can intercept the current screen, there will be a transition animation effect, here extract the effect of this section extracted, can be used for the application sharing function.

The location of the function in the source code is com.android.systemui.screenshot, there are four classes below


The main work is in Globalscreenshot, including the post-animation effect, save to local and display to the notification bar. For simplicity, the following code retains only the transition animation part

Class Globalscreenshot {private static final String TAG = "Globalscreenshot";    private static final int screenshot_flash_to_peak_duration = 130;    private static final int screenshot_drop_in_duration = 430;    private static final int screenshot_drop_out_delay = 500;    private static final int screenshot_drop_out_duration = 430;    private static final int screenshot_drop_out_scale_duration = 370;    private static final int screenshot_fast_drop_out_duration = 320;    Private static final float Background_alpha = 0.5f;    Private static final float Screenshot_scale = 1f;    Private static final Float Screenshot_drop_in_min_scale = Screenshot_scale * 0.725f;    Private static final Float Screenshot_drop_out_min_scale = Screenshot_scale * 0.45f;    Private static final Float Screenshot_fast_drop_out_min_scale = Screenshot_scale * 0.6f;    Private static final float screenshot_drop_out_min_scale_offset = 0f;    Private Context Mcontext;    Private WindowManager Mwindowmanager;Private Windowmanager.layoutparams Mwindowlayoutparams;    Private Display Mdisplay;    Private Displaymetrics mdisplaymetrics;    Private Bitmap Mscreenbitmap;    Private View mscreenshotlayout;    Private ImageView Mbackgroundview;    Private ImageView Mscreenshotview;    Private ImageView Mscreenshotflash;    Private Animatorset mscreenshotanimation;    private float mbgpadding;    private float Mbgpaddingscale;    Private Mediaactionsound Mcamerasound; /** * @param context everything needs a context:(*/public globalscreenshot (context context) {RESOURC        Es r = context.getresources ();        Mcontext = context;         Layoutinflater Layoutinflater = (layoutinflater) context.getsystemservice (Context.layout_inflater_service); Inflate the screenshot layout mscreenshotlayout = Layoutinflater.inflate (R.layout.global_screenshot, nul        L); Mbackgroundview = (ImageView) Mscreenshotlayout.findviewbyid (r.id.global_screenshot_background);        Mscreenshotview = (ImageView) Mscreenshotlayout.findviewbyid (r.id.global_screenshot);        Mscreenshotflash = (ImageView) Mscreenshotlayout.findviewbyid (R.id.global_screenshot_flash);        Mscreenshotlayout.setfocusable (TRUE); Mscreenshotlayout.setontouchlistener (New View.ontouchlistener () {@Override public boolean OnTouch (V            Iew V, motionevent event) {//Intercept and Ignore All touch events return true;        }        }); Setup The window that we is going to use Mwindowlayoutparams = new Windowmanager.layoutparams (V IewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, 0, 0, WINDOWMANAGER.LAYOUTPARAMS.T Ype_system_alert, WindowManager.LayoutParams.FLAG_FULLSCREEN | WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED |                WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN        |        WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED, pixelformat.translucent);        Mwindowlayoutparams.settitle ("Screenshotanimation");        Mwindowmanager = (WindowManager) context.getsystemservice (Context.window_service);        Mdisplay = Mwindowmanager.getdefaultdisplay ();        Mdisplaymetrics = new Displaymetrics ();        Mdisplay.getrealmetrics (Mdisplaymetrics); Scale have to account for both sides of the BG mbgpadding = (float) r.getdimensionpixelsize (r.dimen.global_screen        shot_bg_padding);        Mbgpaddingscale = Mbgpadding/mdisplaymetrics.widthpixels;        Setup the Camera shutter sound mcamerasound = new Mediaactionsound ();    Mcamerasound.load (Mediaactionsound.shutter_click);     }/** * Takes A screenshot of the current display and shows an animation. */void Takescreenshot (View view, Runnable Finisher, Boolean statusbarvisible, Boolean navbarvisible) {//Take The screenshot MscreenbItmap = Surfacecontrol.screenshot (view);            if (Mscreenbitmap = = null) {notifyscreenshoterror (mcontext);            Finisher.run ();        Return        }//Optimizations Mscreenbitmap.sethasalpha (FALSE);        Mscreenbitmap.preparetodraw (); Start the Post-screenshot animation startanimation (finisher, Mdisplaymetrics.widthpixels, Mdisplaymetrics.height    Pixels, statusbarvisible, navbarvisible); }/** * Starts the animation after taking the screenshot * * private void Startanimation (final Runnable Finis Her, int w, int h, Boolean statusbarvisible, Boolean navbarvisible) {//ADD the Vie        W for the animation Mscreenshotview.setimagebitmap (MSCREENBITMAP);        Mscreenshotlayout.requestfocus (); Setup the animation with the screenshot just taken if (mscreenshotanimation! = null) {Mscreenshotani            Mation.end (); MscreenshotanimatioN.removealllisteners ();        } mwindowmanager.addview (Mscreenshotlayout, mwindowlayoutparams);        Valueanimator Screenshotdropinanim = Createscreenshotdropinanimation (); Valueanimator Screenshotfadeoutanim = createscreenshotdropoutanimation (W, H, statusbarvisible, NavBarVisibl        e);        Mscreenshotanimation = new Animatorset ();        Mscreenshotanimation.playsequentially (Screenshotdropinanim, Screenshotfadeoutanim); Mscreenshotanimation.addlistener (New Animatorlisteneradapter () {@Override public void Onanimationen D (Animator animation) {//Save The screenshot Once we have a bit of time now Savescreenshot                Inworkerthread (finisher);                Mwindowmanager.removeview (mscreenshotlayout);                Clear any references to the bitmap mscreenbitmap = null;            Mscreenshotview.setimagebitmap (NULL);        }        }); Mscreenshotlayout.post (New Runnable () {@Override public void run () {//Play the shutter-notify that we ve                Taken a screenshot mcamerasound.play (Mediaactionsound.shutter_click);                Mscreenshotview.setlayertype (view.layer_type_hardware, NULL);                Mscreenshotview.buildlayer ();            Mscreenshotanimation.start ();    }        }); } private Valueanimator Createscreenshotdropinanimation () {final float flashpeakdurationpct = ((float) (SCREENS        hot_flash_to_peak_duration)/screenshot_drop_in_duration);        Final float flashdurationpct = 2f * FLASHPEAKDURATIONPCT; Final Interpolator flashalphainterpolator = new Interpolator () {@Override public float Getinterpola                    tion (float x) {//flash the Flash view in and out quickly if (x <= flashdurationpct) {          return (float) Math.sin (Math.PI * (x/flashdurationpct));      } return 0;        }        }; Final Interpolator scaleinterpolator = new Interpolator () {@Override public float getinterpolation ( float x) {//We start scaling when the flash was at it ' s peak if (x < FLASHPEAKDURATIONPC                T) {return 0;            } return (x-flashdurationpct)/(1f-flashdurationpct);        }        };        Valueanimator anim = Valueanimator.offloat (0f, 1f);        Anim.setduration (screenshot_drop_in_duration); Anim.addlistener (New Animatorlisteneradapter () {@Override public void Onanimationstart (Animator ani                mation) {Mbackgroundview.setalpha (0f);                Mbackgroundview.setvisibility (view.visible);                Mscreenshotview.setalpha (0f);                Mscreenshotview.settranslationx (0f);                Mscreenshotview.settranslationy (0f); Mscreenshotview.setscalex (Screenshot_scale + Mbgpaddingscale);                Mscreenshotview.setscaley (Screenshot_scale + mbgpaddingscale);                Mscreenshotview.setvisibility (view.visible);                Mscreenshotflash.setalpha (0f);            Mscreenshotflash.setvisibility (view.visible); } @Override public void Onanimationend (Android.animation.Animator animation) {Mscree            Nshotflash.setvisibility (View.gone);        }        }); Anim.addupdatelistener (New Animatorupdatelistener () {@Override public void onanimationupdate (Valuea                Nimator animation) {Float t = (float) animation.getanimatedvalue ();                        float Scalet = (Screenshot_scale + mbgpaddingscale)-scaleinterpolator.getinterpolation (t)                * (Screenshot_scale-screenshot_drop_in_min_scale);       Mbackgroundview.setalpha (scaleinterpolator.getinterpolation (t) * background_alpha);         Mscreenshotview.setalpha (t);                Mscreenshotview.setscalex (Scalet);                Mscreenshotview.setscaley (Scalet);            Mscreenshotflash.setalpha (Flashalphainterpolator.getinterpolation (t));        }        });    return anim;                                                           } private Valueanimator createscreenshotdropoutanimation (int w, int h, Boolean statusbarvisible,        Boolean navbarvisible) {valueanimator anim = valueanimator.offloat (0f, 1f);        Anim.setstartdelay (Screenshot_drop_out_delay); Anim.addlistener (New Animatorlisteneradapter () {@Override public void Onanimationend (Animator anima                tion) {mbackgroundview.setvisibility (view.gone);                Mscreenshotview.setvisibility (View.gone);            Mscreenshotview.setlayertype (View.layer_type_none, NULL);        }        }); if (!statusbarvisible | |!navbarvisible) {//There is no status BAR/nav bar, so just fade the screenshot away in place Anim.setduration (screenshot_fast_drop_out_duration); Anim.addupdatelistener (New Animatorupdatelistener () {@Override public void Onanimati                    OnUpdate (Valueanimator animation) {Float t = (float) animation.getanimatedvalue (); float Scalet = (Screenshot_drop_in_min_scale + mbgpaddingscale)-T * (screenshot_drop_in_min_                    Scale-screenshot_fast_drop_out_min_scale);                    Mbackgroundview.setalpha ((1f-t) * background_alpha);                    Mscreenshotview.setalpha (1F-T);                    Mscreenshotview.setscalex (Scalet);                Mscreenshotview.setscaley (Scalet);        }            }); } else {//In the case where there are a status bar, animate to the origin of the bar (Top-left) fin   Al float scaledurationpct = (float) screenshot_drop_out_scale_duration                 /screenshot_drop_out_duration; Final Interpolator scaleinterpolator = new Interpolator () {@Override public float GETINTERP Olation (float x) {if (x < scaledurationpct) {//decelerate, and scale the I                    Nput accordingly return (float) (1f-math.pow (1f-(x/scaledurationpct), 2f));                } return 1f;            }            };            Determine the bounds of how to scale float Halfscreenwidth = (w-2f * mbgpadding)/2f;            float Halfscreenheight = (h-2f * mbgpadding)/2f;            Final float offsetpct = Screenshot_drop_out_min_scale_offset; Final PointF Finalpos = new PointF (-halfscreenwidth + (Screenshot_drop_out_min_scale + offsetpct) * ha       Lfscreenwidth,-halfscreenheight + (Screenshot_drop_out_min_scale + offsetpct) * halfscreenheight);     Animate the screenshot to the status bar Anim.setduration (screenshot_drop_out_duration); Anim.addupdatelistener (New Animatorupdatelistener () {@Override public void Onanimationupdat                    E (valueanimator animation) {Float t = (float) animation.getanimatedvalue (); float Scalet = (Screenshot_drop_in_min_scale + mbgpaddingscale)-Scaleinterpolator.getinterpol                    ation (t) * (Screenshot_drop_in_min_scale-screenshot_drop_out_min_scale);                    Mbackgroundview.setalpha ((1f-t) * background_alpha);                    Mscreenshotview.setalpha (1f-scaleinterpolator.getinterpolation (t));                    Mscreenshotview.setscalex (Scalet);                    Mscreenshotview.setscaley (Scalet);                    Mscreenshotview.settranslationx (T * finalpos.x);              Mscreenshotview.settranslationy (T * finalpos.y);  }            });    } return anim; private void Notifyscreenshoterror (context context) {} private void Savescreenshotinworkerthread (Runnable Runn able) {}}

Take a look at the effect


Here is the following analysis of the relevant principles:

1. How to display

Back to the corresponding bitmap, with WindowManager directly on the screen to display the bitmap, that is, bitmap put into a imageview, WindowManager AddView can be displayed.

To have a shadow effect, an additional layout:global_screenshot.xml is defined here, as follows

<framelayout xmlns:android= "http://schemas.android.com/apk/res/android" android:layout_width= "Match_parent" android:layout_height= "Match_parent" > <imageview android:id= "@+id/global_screenshot_background" Android:la Yout_width= "Match_parent" android:layout_height= "match_parent" android:src= "@android: Color/black" and roid:visibility= "Gone"/> <imageview android:id= "@+id/global_screenshot" android:layout_width= "Wrap_conten T "android:layout_height=" wrap_content "android:layout_gravity=" center "android:background=" @drawable /screenshot_panel "android:visibility=" Gone "android:adjustviewbounds=" true "/> <imageview android:        Id= "@+id/global_screenshot_flash" android:layout_width= "match_parent" android:layout_height= "Match_parent" Android:src= "@android: Color/white" android:visibility= "Gone"/></framelayout>

Above the layout of a total of three layers, the bottom of the background for the cover, the middle of the screenshot used to put, the top also has a layer of flash, mainly used to make a reflective effect.

Bitmap is placed in the ImageView of Global_screenshot. The corresponding code

Mscreenshotview.setimagebitmap (MSCREENBITMAP);        Mscreenshotlayout.requestfocus ();        Setup the animation with the screenshot just taken        if (mscreenshotanimation! = null) {            mscreenshotanimation.end ();            Mscreenshotanimation.removealllisteners ();        }        Mwindowmanager.addview (Mscreenshotlayout, mwindowlayoutparams);

So you can see it on the screen, and then there's a transition animation effect, respectively

        Valueanimator Screenshotdropinanim = Createscreenshotdropinanimation ();        Valueanimator Screenshotfadeoutanim = createscreenshotdropoutanimation (W, H,                statusbarvisible, navBarVisible);

These two properties animate the display-zoom-disappear process, specifically to transform the above three-layer view.

Called in activity

protected void OnCreate (Bundle savedinstancestate) {        super.oncreate (savedinstancestate);        Setcontentview (r.layout.activity_main);        Final Globalscreenshot screenshot = new Globalscreenshot (this);        Findviewbyid (R.ID.MAIN_BTN). Setonclicklistener (New View.onclicklistener () {            @Override public            void OnClick ( View v) {                screenshot.takescreenshot (GetWindow (). Getdecorview (), new Runnable () {                    @Override public                    Void Run () {                    }                }, True, true);}}        );    

The two Boolean arguments that follow indicate whether there is a status bar for displaying different fade animations, and if one is false, it will fade out without being offset upward to the status bar.

Screenshot feature extraction for Android system

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.