Android屏幕截屏的方法

来源:爱站网时间:2020-12-31编辑:网友分享
在使用Android系统的时候很多用户们都会截屏,但是在Android系统中截屏的方法有很多,下面我们就和爱站小编一起去看看Android屏幕截屏的方法吧。

在使用Android系统的时候很多用户们都会截屏,但是在Android系统中截屏的方法有很多,下面我们就和爱站小编一起去看看Android屏幕截屏的方法吧。

1、直接使用getWindow().getDecorView().getRootView()

直接使用getWindow().getDecorView().getRootView()是获取当前屏幕的activity。然而对于系统状态栏的信息是截不了,出现一条空白的。如下图:

 

主要到没,有一条白色边就是系统状态栏。看一下代码,很简单都加了注释了。

//这种方法状态栏是空白,显示不了状态栏的信息 
private void saveCurrentImage() 
{ 
//获取当前屏幕的大小 
int width = getWindow().getDecorView().getRootView().getWidth(); 
int height = getWindow().getDecorView().getRootView().getHeight(); 
//生成相同大小的图片 
Bitmap temBitmap = Bitmap.createBitmap( width, height, Config.ARGB_8888 ); 
//找到当前页面的跟布局 
View view = getWindow().getDecorView().getRootView(); 
//设置缓存 
view.setDrawingCacheEnabled(true); 
view.buildDrawingCache(); 
//从缓存中获取当前屏幕的图片 
temBitmap = view.getDrawingCache(); 
//输出到sd卡 
if (FileIOUtil.getExistStorage()) { 
FileIOUtil.GetInstance().onFolderAnalysis(FileIOUtil.GetInstance().getFilePathAndName()); 
File file = new File(FileIOUtil.GetInstance().getFilePathAndName()); 
try { 
if (!file.exists()) { 
file.createNewFile(); 
} 
FileOutputStream foStream = new FileOutputStream(file); 
temBitmap.compress(Bitmap.CompressFormat.PNG, 100, foStream); 
foStream.flush(); 
foStream.close(); 
} catch (Exception e) { 
Log.i("Show", e.toString()); 
} 
} 
}

2、自定义view控件的截图

自定义view控件都是继承view的吗,那么就有可以获取宽度,高度。生成图片,把它绘制出来的。我拿了直接写的自定义随机验证码的例子来截图。

//保存自定义view的截图 
private void saveCustomViewBitmap() { 
//获取自定义view图片的大小 
Bitmap temBitmap = Bitmap.createBitmap(mCodeView.getWidth(), mCodeView.getHeight(), Config.ARGB_8888); 
//使用Canvas,调用自定义view控件的onDraw方法,绘制图片 
Canvas canvas = new Canvas(temBitmap); 
mCodeView.onDraw(canvas); 
//输出到sd卡 
if (FileIOUtil.getExistStorage()) { 
FileIOUtil.GetInstance().onFolderAnalysis(FileIOUtil.GetInstance().getFilePathAndName()); 
File file = new File(FileIOUtil.GetInstance().getFilePathAndName()); 
try { 
if (!file.exists()) { 
file.createNewFile(); 
} 
FileOutputStream foStream = new FileOutputStream(file); 
temBitmap.compress(Bitmap.CompressFormat.PNG, 100, foStream); 
foStream.flush(); 
foStream.close(); 
Toast.makeText(MainActivity.this, "截屏文件已保存至" + FileIOUtil.GetInstance().getFilePathAndName(), Toast.LENGTH_LONG).show(); 
} catch (Exception e) { 
Log.i("Show", e.toString()); 
} 
} 
}

有人根据这种思路,自定义整个布局的view,然后来截图。也是够拼的,我有点不赞成这样使用。

3、基于android ddmlib截屏

这个是java写的一个类,入口是mian函数。那么这种实现方式是要android连接着电脑,还需要android设备调试。这种不多说,搞android开发都懂。太麻烦了,我们也不使用。

