当前位置: 移动技术网 > IT编程>移动开发>Android > Android 偷拍功能实现(手机关闭依然拍照)详解及实例代码

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

2019年07月24日  | 移动技术网IT编程  | 我要评论

减肥瑜伽图片,异界变身之不老传说,保卫花园2无敌版

 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下载地址:

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网