Android 偷拍功能實現(手機關閉依然拍照)詳解及執行個體代碼_Android

來源:互聯網
上載者:User

 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://www.jb51.net/softs/519032.html

感謝閱讀,希望能協助到大家,謝謝大家對本站的支援!

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.