Android 如何实现偷拍功能(手机关闭依然拍照)的教程

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

时间: 2024-10-23 16:03:34

Android 如何实现偷拍功能(手机关闭依然拍照)的教程的相关文章

Android 偷拍功能实现(手机关闭依然拍照)详解及实例代码_Android

 Android 偷拍功能/手机关闭能拍照 效果如下: 其实偷拍与偷录实现方式是一样的,都是使用到的WindowManager来绘制桌面小控件的原理.那我就不多说了- 一.首先我们需要一个SurfaceView: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android&quo

13部门联手整治网络秩序 网上偷拍栏目全部关闭

中介交易 SEO诊断淘宝客 站长团购 云主机 技术大厅 本报讯 (记者刘甲)记者近日从公安部获悉,公安部等13部门从上月起在全国展开整治网络秩序联合行动,互联网上设置的偷拍.露点.走光.成人文学等栏目将全部清除关闭. 网上招嫖成重点打击对象 此次联合行动,各部门将重点打击四类对象:一是利用互联网和手机大量传播淫秽信息非法牟利;二是在境外开办淫秽网站向境内传播淫秽信息.发展会员;三是组织网上淫秽表演和进行网上招嫖;四是从事网络诈骗.盗窃.赌博和销售违禁品等犯罪活动. 涉"黄"博客将被关闭

22_Android中的本地音乐播放器和网络音乐播放器的编写,本地视频播放器和网络视频播放器,照相机案例,偷拍案例实现

1 编写以下案例: 当点击了"播放"之后,在手机上的/mnt/sdcard2/natural.mp3就会播放. 2 编写布局文件activity_main.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     xmlns:tools="http://schemas.android.com/tools"     android:layo

国家重击网络色情 偷拍视频图片全清除

中介交易 SEO诊断淘宝客 站长团购 云主机 技术大厅 多部门联合打击网络色情信息搜索引擎服务商限期过滤色情内容-- 本报讯传播色情淫秽节目的"黑网站"被发现后将列入"黑名单",电信部门对其进行关闭,各基础运营企业和互联网接入单位不得再为其提供接入.记者昨天从公安部获悉,1月至9月,打击整治网络淫秽色情等有害信息专项行动在全国开展,要在各网站推广论坛版主.吧主和聊天室主持人实名制,搜索引擎服务商也将被限期封堵过滤色情内容. -一年关闭清理4.4万个网站 截至目前,我

iOS 10.2.1 有偷拍漏洞!情人节防偷拍指南 | 宅客爱测试

 话说,在情人节,两个现象值得注意:玫瑰花特别贵,酒店预订爆满. 这意味着,这可能是全世界兴奋指数最高的一天. 但是,这天,雷锋网(公众号:雷锋网)宅客频道编辑发现了一个了不得的事情: 你知道吗?iOS 10.2.1有一个偷拍漏洞!可以偷偷拍照和拍视频! 纳尼?是不是令人难以相信?这--无视频无真相,雷锋网编辑只好奉上测试视频告诉你: 这是真的! 情人节防偷拍,你值得拥有!         本文作者:李勤 本文转自雷锋网禁止二次转载,原文链接

男友手机遭窃女生求卫星定位找寻内存偷拍艳照

被男友偷偷拍了艳照,手机遭窃担心成"艳照门" 女生哭求卫星定位找手机 裴睿 本报讯 昨天上午,浙江的一名艺校女学生在南京中央门长途汽车站附近报警称男友的手机被偷了,民警赶到现场后,女学生哭着央求民警能否通过卫星定位,帮助找回手机,因为手机里有男友偷拍她的艳照,她怕被坏人偷走后放到网上名誉受损. 目前,警方正在调查此事. 据了解,昨天上午10点钟左右,在中央门长途汽车站附近,一对年轻的情侣发生了争吵,女孩子还央求市民帮助她报警.中央门立交桥派出所民警在接到报警赶到现场之后,才了解到两人刚

功能手机渐离舞台:谷歌悄然关闭短信搜索服务

5月13日消息,据国外http://www.aliyun.com/zixun/aggregation/31646.html">媒体报道,谷歌日前关闭了主要面向功能手机用户推出的"短信搜索服务"(Short Messaging Service Search). 据悉,当用户以短信形式向一个谷歌指定的固定号码发送搜索关键词时,"短信搜索服务"就会以短信形式向用户发送搜索结果,搜索结果不包含网页链接,而是完全的文本信息. Techcrunch称,谷歌在关闭

偷拍窃听设备放弃实体店

<禁止生产销售使用窃听窃照专用器材和"伪基站"设备的规定>拟规定从5月1日起,对经公安机关认定的生产.销售窃听窃照专用器材设备行为,责令其停止生产.销售,并处以3万元以下罚款:对不构成犯罪的相关行为,责令其停止使用,处以3万元以下罚款. 近日,记者调查发现,此前沪上销售偷拍器材的"大本营"--虬江路电子市场内,因风声紧已遍寻不着此类设备的踪迹.不过在网络上,窃照专用器材却"暗流涌动",不少卖家通过改头换面.打擦边球的方式仍在网上大肆销

android系统在静音模式下关闭camera拍照声音的方法

话说为了防止偷拍,业内有不成文规定,手机公司在做camera时,点击拍照和录像键的时候,必须要有提示音.因此,google也就非常人性化的将播放 拍照声音的函数,放到了cameraService中,防止开发者能开发出不响的camera,从而只要调用拍照函数,一定会响,这是写死在 framework中的. 话说这个规定在当今有点不合时宜,这不,今天我收到测试提的一个BUG,说是公司的新需求,要求在静音模式下拍照声音也得取消.这么无耻的需求,也许就在我们中国最大的山寨手机公司才会提到.废话不多说,看