首页 > 系统 > Android > 正文

android实现手机截屏并保存截图功能

2019-10-21 21:37:06
字体:
来源:转载
供稿:网友

本文实例为大家分享了android实现手机截屏并保存截图功能的具体代码,供大家参考,具体内容如下

一、准备一张图片

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"/>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。


注:相关教程知识阅读请移步到Android开发频道。
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表