截屏的時候會有卡頓,暫時未解決。
第一種(這種截圖隻會截屏應用内,狀态欄是不會截到的):
調用方法
if (ContextCompat.checkSelfPermission(ShareCodeActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(ShareCodeActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 54);
Log.i("-->", "權限申請");
} else {
screenshot();
}
在調用之前需要判斷權限
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
doNext(requestCode, grantResults);
}
private void doNext(int requestCode, int[] grantResults) {
if (requestCode == 54) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
screenshot();
} else {
new AlertDialog.Builder(this)
.setTitle("權限申請")
.setMessage("在設定-應用-(應用名稱)-權限中啟動存儲權限,以正常使用此功能")
.setPositiveButton("去設定", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS);
startActivity(intent);
}
})
.setNegativeButton("取消", null)
.show();
}
}
}
接下來是截圖的具體方法:
/**
* 擷取螢幕
*/
private void screenshot() {
// 擷取螢幕
View dView = getWindow().getDecorView();
dView.setDrawingCacheEnabled(true);
dView.buildDrawingCache();
Bitmap bmp = dView.getDrawingCache();
File file = PathGetUtils.getFile(this);
if (bmp != null) {
try {
Log.i("-->", "路徑:" + file.getPath() + " " + file.getAbsolutePath());
if (file.exists()) {
file.delete();
}
FileOutputStream os = new FileOutputStream(file);
bmp.compress(Bitmap.CompressFormat.PNG, 100, os);
os.flush();
os.close();
String mUri = MediaStore.Images.Media.insertImage(getContentResolver(), file.getPath(), "ck", null);
if (mUri != null) {
Toast.makeText(ShareCodeActivity.this, "截圖成功", Toast.LENGTH_SHORT).show();
// 最後通知圖庫更新
Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri uri = Uri.fromFile(new File(mUri));
intent.setData(uri);
sendBroadcast(intent);
} else {
Toast.makeText(ShareCodeActivity.this, "截圖失敗", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
}
}
}
其中擷取的bitmap就是截屏圖檔.
第二種方法(這個隻支援5.0的系統以上,截取整個視圖):
調用方法,需要判斷api版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP){
mMpMngr = (MediaProjectionManager) getApplicationContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);
if(NoDoubleClick.isFastClick()){
startIntent();
}
}else {
Toast.makeText(this, "您的手機系統暫不支援截屏功能", Toast.LENGTH_SHORT).show();
}
接下來是截圖的方法
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//3、通過onActivityResult()擷取授權結果。
if (requestCode == REQUEST_MEDIA_PROJECTION && resultCode == RESULT_OK) {
MyApp.mResultCode = resultCode;
MyApp.mResultIntent = data;
MyApp.mMpmngr = mMpMngr;
newPrintScreen();
}
}
private void startIntent() {
if (MyApp.mResultIntent != null && MyApp.mResultCode != 0) {
//已授權
newPrintScreen();
} else{
//2、調用MediaProjectionManager.createScreenCaptureIntent()後,會彈出一個dialog詢問使用者是否授權應用捕捉螢幕
startActivityForResult(mMpMngr.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);//未授權
}
}
private void newPrintScreen(){
wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metric = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metric);
windowWidth = metric.widthPixels;
windowHeight = metric.heightPixels;
screenDensity = metric.densityDpi;
mImageReader = ImageReader.newInstance(windowWidth, windowHeight, 0x1, 2);
Handler handler = new Handler();
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.e(TAG, "start startVirtual");
startVirtual();
}
}, 000);
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.e(TAG, "start startCapture");
startCapture();
}
}, 500);
handler.postDelayed(new Runnable() {
@Override
public void run() {
Log.e(TAG, "start stopVirtual");
stopVirtual();
}
}, 1000);
}
private void stopVirtual() {
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
mVirtualDisplay = null;
}
}
private void startCapture() {
mImageName = System.currentTimeMillis() + ".png";
Log.e(TAG, "image name is : " + mImageName);
Image image = mImageReader.acquireLatestImage();
int width = image.getWidth();
int height = image.getHeight();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
Bitmap bitmap = Bitmap.createBitmap(width + rowPadding / pixelStride, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
bitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height);
image.close();
if (bitmap != null) {
Log.e(TAG, "bitmap create success ");
try {
File fileFolder = new File(mImagePath);
if (!fileFolder.exists()) fileFolder.mkdirs();
File file = new File(mImagePath, mImageName);
if (!file.exists()) {
Log.e(TAG, "file create success ");
file.createNewFile();
}
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
Log.e(TAG, "file save success ");
shareDialog(bitmap);
if (mMpj != null) {
mMpj.stop();
mMpj = null;
}
} catch (IOException e) {
Log.e(TAG, e.toString());
e.printStackTrace();
}
}
}
private void startVirtual() {
if (mMpj == null) mMpj = MyApp.mMpmngr.getMediaProjection(MyApp.mResultCode, MyApp.mResultIntent);
mVirtualDisplay = mMpj.createVirtualDisplay("capture_screen", windowWidth, windowHeight, screenDensity,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
}
這種方法需要手動允許截屏的權限。