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

前一篇文章我写了android偷录的功能,那么你会发现效果图上还有个偷拍功能

效果如下:

其实偷拍与偷录实现方式是一样的,都是使用到的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中控制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() {
        @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;
        }
    }
}

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

有什么不足,望大家指教,谢谢….

时间: 2024-10-10 15:20:24

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

支持HCE功能的NFC手机(Android)、 支持NFC功能的手机大全(安卓、微软、塞班、苹果)

支持HCE功能的Android手机需要满足如下条件: 1.支持NFC功能 2.操作系统是Android 3.Android版本4.4 如果满足条件1.2,但是通过刷机满足条件3也成立. 说明:对于NFC发烧友,如果囊中羞涩,不妨购买二手手机(刷机满足要求的二手手机更实惠)发烧.淘宝上价廉物美的很多! HCE(Host-based Card Emulation)是一个模拟智能卡的软件,在Android中就是一个apk.HCE的特点是模拟智能IC卡(ISO 7816-4),可用于金融和行业应用,HC

开源一款android 偷拍 app【静拍】豌豆荚、flyme商店已经上线

首先先花3秒时间,预览下下app的大概是做啥的,解决啥痛点的:) 需求点: 1:音量键可以拍照 2:没有快门声.闪光灯 3:锁屏下.或者是在其他程序界面都可以拍照 思路: 1:创建一个内容观察者(ContentObserver)来监听音量变化 2:使用原生camera实现拍照 3:同1 技术总结: 1:android的音量内容分很多种类,有系统的.铃声的.音乐的(AudioManager.STREAM_MUSIC),我们只监听音乐的就好了 那么问题来了,如何确保任何情况下,音量键操作的对象,都是

Android 微信小视频录制功能实现

目录 开发之前 开发环境 相关知识点 开始开发 案例预览 案例分析 搭建布局 视频预览的实现 自定义双向缩减的进度条 录制事件的处理 长按录制 抬起保存 上滑取消 双击放大(变焦) 实现视频的录制 实现视频的停止 完整代码 总结 开发之前 这几天接触了一下和视频相关的控件, 所以, 继之前的微信摇一摇, 我想到了来实现一下微信小视频录制的功能, 它的功能点比较多, 我每天都抽出点时间来写写, 说实话, 有些东西还是比较费劲, 希望大家认真看看, 说得不对的地方还请大家在评论中指正. 废话不多说,

拍照都出色 主打拍照功能旗舰手机

现在手机的拍照技术已经非常的出色,尤其是移动互联网的蓬勃发展以及4G网络的普及,让用户从之前的简单拍照,到现在的即时分享,那么手机的优势就显现出来.而现在更多朋友喜欢分享自己的美照.自拍照,那么大家在选购手机的时候拍照也成为了大家在选择手机时候的重要标准,下面就为大家介绍几款前后拍照效果都非常强劲的智能4G手机. 前后拍照都出色 主打拍照功能旗舰手机 manta 7X manta 7X是今年年初全新上市的一款创新型智能手机,该机采用智慧边框设计,当我们持握手机时,智慧边框就会自动判断两边的手指数

Android开发之自动登录功能的实现

在我们平时使用的手机应用都可以实现只需要登陆一次账号后,第二次进入应用直接跳转到效果界面的效果,还有QQ的登陆框是如何记忆我们的隐身登陆,保存账号选项的呢,这些都是通过使用SharedPreferences共享参数效果实现的,而无须使用数据库来存储.以下我们直接看详细代码分析. package com.example.account.login; import java.util.HashMap; import java.util.Map; import com.android.dao.MySQ

偷拍成隐私泄露重要途径!我们该如何保护自己

在互联网时代,个人隐私似乎变成砧板上的鱼肉,被众多别有用心的人任意"切割.使用".在网站的注册信息.快递单上的地址.电脑/手机中储存的文件--这些隐私信息的泄露,给大众造成极大的困扰.但其实除了这些之外,偷拍也逐渐成为隐私泄露的重要途径. 媒体头条上总是会曝出在公交车.酒店.卫生间.出租屋.浴室等地点发生的偷拍事件,随后而来的自然是人们的喊打之声.但在事件平息之后,却又是新的偷拍事件来袭.屡禁不止的偷拍,到底会对人们造成怎样的影响,我们又该如何保护自己? 偷拍泛滥,人人自危 如今互联网

Android ShareSDK快速实现分享功能

第一步 :获取ShareSDK 为了集成ShareSDK,您首先需要到ShareSDK官方网站注册并且创建应用,获得ShareSDK的Appkey,然后到SDK的下载页面下载SDK的压缩包,解压以后可以得到如下图的目录结构: ShareSDK在“ShareSDK for Android”目录下,此目录中的“Libs”包含“MainLibs”和“OnekeyShare” 分别是ShareSDK的核心库和“快捷分享”的源码库,说明文档也在“ShareSDK for Android”目录下,集成Sha

检查android设备是否支持某些功能

我们在开发APP的时候,应用程序可能需要设备支持某些功能才能保证应用程序的运行.例如需要支持电话,NFC.陀螺仪等等. 我们可以使用PackageManager对象的hasSystemFeature方法来检查当前设备是否支持某些功能. 第一种方法: 使用代码检查设备是否支持某些功能.这种方法比较好.因为不论app来自哪里.都能准确的判断设备是否支持应用所需的功能. 代码: PackageManager pm = getPackageManager(); // 获取是否支持电话 boolean t

6月第3周业务风控关注 | 偷拍产业链曝光:你的私生活,可能正被几万人围观

易盾业务风控周报每周报道值得关注的安全技术和事件,包括但不限于内容安全.移动安全.业务安全和网络安全,帮助企业提高警惕,规避这些似大实小.影响业务健康发展的安全风险. 1.传暗网出售180万苏宁会员数据 6月18日晚7点,南方都市报报道,有网友在暗网发帖出售苏宁会员数据,数据涉及180万苏宁用户,售价100美元,包含手机号.密码.姓名.×××号等信息.针对以上事件,苏宁表示,经对网曝示例数据进行核查,并非苏宁用户数据.其还表示,不管是买卖个人信息还是编造谣言损害苏宁声誉均已触犯法律乃至构成犯罪.