首页 > 系统 > Android > 正文

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

2019-12-12 04:19:47
字体:
来源:转载
供稿:网友

 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下载地址://www.VeVB.COm/softs/519032.html

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

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表