android实现手机截屏并保存截图功能
程序员文章站
2023-09-04 14:11:45
本文实例为大家分享了android实现手机截屏并保存截图功能的具体代码,供大家参考,具体内容如下
一、准备一张图片
拷贝screenshot_panel.9.p...
本文实例为大家分享了android实现手机截屏并保存截图功能的具体代码,供大家参考,具体内容如下
一、准备一张图片
拷贝screenshot_panel.9.png放在目录drawable-xhdpi下
二、activity_main.xml
代码如下:
<relativelayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:paddingbottom="@dimen/activity_vertical_margin" android:paddingleft="@dimen/activity_horizontal_margin" android:paddingright="@dimen/activity_horizontal_margin" android:paddingtop="@dimen/activity_vertical_margin" tools:context=".mainactivity" > <textview android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/hello_world" /> <button android:id="@+id/main_btn" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="shot" android:layout_alignparentbottom="true"/> </relativelayout>
三、新建xml文件
<?xml version="1.0" encoding="utf-8"?> <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:layout_width="match_parent" android:layout_height="match_parent" android:src="@android:color/black" android:visibility="gone" /> <imageview android:id="@+id/global_screenshot" android:layout_width="wrap_content" 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>
四、在dimens.xml添加一项
<dimen name="global_screenshot_bg_padding">20dp</dimen>
五、后台代码
1)surfacecontrol.java
import android.graphics.bitmap; import android.view.view; public class surfacecontrol { public static bitmap screenshot(view view) { view.setdrawingcacheenabled(true); view.builddrawingcache(); bitmap bmp = view.getdrawingcache(); return bmp; } }
2)globalscreenshot.java代码如下,其中savepicture方法有保存截图的路径
import java.io.file; import java.io.filenotfoundexception; import java.io.fileoutputstream; import java.text.simpledateformat; import java.util.date; import java.util.locale; import android.animation.animator; import android.animation.animatorlisteneradapter; import android.animation.animatorset; import android.animation.valueanimator; import android.animation.valueanimator.animatorupdatelistener; import android.content.context; import android.content.res.resources; import android.graphics.bitmap; import android.graphics.matrix; import android.graphics.pixelformat; import android.graphics.pointf; import android.media.mediaactionsound; import android.net.uri; import android.os.environment; import android.util.displaymetrics; import android.util.log; import android.view.display; import android.view.layoutinflater; import android.view.motionevent; import android.view.view; import android.view.viewgroup; import android.view.windowmanager; import android.view.animation.interpolator; import android.widget.imageview; import android.widget.toast; /** * pod used in the asynctask which saves an image in the background. */ class saveimageinbackgrounddata { context context; bitmap image; uri imageuri; runnable finisher; int iconsize; int result; void clearimage() { image = null; imageuri = null; iconsize = 0; } void clearcontext() { context = null; } } /** * todo: * - performance when over gl surfaces? ie. gallery * - what do we say in the toast? which icon do we get if the user uses another * type of gallery? */ 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) { resources 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, null); 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(view v, motionevent event) { // intercept and ignore all touch events return true; } }); // setup the window that we are going to use mwindowlayoutparams = new windowmanager.layoutparams( viewgroup.layoutparams.match_parent, viewgroup.layoutparams.match_parent, 0, 0, windowmanager.layoutparams.type_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 has to account for both sides of the bg mbgpadding = (float) r.getdimensionpixelsize(r.dimen.global_screenshot_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 log.d("debug","takescreenshot start"); mscreenbitmap = surfacecontrol.screenshot(view); log.d("debug","takescreenshot 1"); if (mscreenbitmap == null) { notifyscreenshoterror(mcontext); finisher.run(); return; } // optimizations mscreenbitmap.sethasalpha(false); mscreenbitmap.preparetodraw(); log.d("debug","takescreenshot 2"); log.d("debug","takescreenshot 3"); // start the post-screenshot animation startanimation(finisher, mdisplaymetrics.widthpixels, mdisplaymetrics.heightpixels, statusbarvisible, navbarvisible); log.d("debug","takescreenshot end"); } private void savepicture(){ log.d("debug","savepicture 1"); mscreenshotview.setdrawingcacheenabled(true); log.d("debug","savepicture 2"); bitmap obmp = bitmap.createbitmap(mscreenshotview.getdrawingcache()); log.d("debug","savepicture 3"); if (obmp != null) { // 图片存储路径 string savepath = getsdcardpath() + "/test/screenimages"; // 保存bitmap log.d("debug","savepath = "+savepath); try { file path = new file(savepath); // 文件 string filepath = savepath + "/screen_1.png"; log.d("debug","filepath = "+filepath); file file = new file(filepath); if (!path.exists()) { log.d("debug","path is not exists"); path.mkdirs(); } if (!file.exists()) { log.d("debug","file create new "); file.createnewfile(); } fileoutputstream fos = null; fos = new fileoutputstream(file); if (null != fos) { obmp.compress(bitmap.compressformat.png, 90, fos); fos.flush(); fos.close(); log.d("debug","save ok"); } } catch (exception e) { e.printstacktrace(); } } } /** * 获取sdcard的目录路径功能 * * @return */ private string getsdcardpath() { file sdcarddir = null; // 判断sdcard是否存在 boolean sdcardexist = environment.getexternalstoragestate().equals( android.os.environment.media_mounted); if (sdcardexist) { sdcarddir = environment.getexternalstoragedirectory(); } return sdcarddir.tostring(); } /** * starts the animation after taking the screenshot */ private void startanimation(final runnable finisher, int w, int h, boolean statusbarvisible, boolean navbarvisible) { // add the view for the animation mscreenshotview.setimagebitmap(mscreenbitmap); mscreenshotlayout.requestfocus(); // setup the animation with the screenshot just taken if (mscreenshotanimation != null) { mscreenshotanimation.end(); mscreenshotanimation.removealllisteners(); } mwindowmanager.addview(mscreenshotlayout, mwindowlayoutparams); valueanimator screenshotdropinanim = createscreenshotdropinanimation(); valueanimator screenshotfadeoutanim = createscreenshotdropoutanimation(w, h, statusbarvisible, navbarvisible); mscreenshotanimation = new animatorset(); mscreenshotanimation.playsequentially(screenshotdropinanim, screenshotfadeoutanim); mscreenshotanimation.addlistener(new animatorlisteneradapter() { @override public void onanimationend(animator animation) { // save the screenshot once we have a bit of time now savescreenshotinworkerthread(finisher); mwindowmanager.removeview(mscreenshotlayout); savepicture(); // clear any references to the bitmap mscreenbitmap = null; mscreenshotview.setimagebitmap(null); } }); mscreenshotlayout.post(new runnable() { @override public void run() { // play the shutter sound to 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) (screenshot_flash_to_peak_duration) / screenshot_drop_in_duration); final float flashdurationpct = 2f * flashpeakdurationpct; final interpolator flashalphainterpolator = new interpolator() { @override public float getinterpolation(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 is at it's peak if (x < flashpeakdurationpct) { 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 animation) { 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) { mscreenshotflash.setvisibility(view.gone); } }); anim.addupdatelistener(new animatorupdatelistener() { @override public void onanimationupdate(valueanimator 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 animation) { 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 onanimationupdate(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 is a status bar, animate to the origin of the bar (top-left) final float scaledurationpct = (float) screenshot_drop_out_scale_duration / screenshot_drop_out_duration; final interpolator scaleinterpolator = new interpolator() { @override public float getinterpolation(float x) { if (x < scaledurationpct) { // decelerate, and scale the input 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) * halfscreenwidth, -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 onanimationupdate(valueanimator animation) { float t = (float) animation.getanimatedvalue(); float scalet = (screenshot_drop_in_min_scale + mbgpaddingscale) - scaleinterpolator.getinterpolation(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 runnable) { } }
3)在mainactivity.java调用
import android.os.bundle; import android.app.activity; import android.view.menu; import android.view.menuitem; import android.view.view; public class mainactivity extends activity { @override 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); } }); } @override public boolean oncreateoptionsmenu(menu menu) { // inflate the menu; this adds items to the action bar if it is present. getmenuinflater().inflate(r.menu.main, menu); return true; } @override public boolean onoptionsitemselected(menuitem item) { // handle action bar item clicks here. the action bar will // automatically handle clicks on the home/up button, so long // as you specify a parent activity in androidmanifest.xml. int id = item.getitemid(); if (id == r.id.action_settings) { return true; } return super.onoptionsitemselected(item); } }
六、androidmanifest.xml设置权限
<uses-permission android:name="android.permission.system_alert_window"></uses-permission> <uses-permission android:name="android.permission.write_external_storage"/>
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。