Android 5.0+的截屏

Android 5.0+截屏

Android 5.0+截屏 非后台截屏 需要Activity的配合

观察5.0+的源码不难发现,Android为我们提供了android.media.projection.MediaProjectionManager 类,我们可以使用它去截取Android系统屏幕内容

package com.example.helloworld;

import java.io.IOException;
import java.io.OutputStream;
import java.text.SimpleDateFormat;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.media.projection.MediaProjectionManager;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.TextView;

public class MainActivity extends Activity {

    private TextView tv_snap;
    private Intent mResultIntent = null;
    private int mResultCode = 0;
    private static final int REQUEST_MEDIA_PROJECTION = 1;
    private MediaProjectionManager mMpMngr;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        PathUtil.getInstance().init(MainActivity.this);

        tv_snap = (TextView) findViewById(R.id.tv_snap);

        tv_snap.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                try {
                    SLog.Console("点击事件触发截屏事件");
                    // takeSnapShoot();
                    // rootOrNot();
                    // startService(new Intent(MainActivity.this,
                    // CaptureService.class));
                    startIntent();
                } catch (Exception e) {
                    e.printStackTrace();
                    SLog.Console(e.toString());
                }
            }
        });

        mResultIntent = ((MyApplication) getApplication()).getResultIntent();
        mResultCode = ((MyApplication) getApplication()).getResultCode();
        mMpMngr = (MediaProjectionManager) getApplicationContext().getSystemService(Context.MEDIA_PROJECTION_SERVICE);

        // startService(new Intent(getApplicationContext(), LogService.class));
    }

    private void startIntent() {
        if (mResultIntent != null && mResultCode != 0) {
            SLog.Console("mResultIntent:" + mResultIntent + "   " + "mResultCode:" + mResultCode);
            startService(new Intent(getApplicationContext(), CaptureService.class));
        } else {
            startActivityForResult(mMpMngr.createScreenCaptureIntent(), REQUEST_MEDIA_PROJECTION);
        }
    }

    // 就是因为需要这个返回值,所以不能完全移植到Service中,还是需要依赖MainActivity
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == REQUEST_MEDIA_PROJECTION) {
            if (resultCode == RESULT_OK) {
                SLog.Console("get capture permission success!");
                mResultCode = resultCode;
                mResultIntent = data;
                SLog.Console("onActivityResult---"+"mResultIntent:" + mResultIntent + "   " + "mResultCode:" + mResultCode);
                ((MyApplication) getApplication()).setResultCode(resultCode);
                ((MyApplication) getApplication()).setResultIntent(data);
                ((MyApplication) getApplication()).setMpmngr(mMpMngr);
                startService(new Intent(getApplicationContext(), CaptureService.class));
            }
        }
    }
}

Service中主要做对应的截屏操作

package com.example.helloworld;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Timer;
import java.util.TimerTask;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.PixelFormat;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.Image;
import android.media.ImageReader;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.os.Environment;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.support.annotation.Nullable;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.Toast;

/**
 * 截屏service
 * 
 * @author hanzhe
 * @date 2017年4月12日 上午10:47:33
 */
public class CaptureService extends Service {

    private static final String TAG = "CService";

    private MediaProjectionManager mMpmngr;
    private MediaProjection mMpj;
    private ImageReader mImageReader;
    private String mImageName;
    private String mImagePath;
    private int screenDensity;
    private int windowWidth;
    private int windowHeight;
    private VirtualDisplay mVirtualDisplay;
    private WindowManager wm;

    private static final int MESSAGE_WHAT_TIME = 0x1001;
    private Timer mTimer;
    private static final int HEART_SPE = 1 * 60 * 1000;

    private Handler mHandler = new Handler() {

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case MESSAGE_WHAT_TIME :
                    createFloatView();
                    break;
                default :
                    break;
            }
        }

    };

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        createEnvironment();
        mTimer = new Timer();
        mTimer.schedule(new TimerTask() {
            @Override
            public void run() {
                mHandler.sendEmptyMessage(MESSAGE_WHAT_TIME);
            }
        }, 5 * 1000, HEART_SPE/* 表示5000毫秒之後,每隔1000毫秒執行一次 */);
    }

    private void createEnvironment() {
        mImagePath = Environment.getExternalStorageDirectory().getPath() + "/screenshort/";
        mMpmngr = ((MyApplication) getApplication()).getMpmngr();
        wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
        windowWidth = wm.getDefaultDisplay().getWidth();
        windowHeight = wm.getDefaultDisplay().getHeight();
        DisplayMetrics displayMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(displayMetrics);
        screenDensity = displayMetrics.densityDpi;
        mImageReader = ImageReader.newInstance(windowWidth, windowHeight, 0x1, 2);

    }

    private void createFloatView() {

        Handler handler = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                SLog.Console("start startVirtual");
                startVirtual();
            }
        }, 500);
        // Handler handler1 = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                SLog.Console("start startCapture");
                startCapture();
            }
        }, 1000);
        // Handler handler2 = new Handler();
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                SLog.Console("start stopVirtual");
                stopVirtual();
            }
        }, 1500);
    }

    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 ");
                Toast.makeText(this.getApplicationContext(), "截图成功", Toast.LENGTH_SHORT).show();
            } catch (IOException e) {
                Log.e(TAG, e.toString());
                e.printStackTrace();
                SLog.Console(e.toString());
            }
        }
        SLog.Console("end startCapture");
    }

    private void startVirtual() {
        if (mMpj != null) {
            virtualDisplay();
        } else {
            setUpMediaProjection();
            virtualDisplay();
        }
    }

    private void setUpMediaProjection() {
        try {
            int resultCode = ((MyApplication) getApplication()).getResultCode();
            Intent data = ((MyApplication) getApplication()).getResultIntent();
            mMpj = mMpmngr.getMediaProjection(resultCode, data);
        } catch (Exception e) {
            SLog.Console("setUpMediaProjection" + e.toString());
        }
    }

    private void virtualDisplay() {
        try {
            mVirtualDisplay = mMpj.createVirtualDisplay("capture_screen", windowWidth, windowHeight, screenDensity,
                    DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, mImageReader.getSurface(), null, null);
        } catch (Exception e) {
            SLog.Console("virtualDisplay" + e.toString());
        }
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        if (mMpj != null) {
            mMpj.stop();
            mMpj = null;
        }
    }
}

最后,还是跪求能在后台直接截屏的方法,求不涉及ROOT和su权限

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值