[안드로이드 앱 개발] - (13) 화면 캡처 기능 - 전체 화면을 캡처하여 Root(부원코드) 필요 없음

설명서를 작성하거나 고객에게 효과도를 보여줘야 하기 때문에 캡처하는 방식으로 화면을 이어야 한다(당연하지, 사진을 찍어서 목적을 달성할 수도 있다).따라서 Google은 루트 권한이 필요하거나, 루트 권한이 필요하지 않은 캡처 애플리케이션을 찾았지만, 실망스럽게도 대부분 사용할 수 없습니다.그래서 스스로 캡처 앱을 개발하고 싶어요.뷰에서 getDrawingCache 방법을 제공합니다. 다음 방법으로 뷰의 캡처를 얻을 수 있지만, 단지 뷰를 캡처할 수 있습니다.상태막대를 캡처하려면?
그렇지 않으면 ICS의 SystemUI에서 캡처 기능을 실현하고 조합키인 Power+Volume Add/Volume sub을 누르면 그림을 캡처할 수 있다.코드 디렉터리:frameworks/base/packages/SystemUI/src/com/android/systemui/screenshot/이 디렉터리에 두 개의 파일이 있는데 주요한 캡처 방법은 GlobalScreenshot에서 본고는 SystemUI에서 캡처한 코드를 이식하여 캡처 기능을 실현하고자 한다.
먼저 SystemUI의 코드를 직접 이식하여 캡처 효과를 실현한다. 이 부분의 코드는 붙이지 않고 코드를 다운로드하자. 관건적인 코드는 몇 마디가 없다. 가장 중요한 것은Surface이다.screenshot(), 코드를 보십시오.
package org.winplus.ss;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.os.SystemProperties;

public class SimpleScreenshotActivity extends Activity {

	private Display mDisplay;
	private WindowManager mWindowManager;
	private DisplayMetrics mDisplayMetrics;
	private Bitmap mScreenBitmap;
	private Matrix mDisplayMatrix;

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.main);

		new Thread(new Runnable() {

			@Override
			public void run() {
				takeScreenshot();

			}
		}).start();
	}

	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;
	}

	private void takeScreenshot() {
		mWindowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
		mDisplay = mWindowManager.getDefaultDisplay();
		mDisplayMetrics = new DisplayMetrics();
		mDisplay.getRealMetrics(mDisplayMetrics);
		mDisplayMatrix = new Matrix();
		float[] dims = { mDisplayMetrics.widthPixels,
				mDisplayMetrics.heightPixels };

		int value = mDisplay.getRotation();
		String hwRotation = SystemProperties.get("ro.sf.hwrotation", "0");
		if (hwRotation.equals("270") || hwRotation.equals("90")) {
			value = (value + 3) % 4;
		}
		float degrees = getDegreesForRotation(value);

		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]);
		}

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

		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;
        }

        // If we couldn't take the screenshot, notify the user
        if (mScreenBitmap == null) {
            return;
        }

        // Optimizations
        mScreenBitmap.setHasAlpha(false);
        mScreenBitmap.prepareToDraw();
        
		try {
			saveBitmap(mScreenBitmap);
		} catch (IOException e) {
			System.out.println(e.getMessage());
		}
	}

	public void saveBitmap(Bitmap bitmap) throws IOException {
		String imageDate = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss")
				.format(new Date(System.currentTimeMillis()));
		File file = new File("/mnt/sdcard/Pictures/"+imageDate+".png");
		if(!file.exists()){
			file.createNewFile();
		}
		FileOutputStream out;
		try {
			out = new FileOutputStream(file);
			if (bitmap.compress(Bitmap.CompressFormat.PNG, 70, out)) {
				out.flush();
				out.close();
			}
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

PS:1 AndroidManifest에 있어야 합니다.xml에 코드 추가:android:sharedUserId="android.uid.system"
2. @hide의 API가 호출되었기 때문에makefile로 컴파일하십시오.또는 Eclipse에 Jar 파일을 추가하여 컴파일합니다.
3. 이 코드는 안드로이드 4.0에서 사용했지만 2.3은 테스트를 하지 않았다.
오리지널 문장 전재는 출처를 밝혀 주십시오.http://www.blog.csdn.net/tangcheng_ok

좋은 웹페이지 즐겨찾기