Android 偷拍功能/手机关闭能拍照效果如下:

其实偷拍与偷录实现方式是一样的,都是使用到的WindowManager来绘制桌面小控件的原理。那我就不多说了…
一、首先我们需要一个SurfaceView:<?xml version="1.0" encoding="utf-8"?><LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:id="@+id/small_window_layout"android:layout_width="1dip"android:layout_height="1dip"><FrameLayoutandroid:id="@+id/percent"android:layout_width="fill_parent"android:layout_height="fill_parent"android:gravity="center"/></LinearLayout>
二、然后进行的操作就是生产这个小控件了:public PhotoWindowSmallView(Context context) {super(context);windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);LayoutInflater.from(context).inflate(R.layout.float_window_small, this);View view = findViewById(R.id.small_window_layout);viewWidth = view.getLayoutParams().width;viewHeight = view.getLayoutParams().height;//SurfaceView percentView = (SurfaceView) findViewById(R.id.percent);//percentView.setText(MyWindowManager.getUsedPercentValue(context));}/** * 将小悬浮窗的参数传入,用于更新小悬浮窗的位置。 * * @param params 小悬浮窗的参数 */public void setParams(WindowManager.LayoutParams params) {mParams = params;}
三、那桌面控件有了,下面当然就是使用WindowManager添加到桌面上了: /** * 创建一个小悬浮窗。初始位置为屏幕的右部中间位置。 * * @param context 必须为应用程序的Context. */public void createSmallWindow(Context context) {mContext = context;WindowManager windowManager = getWindowManager(context);int screenWidth = windowManager.getDefaultDisplay().getWidth();int screenHeight = windowManager.getDefaultDisplay().getHeight();if (smallWindow == null) {smallWindow = new PhotoWindowSmallView(context);if (smallWindowParams == null) {smallWindowParams = new LayoutParams();smallWindowParams.type = LayoutParams.TYPE_PHONE;smallWindowParams.format = PixelFormat.RGBA_8888;smallWindowParams.flags = LayoutParams.FLAG_NOT_TOUCH_MODAL| LayoutParams.FLAG_NOT_FOCUSABLE;smallWindowParams.gravity = Gravity.LEFT | Gravity.TOP;smallWindowParams.width = PhotoWindowSmallView.viewWidth;smallWindowParams.height = PhotoWindowSmallView.viewHeight;smallWindowParams.x = screenWidth;smallWindowParams.y = screenHeight / 2;}smallWindow.setParams(smallWindowParams);windowManager.addView(smallWindow, smallWindowParams);mSurfaceview = (FrameLayout) smallWindow.findViewById(R.id.percent);}}/** * 将小悬浮窗从屏幕上移除。 * * @param context 必须为应用程序的Context. */public void removeSmallWindow(Context context) {if (smallWindow != null) {WindowManager windowManager = getWindowManager(context);windowManager.removeView(smallWindow);smallWindow = null;}}
四、这个时候我们需要的SurfaceView就有了,那么,怎么在后台进行操作呢?自然而然就想到了Service了在Service中执行桌面控件的操作:
@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {myWindowManager = new MyPhotoWindowManager();createWindow();return super.onStartCommand(intent, flags, startId);}@Overridepublic void onDestroy() {super.onDestroy();}private void createWindow() {// 当前界面是桌面,且没有悬浮窗显示,则创建悬浮窗。myWindowManager.removeSmallWindow(getApplicationContext());myWindowManager.createSmallWindow(getApplicationContext());}
五、在activity中对Service绑定,进行拍照的操作private class MyServiceConn implements ServiceConnection {@Overridepublic void onServiceConnected(ComponentName name, IBinder service) {// TODO Auto-generated method stubbinder = (PhotoWindowService.myServiceBinder) service;if (isVedio) {binder.startCarema();} else {binder.stopCarema();}}@Overridepublic void onServiceDisconnected(ComponentName name) {// TODO Auto-generated method stub}}
六、在Service中控制myWindowManager中的拍照的开始和结束 public class myServiceBinder extends Binder {public void startCarema() {myWindowManager.startCarema();}public void stopCarema() {myWindowManager.stopCarema();}}
七、在MyPhotoWindowManager开启或终止拍照操作 public void startCarema() {itt = InitTimetoTakePic.getInstance(mContext);itt.initView(mSurfaceview);itt.start();}public void stopCarema() {if (itt != null)itt.releaseCarema();}
八、在InitTimetoTakePic进行拍照的相关处理
package com.ddv.www.candidphotodemo;import android.annotation.TargetApi;import android.app.Activity;import android.content.Context;import android.content.Intent;import android.content.pm.PackageManager;import android.hardware.Camera;import android.hardware.Camera.AutoFocusCallback;import android.hardware.Camera.PictureCallback;import android.os.Build;import android.os.Handler;import android.os.Message;import android.widget.FrameLayout;import java.io.File;import java.io.FileOutputStream;/** * 设置定时拍照功能 * * @author <p> * 创建定时拍照任务 * cameraType 摄像头 * resolutionString 分辨率 * tvSaveLocation 保存地址 * etExtension 拓展名 * cameraStart, 开始拍摄时间 * cameraNumber, 拍摄次数 * cameraStop 拍摄张数 */public class InitTimetoTakePic {private static InitTimetoTakePic mInstance;private static int cameraType = 1;Context mContext;static FrameLayout mSurfaceViewFrame;private static Camera mCamera;private static CameraPreview mPreview;private static String resolutionString = "1920x1080";private static String saveLocation = AppUtils.getSDCardPath();private static String extension = "JPG";private static String cameraStart = "1";private static String cameraNumber = "1";private static String cameraStop = "10";private static int number = 0;private static boolean clearVoice = false;private Intent intent;private InitTimetoTakePic(Context context) {this.mContext = context;}public synchronized static InitTimetoTakePic getInstance(Context context) {mInstance = null;mInstance = new InitTimetoTakePic(context);return mInstance;}public void initView(FrameLayout surfaceViewFrame) {mSurfaceViewFrame = surfaceViewFrame;}/** * 启动定时拍照并上传功能 */Handler mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {switch (msg.what) {case 1:LogUtils.v("开始拍照");initCarema();break;case 2:if (mCamera == null) {releaseCarema();number = 0;mHandler.removeCallbacksAndMessages(null);} else {if (number < Integer.valueOf(cameraStop)) {mCamera.autoFocus(new AutoFocusCallback() {@Overridepublic void onAutoFocus(boolean success, Camera camera) {// 从Camera捕获图片LogUtils.v("自动聚焦111" + success);try {mCamera.takePicture(null, null, mPicture);mHandler.sendEmptyMessageDelayed(1, Integer.valueOf(cameraNumber) * 1000);} catch (Exception e) {releaseCarema();mHandler.removeCallbacksAndMessages(null);}}});} else {releaseCarema();number = 0;mHandler.removeCallbacksAndMessages(null);}}break;}}};public void start() {mHandler.sendEmptyMessageDelayed(1, 1 * 1000); //7s 后开始启动相机}private void initCarema() {LogUtils.v("initCarema");if (mCamera == null) {LogUtils.v("camera=null");mCamera = getCameraInstance();mPreview = new CameraPreview(mContext, mCamera);mSurfaceViewFrame.removeAllViews();mSurfaceViewFrame.addView(mPreview);}LogUtils.v(mCamera == null ? "mCamera is null" : "mCamera is not null");mCamera.startPreview();mHandler.sendEmptyMessageDelayed(2, Integer.valueOf(cameraStart) * 1000); //3s后拍照}/** * 检测设备是否存在Camera硬件 */private boolean checkCameraHardware(Context context) {if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {// 存在return true;} else {// 不存在return false;}}/** * 打开一个Camera */@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)public static Camera getCameraInstance() {Camera c = null;try {c = Camera.open(cameraType);c.setDisplayOrientation(90);Camera.Parameters mParameters = c.getParameters();//快门声音c.enableShutterSound(clearVoice);//可以用得到当前所支持的照片大小,然后//List<Size> ms = mParameters.getSupportedPictureSizes();//mParameters.setPictureSize(ms.get(0).width, ms.get(0).height); //默认最大拍照取最大清晰度的照片String[] xes = resolutionString.split("x");// LogUtils.i("ms.get(0).width==>"+ms.get(0).width);// LogUtils.i("ms.get(0).height==>"+ms.get(0).height);// LogUtils.i("Integer.valueOf(xes[0])==>"+Integer.valueOf(xes[0]));// LogUtils.i("Integer.valueOf(xes[1])==>"+Integer.valueOf(xes[1]));mParameters.setPictureSize(Integer.valueOf(xes[0]), Integer.valueOf(xes[1])); //默认最大拍照取最大清晰度的照片c.setParameters(mParameters);} catch (Exception e) {LogUtils.v("打开Camera失败失败");}return c;}private PictureCallback mPicture = new PictureCallback() {@Overridepublic void onPictureTaken(byte[] data, Camera camera) {// 获取Jpeg图片,并保存在sd卡上String path = saveLocation;File dirF = new File(path);if (!dirF.exists()) {dirF.mkdirs();}File pictureFile = new File(path + "/" + System.currentTimeMillis() + "." + extension);//扩展名try {FileOutputStream fos = new FileOutputStream(pictureFile);fos.write(data);fos.close();LogUtils.v("保存图成功");number++;intent = new Intent();intent.setAction("CameraFragment.start");intent.putExtra("number", number);mContext.sendBroadcast(intent);} catch (Exception e) {LogUtils.v("保存图片失败");e.printStackTrace();}releaseCarema();}};public void releaseCarema() {if (mCamera != null) {mCamera.stopPreview();mCamera.release();mCamera = null;}}}
demo下载地址:http://www.jb51.net/softs/519032.html
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!