Android 偷拍功能/手机关闭能拍照
效果如下:
其实偷拍与偷录实现方式是一样的,都是使用到的WindowManager来绘制桌面小控件的原理。那我就不多说了…
一、首先我们需要一个SurfaceView:
<?xmlversion="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/small_window_layout" android:layout_width="1dip" android:layout_height="1dip" > <FrameLayout android:id="@+id/percent" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" /> </LinearLayout> |
二、然后进行的操作就是生产这个小控件了:
publicPhotoWindowSmallView(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 小悬浮窗的参数 */ publicvoidsetParams(WindowManager.LayoutParams params) { mParams = params; } |
三、那桌面控件有了,下面当然就是使用WindowManager添加到桌面上了:
/** * 创建一个小悬浮窗。初始位置为屏幕的右部中间位置。 * * @param context 必须为应用程序的Context. */ publicvoidcreateSmallWindow(Context context) { mContext = context; WindowManager windowManager = getWindowManager(context); intscreenWidth = windowManager.getDefaultDisplay().getWidth(); intscreenHeight = windowManager.getDefaultDisplay().getHeight(); if(smallWindow ==null) { smallWindow =newPhotoWindowSmallView(context); if(smallWindowParams ==null) { smallWindowParams =newLayoutParams(); 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. */ publicvoidremoveSmallWindow(Context context) { if(smallWindow !=null) { WindowManager windowManager = getWindowManager(context); windowManager.removeView(smallWindow); smallWindow =null; } } |
四、这个时候我们需要的SurfaceView就有了,那么,怎么在后台进行操作呢?自然而然就想到了Service了
在Service中执行桌面控件的操作:
@Override publicintonStartCommand(Intent intent,intflags,intstartId) { myWindowManager =newMyPhotoWindowManager(); createWindow(); returnsuper.onStartCommand(intent, flags, startId); }
@Override publicvoidonDestroy() { super.onDestroy();
}
privatevoidcreateWindow() { // 当前界面是桌面,且没有悬浮窗显示,则创建悬浮窗。 myWindowManager.removeSmallWindow(getApplicationContext()); myWindowManager.createSmallWindow(getApplicationContext());
} |
五、在activity中对Service绑定,进行拍照的操作
privateclassMyServiceConnimplementsServiceConnection {
@Override publicvoidonServiceConnected(ComponentName name, IBinder service) { // TODO Auto-generated method stub binder = (PhotoWindowService.myServiceBinder) service; if(isVedio) { binder.startCarema(); }else{ binder.stopCarema(); } }
@Override publicvoidonServiceDisconnected(ComponentName name) { // TODO Auto-generated method stub }
} |
六、在Service中控制myWindowManager中的拍照的开始和结束
publicclassmyServiceBinderextendsBinder { publicvoidstartCarema() { myWindowManager.startCarema(); }
publicvoidstopCarema() { myWindowManager.stopCarema(); } } |
七、在MyPhotoWindowManager开启或终止拍照操作
publicvoidstartCarema() { itt = InitTimetoTakePic.getInstance(mContext); itt.initView(mSurfaceview); itt.start(); }
publicvoidstopCarema() { if(itt !=null) itt.releaseCarema(); } |
八、在InitTimetoTakePic进行拍照的相关处理
packagecom.ddv.www.candidphotodemo;
importandroid.annotation.TargetApi; importandroid.app.Activity; importandroid.content.Context; importandroid.content.Intent; importandroid.content.pm.PackageManager; importandroid.hardware.Camera; importandroid.hardware.Camera.AutoFocusCallback; importandroid.hardware.Camera.PictureCallback; importandroid.os.Build; importandroid.os.Handler; importandroid.os.Message; importandroid.widget.FrameLayout;
importjava.io.File; importjava.io.FileOutputStream;
/** * 设置定时拍照功能 * * @author <p> * 创建定时拍照任务 * cameraType 摄像头 * resolutionString 分辨率 * tvSaveLocation 保存地址 * etExtension 拓展名 * cameraStart, 开始拍摄时间 * cameraNumber, 拍摄次数 * cameraStop 拍摄张数 */ publicclassInitTimetoTakePic {
privatestaticInitTimetoTakePic mInstance; privatestaticintcameraType =1; Context mContext; staticFrameLayout mSurfaceViewFrame; privatestaticCamera mCamera; privatestaticCameraPreview mPreview; privatestaticString resolutionString ="1920x1080"; privatestaticString saveLocation = AppUtils.getSDCardPath(); privatestaticString extension ="JPG"; privatestaticString cameraStart ="1"; privatestaticString cameraNumber ="1"; privatestaticString cameraStop ="10"; privatestaticintnumber =0; privatestaticbooleanclearVoice =false; privateIntent intent;
privateInitTimetoTakePic(Context context) { this.mContext = context; }
publicsynchronizedstaticInitTimetoTakePic getInstance(Context context) { mInstance =null; mInstance =newInitTimetoTakePic(context);
returnmInstance; }
publicvoidinitView(FrameLayout surfaceViewFrame) { mSurfaceViewFrame = surfaceViewFrame; }
/** * 启动定时拍照并上传功能 */ Handler mHandler =newHandler() { @Override publicvoidhandleMessage(Message msg) { switch(msg.what) { case1: LogUtils.v("开始拍照"); initCarema(); break; case2: if(mCamera ==null) { releaseCarema(); number =0; mHandler.removeCallbacksAndMessages(null); }else{ if(number < Integer.valueOf(cameraStop)) { mCamera.autoFocus(newAutoFocusCallback() { @Override publicvoidonAutoFocus(booleansuccess, 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; } } };
publicvoidstart() { mHandler.sendEmptyMessageDelayed(1,1*1000);//7s 后开始启动相机 }
privatevoidinitCarema() { LogUtils.v("initCarema"); if(mCamera ==null) { LogUtils.v("camera=null"); mCamera = getCameraInstance(); mPreview =newCameraPreview(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硬件 */ privatebooleancheckCameraHardware(Context context) { if(context.getPackageManager().hasSystemFeature( PackageManager.FEATURE_CAMERA)) { // 存在 returntrue; }else{ // 不存在 returnfalse; } }
/** * 打开一个Camera */ @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) publicstaticCamera 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失败失败"); } returnc; }
privatePictureCallback mPicture =newPictureCallback() {
@Override publicvoidonPictureTaken(byte[] data, Camera camera) { // 获取Jpeg图片,并保存在sd卡上 String path = saveLocation; File dirF =newFile(path); if(!dirF.exists()) { dirF.mkdirs(); } File pictureFile =newFile(path +"/"+ System.currentTimeMillis() +"."+ extension);//扩展名 try{ FileOutputStream fos =newFileOutputStream(pictureFile); fos.write(data); fos.close();
LogUtils.v("保存图成功"); number++; intent =newIntent(); intent.setAction("CameraFragment.start"); intent.putExtra("number", number); mContext.sendBroadcast(intent); }catch(Exception e) { LogUtils.v("保存图片失败"); e.printStackTrace(); } releaseCarema(); } };
publicvoidreleaseCarema() { if(mCamera !=null) { mCamera.stopPreview(); mCamera.release(); mCamera =null; } } } |
原文链接:http://blog.csdn.net/huangxiaoguo1/article/details/53666047