適配了Android5.0以上的截圖方法紊遵,實現(xiàn)了后臺連續(xù)截圖沐悦;使用該方法請求授權(quán)同意后開始截圖:
private MediaProjectionManager mMediaProjectionManager;
public void getMediaProjectionManger() {
mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if (mMediaProjectionManager != null) {
startActivityForResult(mMediaProjectionManager.createScreenCaptureIntent(), RECORD_REQUEST_CODE);
}
}
由于targetSdkVersion 29及以上要求getMediaProjection需要再前臺服務(wù)執(zhí)行,所以在onActivityResult里面啟動服務(wù):
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == RECORD_REQUEST_CODE && resultCode == RESULT_OK) {
Intent intent = new Intent(ZkScreenshotActivity.this, ZkA5AboveScreenshotService.class);
intent.putExtra("code",resultCode);
intent.putExtra("data",data);
ZkUtlis.startService(ZkScreenshotActivity.this,intent);
}
}
Service方法如下:
public class ZkA5AboveScreenshotService extends Service {
private String mTag = "ZkA5AboveScreenshotService";
private int mResultCode;
private Intent mResultData;
private MediaProjection mMediaProjection;
private MediaProjectionManager mMediaProjectionManager;
private int mWidth;
private int mHeight;
private int mDensity;
private ImageReader mImageReader;
private int mImagesProduced;
private int mCount = 0;
@Override
public void onCreate() {
super.onCreate();
mMediaProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
createNotificationChannel();
mResultCode = intent.getIntExtra("code", -1);
mResultData = intent.getParcelableExtra("data");
mMediaProjection = mMediaProjectionManager.getMediaProjection(mResultCode, Objects.requireNonNull(mResultData));
Log.d(mTag, "mMediaProjection created: " + mMediaProjection);
startCaptureReader();
return super.onStartCommand(intent, flags, startId);
}
/**
* startCaptureReader
*/
@SuppressLint("WrongConstant")
private void startCaptureReader() {
WindowManager wm = (WindowManager) getBaseContext().getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
mWidth = size.x;
mHeight = size.y;
Log.d(mTag,"width:" + mWidth + " height:" + mHeight);
DisplayMetrics metrics = getResources().getDisplayMetrics();
mDensity = metrics.densityDpi;
// start capture reader
mImageReader = ImageReader.newInstance(mWidth, mHeight, 0x01, 2);
mMediaProjection.createVirtualDisplay("screencap", mWidth, mHeight, mDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), null);
}
/**
* ImageAvailableListener
*/
private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
@Override
public void onImageAvailable(ImageReader reader) {
try (Image image = reader.acquireLatestImage()) {
if (image != null) {
/**
* 截圖結(jié)果崔兴,會在內(nèi)容更新自動回調(diào)彰导,該方法可以實現(xiàn)連續(xù)截圖蛔翅,無需重復(fù)啟用截圖方法
*/
}
image.close();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* Create Notification Channel
*/
private void createNotificationChannel() {
//獲取一個Notification構(gòu)造器
Notification.Builder builder = new Notification.Builder(this.getApplicationContext());
//點擊后跳轉(zhuǎn)的界面,可以設(shè)置跳轉(zhuǎn)數(shù)據(jù)
Intent nfIntent = new Intent(this, ZkScreenshotActivity.class);
// 設(shè)置PendingIntent
builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0))
// 設(shè)置下拉列表中的圖標(biāo)(大圖標(biāo))
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.mipmap.ic_launcher))
// 設(shè)置下拉列表里的標(biāo)題
//.setContentTitle("SMI InstantView")
// 設(shè)置狀態(tài)欄內(nèi)的小圖標(biāo)
.setSmallIcon(R.mipmap.ic_launcher)
// 設(shè)置上下文內(nèi)容
.setContentText("is running......")
// 設(shè)置該通知發(fā)生的時間
.setWhen(System.currentTimeMillis());
/*以下是對Android 8.0的適配*/
//普通notification適配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
builder.setChannelId("notification_id");
}
//前臺服務(wù)notification適配
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
NotificationChannel channel = new NotificationChannel("notification_id", "notification_name", NotificationManager.IMPORTANCE_LOW);
notificationManager.createNotificationChannel(channel);
}
// 獲取構(gòu)建好的Notification
Notification notification = builder.build();
//設(shè)置為默認(rèn)的聲音
notification.defaults = Notification.DEFAULT_SOUND;
startForeground(110, notification);
}
@Override
public void onDestroy() {
super.onDestroy();
Log.d(mTag, "Service onDestroy");
if (mImageReader != null) {
mImageReader.setOnImageAvailableListener(null,null);
mImageReader.close();
mImageReader = null;
}
if (mMediaProjection != null) {
mMediaProjection.stop();
mMediaProjection = null;
}
mMediaProjectionManager = null;
}
下面是將Image轉(zhuǎn)Bitmap
/**
* Image 轉(zhuǎn) Bitmap
* @param image
*/
private Bitmap imageToBitmap(Image image) {
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;
Bitmap bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
return bitmap;
}