android不知不觉偷拍他人功能实现(手机关闭依然拍照)

来源:互联网 发布:室内设计网站知乎 编辑:程序博客网 时间:2024/04/25 19:05

效果如下: 
这里写图片描述

其实偷拍与偷录实现方式是一样的,都是使用到的WindowManager来绘制桌面小控件的原理。那我就不多说了…

一、首先我们需要一个SurfaceView:

<?xml version="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>

二、然后进行的操作就是生产这个小控件了:

    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中执行桌面控件的操作:

 @Override    public int onStartCommand(Intent intent, int flags, int startId) {        myWindowManager = new MyPhotoWindowManager();        createWindow();        return super.onStartCommand(intent, flags, startId);    }    @Override    public void onDestroy() {        super.onDestroy();    }    private void createWindow() {        // 当前界面是桌面,且没有悬浮窗显示,则创建悬浮窗。        myWindowManager.removeSmallWindow(getApplicationContext());        myWindowManager.createSmallWindow(getApplicationContext());    }

五、在activity中对Service绑定,进行拍照的操作

 private class MyServiceConn implements ServiceConnection {        @Override        public void onServiceConnected(ComponentName name, IBinder service) {            // TODO Auto-generated method stub            binder = (PhotoWindowService.myServiceBinder) service;            if (isVedio) {                binder.startCarema();            } else {                binder.stopCarema();            }        }        @Override        public void onServiceDisconnected(ComponentName name) {            // TODO Auto-generated method stub        }    }

六、在Service中控制MyPhotoWindowManager中的拍照的开始和结束

   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() {        @Override        public 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() {                                @Override                                public 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() {        @Override        public 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;        }    }}

记得配置权限等

<manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.ddv.www.candidphotodemo">    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />    <uses-permission android:name="android.permission.GET_TASKS" />    <uses-feature android:name="android.hardware.camera" />    <uses-feature android:name="android.hardware.camera.autofocus" />    <uses-permission android:name="android.permission.CAMERA"></uses-permission>    <uses-permission android:name="android.permission.RECORD_AUDIO"></uses-permission>    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:supportsRtl="true"        android:theme="@style/AppTheme">        <activity android:name=".MainActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <service android:name=".PhotoWindowService" />    </application>

</manifest>

demo下载地址:http://download.csdn.net/download/huangxiaoguo1/9711899

0 0
原创粉丝点击