美文网首页
项目需求-隐蔽拍照

项目需求-隐蔽拍照

作者: EraJieZhang | 来源:发表于2018-12-12 13:44 被阅读0次

需求:

隐蔽拍照,没有预览界面打开这个activity直接调用前置摄像头“咔嚓”给你来张照片不能有声音、闪光灯,总之就是在用户不知情的情况下给你来张美美的自拍。

实现(小米5手机测试)

由于是后加的需求,我就在代码里创建surfaceView了
在onCreate的时候添加代码:

getWindow().setFormat(PixelFormat.TRANSLUCENT);  

第一次创建surfaceView 的时候会黑屏一下 或者闪屏,将这个activity设置背景透明,或者在布局里创建这个surfaceView,或者在布局里创建一个宽高0dp的surfaceView(后面两种种方式没有实验过)
如果是fragment设置背景透明好像是不好用,可以用后两种方式(没测过)

    /**
     * 创建surfaceView
     * 隐藏拍照需要有个容器来预览。
     */
    private void createsurfaceView() {
        /*获取手机分辨率*/
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        int width = dm.widthPixels;
        int height = dm.heightPixels;
        BaseLog.w("当前手机的分辨率宽" + width + "高度" + height);

        surfaceView = new SurfaceView(mActivity);
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        /*设置Surface分辨率为手机的分辨率*/
        surfaceView.getHolder().setFixedSize(width, height);
        /*自定义设置Surface分辨率*/
        /*surfaceView.getHolder().setFixedSize(6921,4052);*/
        surfaceView.getHolder().setSizeFromLayout();
        /*屏幕常亮*/
        surfaceView.getHolder().setKeepScreenOn(true);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {

                try {
                    /*创建camera对象 open(1)标识开启前置摄像头  为空开启的是后置摄像头*/
                    camera = Camera.open(1);
                    /*设置用于显示拍照影像的SurfaceHolder对象*/
                    camera.setPreviewDisplay(holder);


                    cameraRotation = setCameraDisplayOrientation(mActivity, 1, camera);
                    camera.setDisplayOrientation(cameraRotation);
                    BaseLog.w("camera旋转的角度是:cameraRotation=" + cameraRotation);

                    try {
                        Camera.Parameters parameters = camera.getParameters();
                        /*
                         * mActivity.getResources().getConfiguration().orientation = 1 竖屏
                         * mActivity.getResources().getConfiguration().orientation = 2 横屏
                         * 个人理解:
                         *   portrait 人像拍摄模式:
                         *       1.手机竖屏拍摄,图片竖直保存
                         *       2.手机横屏拍摄,图片竖直保存
                         *   landscape   风景模式
                         *       1.手机竖屏拍摄,图片横向保存
                         *       2.手机横屏拍摄,图片横向保存
                         *    (个人并未具体实验)
                         * */
                        BaseLog.w("orientation=" + mActivity.getResources().getConfiguration().orientation);
                        BaseLog.w("ORIENTATION_LANDSCAPE=" + Configuration.ORIENTATION_LANDSCAPE);


                        if (mActivity.getResources().getConfiguration().orientation != Configuration.ORIENTATION_LANDSCAPE) {
                            /*这是一个众所周知但未文档化的特性*/
                            parameters.set("orientation", "portrait");
                        } else {
                            /*这是一个众所周知但未文档化的特性*/
                            parameters.set("orientation", "landscape");
                        }
                        camera.setParameters(parameters);
                        camera.setPreviewDisplay(holder);
                    } catch (IOException exception) {
                        camera.release();
                        /*打印异常*/
                        BaseLog.w("IOException = " + exception.getMessage());
                    }

                    /*开始预览*/
                    camera.startPreview();
                    /*自动对焦*/
                    camera.autoFocus(new Camera.AutoFocusCallback() {
                        @Override
                        public void onAutoFocus(boolean success, Camera camera) {

                            if (success) {
                                /*只有加上了这一句,才会自动对焦。*/
                                camera.cancelAutoFocus();
                            }
                        }
                    });
                    /*调用拍照事件*/
                    takepicture();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {

            }
        });
        /*设置这个surfaceView 宽高为1像素,用户基本不可见*/
        FrameLayout.LayoutParams lp = new FrameLayout.LayoutParams(1, 1);
        surfaceView.setLayoutParams(lp);
        /*我是动态创建的,放到指定的view里*/
        mRootContentFuncamera.addView(surfaceView);
    }

 /**
     *获取旋转surfaceView预览的角度(这个方法在api里有,我做了些小改动 API:android.hardware.Camera 1525行-1583行)
     *
     * @param activity
     * @param cameraId
     * @param camera
     */
    public int setCameraDisplayOrientation(Activity activity, int cameraId, android.hardware.Camera camera) {

        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();

        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }

        int result;
        BaseLog.w("info.orientation = " + info.orientation);
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;  // compensate the mirror
        } else {  // back-facing
            result = (info.orientation - degrees + 360) % 360;
        }

        bitmapRotation = info.orientation;

        return result;
    }

    /**
     * 隐藏拍照事件
     */
    private void takepicture() {

        if (camera == null) {
            BaseLog.w("camera == null");
            return;
        }
        /*
         *第一个参数必须是null, 如果你new出来了,就算里面满什么都没写也会有快门声“咔嚓”,估计修改快门音乐也是在这里
         */
        camera.takePicture(null, null, new Camera.PictureCallback() {
            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                /*获取得到的bitmap对象*/
                BaseLog.w("mBitmap旋转的角度是:bitmapRotation=" + bitmapRotation);
                mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                mImgShowFuncamera.setImageBitmap(rotateBitmap(mBitmap, bitmapRotation));
            }
        });
    }

    /**
     * 旋转图片
     *
     * @param bitmap
     * @param degress
     * @return
     */
    public static Bitmap rotateBitmap(Bitmap bitmap, int degress) {

        if (bitmap != null) {
            Matrix m = new Matrix();
            m.postRotate(degress);
            bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), m, true);
            return bitmap;
        }
        return bitmap;
    }

问题

按照上面的方法细心的朋友会发现有些问题

  • 有些朋友拍照之后,设置到img上的图方向不对
  • 你横着拿手机拍的照,方向怎么都不对
    关于这方面我也找了一些资料,也在网上尝试了一些方法,但是一直没找到合适的解决方案,如果谁有解决方法也可以下面贴出来,大家一起学习!

相关文章

网友评论

      本文标题:项目需求-隐蔽拍照

      本文链接:https://www.haomeiwen.com/subject/cboshqtx.html