package com.example.screenshot; 
import java.io.IOException; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
import com.android.ddmlib.AdbCommandRejectedException; 
import com.android.ddmlib.AndroidDebugBridge; 
import com.android.ddmlib.IDevice; 
import com.android.ddmlib.RawImage; 
import com.android.ddmlib.TimeoutException; 
public class ScreenShoddmlib { 
private BufferedImage image = null; 
/** 
* @param args 
*/ 
public static void main(String[] args) { 
// TODO Auto-generated method stub 
AndroidDebugBridge.init(false); // 
ScreenShoddmlib screenshot = new ScreenShoddmlib(); 
IDevice device = screenshot.getDevice(); 
for (int i = 0; i > 3; 
for (int y = 0; y  240) { 
System.err.print("等待获取设备超时"); 
break; 
} 
} 
}

4、使用adb命令

需要系统权限,在APK中调用“adb shell screencap -pfilepath” 命令

需要获得系统权限:

1、 在AndroidManifest.xml文件中添加

2、修改APK为系统权限,将APK放到源码中编译, 修改Android.mk LOCAL_CERTIFICATE := platform
在这里我要说一下,搞过jni调用就知道Android.mk的作用。此举也是麻烦,效果也不是很好。

public void takeScreenShot(){ 
String mSavedPath = Environment.getExternalStorageDirectory()+File. separator + "screenshot.png" ; 
try { 
Runtime. getRuntime().exec("screencap -p " + mSavedPath); 
} catch (Exception e) { 
e.printStackTrace(); 
}

5、看一下系统截屏是怎样的

相信大家都知道,三星的机子是同时按下 home键 + 电源键 3秒截图。
如果没有home键的机子是按下 音量键向下那个 + 电源键 3秒截图的。
获取物理键盘按下的源码:PhoneWindowManager.java

// Handle special keys. 
switch (keyCode) { 
case KeyEvent.KEYCODE_VOLUME_DOWN: 
case KeyEvent.KEYCODE_VOLUME_UP: 
case KeyEvent.KEYCODE_VOLUME_MUTE: { 
if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { 
if (down) { 
if (isScreenOn && !mVolumeDownKeyTriggered 
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 
mVolumeDownKeyTriggered = true; 
mVolumeDownKeyTime = event.getDownTime(); 
mVolumeDownKeyConsumedByScreenshotChord = false; 
cancelPendingPowerKeyAction(); 
interceptScreenshotChord(); 
} 
} else { 
mVolumeDownKeyTriggered = false; 
cancelPendingScreenshotChordAction(); 
} 
} else if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { 
if (down) { 
if (isScreenOn && !mVolumeUpKeyTriggered 
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 
mVolumeUpKeyTriggered = true; 
cancelPendingPowerKeyAction(); 
cancelPendingScreenshotChordAction(); 
} 
} else { 
mVolumeUpKeyTriggered = false; 
cancelPendingScreenshotChordAction(); 
} 
} 
if (down) { 
ITelephony telephonyService = getTelephonyService(); 
if (telephonyService != null) { 
try { 
if (telephonyService.isRinging()) { 
// If an incoming call is ringing, either VOLUME key means 
// "silence ringer". We handle these keys here, rather than 
// in the InCallScreen, to make sure we'll respond to them 
// even if the InCallScreen hasn't come to the foreground yet. 
// Look for the DOWN event here, to agree with the "fallback" 
// behavior in the InCallScreen. 
Log.i(TAG, "interceptKeyBeforeQueueing:" 
+ " VOLUME key-down while ringing: Silence ringer!"); 
// Silence the ringer. (It's safe to call this 
// even if the ringer has already been silenced.) 
telephonyService.silenceRinger(); 
// And *don't* pass this key thru to the current activity 
// (which is probably the InCallScreen.) 
result &= ~ACTION_PASS_TO_USER; 
break; 
} 
if (telephonyService.isOffhook() 
&& (result & ACTION_PASS_TO_USER) == 0) { 
// If we are in call but we decided not to pass the key to 
// the application, handle the volume change here. 
handleVolumeKey(AudioManager.STREAM_VOICE_CALL, keyCode); 
break; 
} 
} catch (RemoteException ex) { 
Log.w(TAG, "ITelephony threw RemoteException", ex); 
} 
} 
if (isMusicActive() && (result & ACTION_PASS_TO_USER) == 0) { 
// If music is playing but we decided not to pass the key to the 
// application, handle the volume change here. 
handleVolumeKey(AudioManager.STREAM_MUSIC, keyCode); 
break; 
} 
} 
break; 
} 
case KeyEvent.KEYCODE_ENDCALL: { 
result &= ~ACTION_PASS_TO_USER; 
if (down) { 
ITelephony telephonyService = getTelephonyService(); 
boolean hungUp = false; 
if (telephonyService != null) { 
try { 
hungUp = telephonyService.endCall(); 
} catch (RemoteException ex) { 
Log.w(TAG, "ITelephony threw RemoteException", ex); 
} 
} 
interceptPowerKeyDown(!isScreenOn || hungUp); 
} else { 
if (interceptPowerKeyUp(canceled)) { 
if ((mEndcallBehavior 
& Settings.System.END_BUTTON_BEHAVIOR_HOME) != 0) { 
if (goHome()) { 
break; 
} 
} 
if ((mEndcallBehavior 
& Settings.System.END_BUTTON_BEHAVIOR_SLEEP) != 0) { 
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP; 
} 
} 
} 
break; 
} 
case KeyEvent.KEYCODE_POWER: { 
result &= ~ACTION_PASS_TO_USER; 
if (down) { 
if (isScreenOn && !mPowerKeyTriggered 
&& (event.getFlags() & KeyEvent.FLAG_FALLBACK) == 0) { 
mPowerKeyTriggered = true; 
mPowerKeyTime = event.getDownTime(); 
interceptScreenshotChord(); 
} 
ITelephony telephonyService = getTelephonyService(); 
boolean hungUp = false; 
if (telephonyService != null) { 
try { 
if (telephonyService.isRinging()) { 
// Pressing Power while there's a ringing incoming 
// call should silence the ringer. 
telephonyService.silenceRinger(); 
} else if ((mIncallPowerBehavior 
& Settings.Secure.INCALL_POWER_BUTTON_BEHAVIOR_HANGUP) != 0 
&& telephonyService.isOffhook()) { 
// Otherwise, if "Power button ends call" is enabled, 
// the Power button will hang up any current active call. 
hungUp = telephonyService.endCall(); 
} 
} catch (RemoteException ex) { 
Log.w(TAG, "ITelephony threw RemoteException", ex); 
} 
} 
interceptPowerKeyDown(!isScreenOn || hungUp 
|| mVolumeDownKeyTriggered || mVolumeUpKeyTriggered); 
} else { 
mPowerKeyTriggered = false; 
cancelPendingScreenshotChordAction(); 
if (interceptPowerKeyUp(canceled || mPendingPowerKeyUpCanceled)) { 
result = (result & ~ACTION_WAKE_UP) | ACTION_GO_TO_SLEEP; 
} 
mPendingPowerKeyUpCanceled = false; 
} 
break; 
}

响应截屏的方法:

private void interceptScreenshotChord() { 
if (mScreenshotChordEnabled 
&& mVolumeDownKeyTriggered && mPowerKeyTriggered && !mVolumeUpKeyTriggered) { 
final long now = SystemClock.uptimeMillis(); 
if (now 

接受响应的服务

private final Runnable mScreenshotChordLongPress = new Runnable() { 
public void run() { 
takeScreenshot(); 
} 
}; 
private void takeScreenshot() { 
synchronized (mScreenshotLock) { 
if (mScreenshotConnection != null) { 
return; 
} 
ComponentName cn = new ComponentName("com.android.systemui", 
"com.android.systemui.screenshot.TakeScreenshotService"); 
Intent intent = new Intent(); 
intent.setComponent(cn); 
ServiceConnection conn = new ServiceConnection() { 
@Override 
public void onServiceConnected(ComponentName name, IBinder service) { 
synchronized (mScreenshotLock) { 
if (mScreenshotConnection != this) { 
return; 
} 
Messenger messenger = new Messenger(service); 
Message msg = Message.obtain(null, 1); 
final ServiceConnection myConn = this; 
Handler h = new Handler(mHandler.getLooper()) { 
@Override 
public void handleMessage(Message msg) { 
synchronized (mScreenshotLock) { 
if (mScreenshotConnection == myConn) { 
mContext.unbindService(mScreenshotConnection); 
mScreenshotConnection = null; 
mHandler.removeCallbacks(mScreenshotTimeout); 
} 
} 
} 
}; 
msg.replyTo = new Messenger(h); 
msg.arg1 = msg.arg2 = 0; 
if (mStatusBar != null && mStatusBar.isVisibleLw()) 
msg.arg1 = 1; 
if (mNavigationBar != null && mNavigationBar.isVisibleLw()) 
msg.arg2 = 1; 
try { 
messenger.send(msg); 
} catch (RemoteException e) { 
} 
} 
} 
@Override 
public void onServiceDisconnected(ComponentName name) {} 
}; 
if (mContext.bindService( 
intent, conn, Context.BIND_AUTO_CREATE, UserHandle.USER_CURRENT)) { 
mScreenshotConnection = conn; 
mHandler.postDelayed(mScreenshotTimeout, 10000); 
} 
} 
}

启动时这个服务 ComponentName cn = new ComponentName("com.android.systemui", "com.android.systemui.screenshot.TakeScreenshotService");

package com.android.systemui.screenshot; 
import android.app.Service; 
import android.content.Intent; 
import android.os.Handler; 
import android.os.IBinder; 
import android.os.Message; 
import android.os.Messenger; 
import android.os.RemoteException; 
public class TakeScreenshotService extends Service { 
private static final String TAG = "TakeScreenshotService"; 
private static GlobalScreenshot mScreenshot; 
private Handler mHandler = new Handler() { 
@Override 
public void handleMessage(Message msg) { 
switch (msg.what) { 
case 1: 
final Messenger callback = msg.replyTo; 
if (mScreenshot == null) { 
mScreenshot = new GlobalScreenshot(TakeScreenshotService.this); 
} 
mScreenshot.takeScreenshot(new Runnable() { 
@Override public void run() { 
Message reply = Message.obtain(null, 1); 
try { 
callback.send(reply); 
} catch (RemoteException e) { 
} 
} 
}, msg.arg1 > 0, msg.arg2 > 0); 
} 
} 
}; 
@Override 
public IBinder onBind(Intent intent) { 
return new Messenger(mHandler).getBinder(); 
}

再往下就是底层库,需要编译出来才能看得到了。这些就先不研究了。

6、还有部分系统源码是截图的

/* 
* Copyright (C) 2011 The Android Open Source Project 
* 
* Licensed under the Apache License, Version 2.0 (the "License"); 
* you may not use this file except in compliance with the License. 
* You may obtain a copy of the License at 
* 
* http://www.apache.org/licenses/LICENSE-2.0 
* 
* Unless required by applicable law or agreed to in writing, software 
* distributed under the License is distributed on an "AS IS" BASIS, 
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
* See the License for the specific language governing permissions and 
* limitations under the License. 
*/ 
package com.android.systemui.screenshot; 
import android.animation.Animator; 
import android.animation.AnimatorListenerAdapter; 
import android.animation.AnimatorSet; 
import android.animation.ValueAnimator; 
import android.animation.ValueAnimator.AnimatorUpdateListener; 
import android.app.Notification; 
import android.app.Notification.BigPictureStyle; 
import android.app.NotificationManager; 
import android.app.PendingIntent; 
import android.content.ContentResolver; 
import android.content.ContentValues; 
import android.content.Context; 
import android.content.Intent; 
import android.content.res.Resources; 
import android.graphics.Bitmap; 
import android.graphics.Canvas; 
import android.graphics.ColorMatrix; 
import android.graphics.ColorMatrixColorFilter; 
import android.graphics.Matrix; 
import android.graphics.Paint; 
import android.graphics.PixelFormat; 
import android.graphics.PointF; 
import android.media.MediaActionSound; 
import android.net.Uri; 
import android.os.AsyncTask; 
import android.os.Environment; 
import android.os.Process; 
import android.provider.MediaStore; 
import android.util.DisplayMetrics; 
import android.view.Display; 
import android.view.LayoutInflater; 
import android.view.MotionEvent; 
import android.view.Surface; 
import android.view.View; 
import android.view.ViewGroup; 
import android.view.WindowManager; 
import android.view.animation.Interpolator; 
import android.widget.ImageView; 
import com.android.systemui.R; 
import java.io.File; 
import java.io.OutputStream; 
import java.text.SimpleDateFormat; 
import java.util.Date; 
/** 
* 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; 
} 
/** 
* An AsyncTask that saves an image to the media store in the background. 
*/ 
class SaveImageInBackgroundTask extends AsyncTask { 
private static final String SCREENSHOTS_DIR_NAME = "Screenshots"; 
private static final String SCREENSHOT_FILE_NAME_TEMPLATE = "Screenshot_%s.png"; 
private static final String SCREENSHOT_FILE_PATH_TEMPLATE = "%s/%s/%s"; 
private int mNotificationId; 
private NotificationManager mNotificationManager; 
private Notification.Builder mNotificationBuilder; 
private String mImageFileName; 
private String mImageFilePath; 
private long mImageTime; 
private BigPictureStyle mNotificationStyle; 
// WORKAROUND: We want the same notification across screenshots that we update so that we don't 
// spam a user's notification drawer. However, we only show the ticker for the saving state 
// and if the ticker text is the same as the previous notification, then it will not show. So 
// for now, we just add and remove a space from the ticker text to trigger the animation when 
// necessary. 
private static boolean mTickerAddSpace; 
SaveImageInBackgroundTask(Context context, SaveImageInBackgroundData data, 
NotificationManager nManager, int nId) { 
Resources r = context.getResources(); 
// Prepare all the output metadata 
mImageTime = System.currentTimeMillis(); 
String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date(mImageTime)); 
String imageDir = Environment.getExternalStoragePublicDirectory( 
Environment.DIRECTORY_PICTURES).getAbsolutePath(); 
mImageFileName = String.format(SCREENSHOT_FILE_NAME_TEMPLATE, imageDate); 
mImageFilePath = String.format(SCREENSHOT_FILE_PATH_TEMPLATE, imageDir, 
SCREENSHOTS_DIR_NAME, mImageFileName); 
// Create the large notification icon 
int imageWidth = data.image.getWidth(); 
int imageHeight = data.image.getHeight(); 
int iconSize = data.iconSize; 
final int shortSide = imageWidth  0) { 
// Show a message that we've failed to save the image to disk 
GlobalScreenshot.notifyScreenshotError(params.context, mNotificationManager); 
} else { 
// Show the final notification to indicate screenshot saved 
Resources r = params.context.getResources(); 
// Create the intent to show the screenshot in gallery 
Intent launchIntent = new Intent(Intent.ACTION_VIEW); 
launchIntent.setDataAndType(params.imageUri, "image/png"); 
launchIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
mNotificationBuilder 
.setContentTitle(r.getString(R.string.screenshot_saved_title)) 
.setContentText(r.getString(R.string.screenshot_saved_text)) 
.setContentIntent(PendingIntent.getActivity(params.context, 0, launchIntent, 0)) 
.setWhen(System.currentTimeMillis()) 
.setAutoCancel(true); 
Notification n = mNotificationBuilder.build(); 
n.flags &= ~Notification.FLAG_NO_CLEAR; 
mNotificationManager.notify(mNotificationId, n); 
} 
params.finisher.run(); 
} 
} 
/** 
* 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 int SCREENSHOT_NOTIFICATION_ID = 789; 
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 NotificationManager mNotificationManager; 
private Display mDisplay; 
private DisplayMetrics mDisplayMetrics; 
private Matrix mDisplayMatrix; 
private Bitmap mScreenBitmap; 
private View mScreenshotLayout; 
private ImageView mBackgroundView; 
private ImageView mScreenshotView; 
private ImageView mScreenshotFlash; 
private AnimatorSet mScreenshotAnimation; 
private int mNotificationIconSize; 
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 
mDisplayMatrix = new Matrix(); 
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_SECURE_SYSTEM_OVERLAY, 
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); 
mNotificationManager = 
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); 
mDisplay = mWindowManager.getDefaultDisplay(); 
mDisplayMetrics = new DisplayMetrics(); 
mDisplay.getRealMetrics(mDisplayMetrics); 
// Get the various target sizes 
mNotificationIconSize = 
r.getDimensionPixelSize(android.R.dimen.notification_large_icon_height); 
// 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); 
} 
/** 
* Creates a new worker thread and saves the screenshot to the media store. 
*/ 
private void saveScreenshotInWorkerThread(Runnable finisher) { 
SaveImageInBackgroundData data = new SaveImageInBackgroundData(); 
data.context = mContext; 
data.image = mScreenBitmap; 
data.iconSize = mNotificationIconSize; 
data.finisher = finisher; 
new SaveImageInBackgroundTask(mContext, data, mNotificationManager, 
SCREENSHOT_NOTIFICATION_ID).execute(data); 
} 
/** 
* @return the current display rotation in degrees 
*/ 
private float getDegreesForRotation(int value) { 
switch (value) { 
case Surface.ROTATION_90: 
return 360f - 90f; 
case Surface.ROTATION_180: 
return 360f - 180f; 
case Surface.ROTATION_270: 
return 360f - 270f; 
} 
return 0f; 
} 
/** 
* Takes a screenshot of the current display and shows an animation. 
*/ 
void takeScreenshot(Runnable finisher, boolean statusBarVisible, boolean navBarVisible) { 
// We need to orient the screenshot correctly (and the Surface api seems to take screenshots 
// only in the natural orientation of the device :!) 
mDisplay.getRealMetrics(mDisplayMetrics); 
float[] dims = {mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels}; 
float degrees = getDegreesForRotation(mDisplay.getRotation()); 
boolean requiresRotation = (degrees > 0); 
if (requiresRotation) { 
// Get the dimensions of the device in its native orientation 
mDisplayMatrix.reset(); 
mDisplayMatrix.preRotate(-degrees); 
mDisplayMatrix.mapPoints(dims); 
dims[0] = Math.abs(dims[0]); 
dims[1] = Math.abs(dims[1]); 
} 
// Take the screenshot 
mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]); 
if (mScreenBitmap == null) { 
notifyScreenshotError(mContext, mNotificationManager); 
finisher.run(); 
return; 
} 
if (requiresRotation) { 
// Rotate the screenshot to the current orientation 
Bitmap ss = Bitmap.createBitmap(mDisplayMetrics.widthPixels, 
mDisplayMetrics.heightPixels, Bitmap.Config.ARGB_8888); 
Canvas c = new Canvas(ss); 
c.translate(ss.getWidth() / 2, ss.getHeight() / 2); 
c.rotate(degrees); 
c.translate(-dims[0] / 2, -dims[1] / 2); 
c.drawBitmap(mScreenBitmap, 0, 0, null); 
c.setBitmap(null); 
mScreenBitmap = ss; 
} 
// Optimizations 
mScreenBitmap.setHasAlpha(false); 
mScreenBitmap.prepareToDraw(); 
// Start the post-screenshot animation 
startAnimation(finisher, mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels, 
statusBarVisible, navBarVisible); 
} 
/** 
* 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(); 
} 
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); 
} 
}); 
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 

可以从这部分源码中,去寻找解决办法。

其中有一个很重要的方法就是

mScreenBitmap = Surface.screenshot((int) dims[0], (int) dims[1]);

这个是可以截图的,但是是隐藏的代码,不提供外面调用的。

注意需要在AndroidManifest.xml中加入代码:android:sharedUserId="android.uid.system" 进行后续开发。

上文就是小编介绍Android屏幕截屏的方法,如您对本文有所疑义或者有任何需求,请留言,小编为您一一解惑。

上一篇:Android如何实现Toast提示框图文并存

下一篇:Android仿微信二维码和条码

您可能感兴趣的文章

相关阅读

热门软件源码

最新软件源码下载