Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I use Android Camera in service without preview?

I have create a application in Android that using a camera I can measure out the distance between user's face to the phone screen.

Problem description:

Now I want to make it running background so that the feature is available while I am using other applications. It means I should open camera in service without preview, and process it in service.

What I did yet:

I referred some questions here

How to record video from background of application : Android

How to use Android Camera in Background?

Taking picture from camera without preview

API level 16

My Service File

import android.app.Service;
import android.content.Intent;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.media.MediaRecorder;
import android.os.IBinder;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;

public class RecorderService extends Service {
private static final String TAG = "RecorderService";
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private static Camera mServiceCamera;
private boolean mRecordingStatus;
private MediaRecorder mMediaRecorder;
File path = android.os.Environment.getExternalStorageDirectory();


@Override
public void onCreate() {
    Log.i(TAG,"onCreate");
    mRecordingStatus = false;
    //mServiceCamera = CameraRecorder.mCamera;
    mServiceCamera = Camera.open(1);
    mSurfaceView = MainActivity.mSurfaceView;
    mSurfaceHolder = MainActivity.mSurfaceHolder;

    super.onCreate();
    if (mRecordingStatus == false)
        startRecording();
}

@Override
public IBinder onBind(Intent intent) {
    // TODO Auto-generated method stub
    return null;
}

@Override
public void onDestroy() {
    Log.i(TAG,"onDestroy");

    stopRecording();
    mRecordingStatus = false;

    super.onDestroy();
}

public boolean startRecording(){
    Log.i(TAG,"startRecording");

    try {
        Toast.makeText(getBaseContext(), "Recording Started", Toast.LENGTH_SHORT).show();

        //mServiceCamera = Camera.open();
        Camera.Parameters params = mServiceCamera.getParameters();
        mServiceCamera.setParameters(params);
        Camera.Parameters p = mServiceCamera.getParameters();

        final List<Size> listSize = p.getSupportedPreviewSizes();
        Size mPreviewSize = listSize.get(2);
        Log.v(TAG, "use: width = " + mPreviewSize.width
                + " height = " + mPreviewSize.height);
        p.setPreviewSize(mPreviewSize.width, mPreviewSize.height);
        p.setPreviewFormat(PixelFormat.YCbCr_420_SP);
        mServiceCamera.setParameters(p);

        try {
            mServiceCamera.setPreviewDisplay(mSurfaceHolder);
            mServiceCamera.startPreview();
        }
        catch (IOException e) {
            Log.e(TAG, e.getMessage());
            e.printStackTrace();
        }

        mServiceCamera.unlock();

        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setCamera(mServiceCamera);
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT);
        mMediaRecorder.setOutputFile(path+"/outputVideo.mp4");
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setVideoSize(mPreviewSize.width, mPreviewSize.height);
        mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

        mMediaRecorder.prepare();
        mMediaRecorder.start();

        mRecordingStatus = true;

        return true;
    } catch (IllegalStateException e) {
        Log.d(TAG, e.getMessage());
        e.printStackTrace();
        return false;
    } catch (IOException e) {
        Log.d(TAG, e.getMessage());
        e.printStackTrace();
        return false;
    }
}

public void stopRecording() {
    Log.i(TAG,"stopRecording");

    Toast.makeText(getBaseContext(), "Recording Stopped", Toast.LENGTH_SHORT).show();
    try {
        mServiceCamera.reconnect();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    try{
        mMediaRecorder.stop();
    }catch (Exception ignored)
    {

    }
    mMediaRecorder.reset();
    mMediaRecorder.release();
    mServiceCamera.stopPreview();
    mServiceCamera.release();
    mServiceCamera = null;
}
}
like image 618
Peter Zhu Avatar asked Mar 16 '15 15:03

Peter Zhu


People also ask

What is the permission for using the Camera in Android?

On your phone, open the Settings app. Tap Privacy. Turn off Camera access or Microphone access.

How do I access Camera on Android application?

You should go onto your apps screen on your android device, where it will display all apps that have been downloaded onto your phone. Also, the camera app comes built into the device, so that means it cannot be accidentally deleted or uninstalled. The camera app will likely be on your apps screen.


1 Answers

You can refer this Question, which discuss how to do video record in the service. The steps to capture image is same as it.

To achieve your requirement, you may need:

  1. Get camera instance in your service. Check this Official Guideline.
  2. Setup your camera parameters. Use the APIs like Camera.getParameters(), Camera.setParameters(), Camera.Parameters.setPictureSize(int with, int height) and Camera.Parameters.setPictureFormat(int format) to do so.
  3. Prepare a file used to store the image. You need to implement Camera.PictureCallback to do so.
  4. Call Camera.startPreview() before you takeing picutre. If you don't call this function before taking picture, you will get exception. (Note: You don't need to do Camera.setPreviewdisplay(SurfaceHolder display) first.)
  5. Call camera.takePicture() in your service. Then you can get the captured image stored on the file you specified.

After it work, don forget to maintain the resource durning lifecycle to acquire/release camera correctly.

Here is my sample code on Github, it is also mentioned in the comment.

like image 133
chartsai Avatar answered Oct 09 '22 02:10

chartsai