Android5.0屏幕截屏與屏幕錄製

一、屏幕截屏

1、屏幕截屏的步驟:

1:通過 getSystemService()得到MediaProjectionManager服務;
2:通過MediaProjectionManager創建一個屏幕捕捉意圖;
3:通過startActivityForResult開啓該意圖;
4:創建ImageReader、MediaProjection對象,然後通過mediaProjection.createVirtualDisplay()創建一個VirtualDisplay對象,並把mImageReader.getSurface()作爲createVirtualDisplay()第六個參數;
5: 通過ImageReader.acquireLatestImage()得到Image;通過Image得到Bitmap.createBitmap()的參數;

2、實例代碼

通過點擊Button,在ImageView中顯示截取的屏幕。
界面佈局:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/ll"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.zjl.jieping.MainActivity"
    android:orientation="vertical"
    android:background="#f00"
    >

    <Button
        android:id="@+id/jieTu"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="截圖"
        android:textSize="24sp"
        />
    <ImageView
        android:id="@+id/imageView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="centerInside"
        />
</LinearLayout>

Activity:

public class MainActivity extends Activity {

    private Button bt_jietu;
    private ImageView imageView;
    private MediaProjection mediaProjection;
    private VirtualDisplay mVirtualDisplay;
    private MediaProjectionManager mediaProjectionManager;
    private static final int REQUESTRESULT = 0x100;
    private int mWidth;
    private int mHeight;
    private int mScreenDensity;
    private ImageReader mImageReader;
    private LinearLayout ll;

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

    private void initData() {
        mediaProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        Display display = getWindowManager().getDefaultDisplay();
        mWidth = display.getWidth();
        mHeight = display.getHeight();
        DisplayMetrics outMetric = new DisplayMetrics();
        display.getMetrics(outMetric);
        mScreenDensity = (int) outMetric.density;
        Intent intent = new Intent(mediaProjectionManager.createScreenCaptureIntent());
        startActivityForResult(intent,REQUESTRESULT);
    }

    private void initView() {
        bt_jietu = (Button) this.findViewById(R.id.jieTu);
        bt_jietu.setOnClickListener(new MyOnClickListener());
        imageView = (ImageView) this.findViewById(R.id.imageView);
        ll = (LinearLayout) this.findViewById(R.id.ll);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (resultCode == RESULT_OK) {
            mImageReader = ImageReader.newInstance(mWidth,mHeight, PixelFormat.RGBA_8888, 2);
            mediaProjection = mediaProjectionManager.getMediaProjection(resultCode,data);
            mVirtualDisplay = mediaProjection.createVirtualDisplay("mediaprojection",mWidth,mHeight,
                    mScreenDensity, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,mImageReader.getSurface(),null,null);

        }
    } 

    private final class MyOnClickListener implements View.OnClickListener {

        @Override
        public void onClick(View v) {
            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();
            imageView.setImageBitmap(bitmap);
            ll.setBackgroundColor(0x0f0);
        }
    }
}

3、注意

Android屏幕錄製存在漏洞:可以查看該博客 Android中利用5.0系統屏幕錄製UI漏洞騙取應用錄製屏幕授權

二、屏幕錄製

屏幕錄製與屏幕截屏的佈置大致相同;同樣也需要使用MediaProjection、VirtualDisplay,不過它還需要MediaRecorder;不在需要ImageReader而已!

1、屏幕錄製的步驟:

1:通過 getSystemService()得到MediaProjectionManager服務;
2、創建MediaRecorder對象,並把音視頻的編碼、輸出方式設置好(有時我們可能會遇到設置音頻後,程序運行會報錯!); 準備錄製;
2:通過MediaProjectionManager創建一個屏幕捕捉意圖;
3:通過startActivityForResult開啓該意圖;
4:創建MediaProjection對象,然後通過mediaProjection.createVirtualDisplay()創建一個VirtualDisplay對象,並把mMediaRecorder.getSurface()作爲createVirtualDisplay()第六個參數;

2、實例代碼

初始化MediaRecorder

    /**
         *  視頻編碼格式:default,H263,H264,MPEG_4_SP
            獲得視頻資源:default,CAMERA
            音頻編碼格式:default,AAC,AMR_NB,AMR_WB
            獲得音頻資源:defalut,camcorder,mic,voice_call,voice_communication,
                      voice_downlink,voice_recognition, voice_uplink
            輸出方式:amr_nb,amr_wb,default,mpeg_4,raw_amr,three_gpp
    */
    //設置音頻源
    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
    //設置視頻源:Surface和Camera 兩種
    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
    //設置視頻輸出格式
    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    //設置視頻編碼格式
    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
    //設置音頻編碼格式
    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    //設置視頻編碼的碼率
    mMediaRecorder.setVideoEncodingBitRate(512 * 1000);
    //設置視頻編碼的幀率
    mMediaRecorder.setVideoFrameRate(30);
    //設置視頻尺寸大小
    mMediaRecorder.setVideoSize(DISPLAY_WIDTH, DISPLAY_HEIGHT);
    //設置視頻輸出路徑
    mMediaRecorder.setOutputFile(path);

其他的代碼與屏幕錄製相同,這裏不再附加;可以從這裏進行下載寫好的Demo,可以直接運行;
Android 5.0 屏幕錄製

發佈了38 篇原創文章 · 獲贊 45 · 訪問量 9萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章