无需预览即可在服务中捕获图像

时间:2018-08-16 11:10:11

标签: android camera

问题陈述:

当有人尝试使用错误的pattern / PIN打开设备时,我的应用程序应触发alarm,向注册的手机号码发送警报SMS。并且它应该捕获试图解锁设备的人的图像,并将该图像发送到注册的电子邮件ID。

我所取得的成就:

  • 我在Pattern / PIN中收到错误的DeviceAdmin class通知。
  • 我启动service进行后台任务。此service成功播放了alarm
  • 我向注册的mobile number发送了一条警报SMS。 我已成功向注册的Email发送了警报email ID。 (但没有图像。)

对于设备锁定时如何在后台IntentService中捕获图像感到困惑,而在没有预览的情况下也是如此。

我显然不能使用Camera intent。因为无法从startActivityForResult调用Service。另外,我不希望用户打开Camera app后捕获图像。

我的研究已经把我引到了这些职位上。

Can I use Android Camera in service without preview?

How to Capture Image When Device is Locked

问题是:Camera API is deprecatedCamera2 API要求Minimum sdk version 21,但是我的客户要求是minSdkVersion 15,我不能更改。我不知道现在该怎么办。有任何参考或帮助吗?

1 个答案:

答案 0 :(得分:0)

我在this blog的帮助下解决了我的问题

因此,我使用以下代码在后台服务中捕获图像:

@Override
public void onStart(Intent intent, int startId) {
    mCamera = getAvailableFrontCamera();     // globally declared instance of camera
    if (mCamera == null){
        mCamera = Camera.open();    //Take rear facing camera only if no front camera available
    }
    SurfaceView sv = new SurfaceView(getApplicationContext());
    SurfaceTexture surfaceTexture = new SurfaceTexture(10);

    try {
        mCamera.setPreviewTexture(surfaceTexture);
        //mCamera.setPreviewDisplay(sv.getHolder());
        parameters = mCamera.getParameters();

        //set camera parameters
        mCamera.setParameters(parameters);


        //This boolean is used as app crashes while writing images to file if simultaneous calls are made to takePicture
        if(safeToCapture) {
            mCamera.startPreview();
            mCamera.takePicture(null, null, mCall);
        }
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }


    //Get a surface
    sHolder = sv.getHolder();
    //tells Android that this surface will have its data constantly replaced
    sHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}

Camera.PictureCallback mCall = new Camera.PictureCallback()
{

    public void onPictureTaken(byte[] data, Camera camera)
    {
        safeToCapture = false;
        //decode the data obtained by the camera into a Bitmap

        FileOutputStream outStream = null;
        try{

            // create a File object for the parent directory
            File myDirectory = new File(Environment.getExternalStorageDirectory()+"/Test");
            // have the object build the directory structure, if needed.
            myDirectory.mkdirs();

            //SDF for getting current time for unique image name
            SimpleDateFormat curTimeFormat = new SimpleDateFormat("ddMMyyyyhhmmss");
            String curTime = curTimeFormat.format(new java.util.Date());

            // create a File object for the output file
            outStream = new FileOutputStream(myDirectory+"/user"+curTime+".jpg");
            outStream.write(data);
            outStream.close();
            mCamera.release();
            mCamera = null;

            String strImagePath = Environment.getExternalStorageDirectory()+"/"+myDirectory.getName()+"/user"+curTime+".jpg";
            sendEmailWithImage(strImagePath);
            Log.d("CAMERA", "picture clicked - "+strImagePath);
        } catch (FileNotFoundException e){
            Log.d("CAMERA", e.getMessage());
        } catch (IOException e){
            Log.d("CAMERA", e.getMessage());
        }

        safeToCapture = true;    //Set a boolean to true again after saving file.

    }
};

private Camera getAvailableFrontCamera (){

    int cameraCount = 0;
    Camera cam = null;
    Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
    cameraCount = Camera.getNumberOfCameras();
    for (int camIdx = 0; camIdx < cameraCount; camIdx++) {
        Camera.getCameraInfo(camIdx, cameraInfo);
        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            try {
                cam = Camera.open(camIdx);
            } catch (RuntimeException e) {
                Log.e("CAMERA", "Camera failed to open: " + e.getLocalizedMessage());
            }
        }
    }

    return cam;
}


//Send Email using javamail API as user will not be allowed to choose available
// application using a Chooser dialog for intent.
public void sendEmailWithImage(String imageFile){
    .
    .
    .
}

清单文件中需要以下使用功能和权限:

<uses-feature
    android:name="android.hardware.camera"
    android:required="false" />
<uses-feature
    android:name="android.hardware.camera.front"
    android:required="false" />

<uses-permission android:name="android.permission.SEND_MAIL" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

我已将属性required设置为false,这样即使没有可用的Camera,用户也可以安装我的应用程序。也许这可以在将来对某人有所帮助。