Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android Camera won't take picture when screen off

I have a simple app that has an activity being called periodically by an alarm manager to display a preview frame and take a picture when the preview frame is built.After taking the picture, it is saved using a AsyncTask and the activity destroyed using finish(). The code works perfectly fine when I have the screen turned on.However it fails to take a picture with the screen off.I want to monitor a house and take pictures periodically using the app and in that case keeping the screen always on or turning it on manually is not a viable option.

Also the code for the camera activity has been copied from Commonsware library and works perfectly great.I am only having a problem with taking a picture with screen off.I can also see from the logs that the camera is opened by the activity.However the Runnable that is supposed to take picture when the preview frame is built, doesn't run and the camera goes to the pause state instead and stays there.

I have the necessary permissions set up perfectly as I am able to get the images with screen turned on.Maybe I am having trouble understanding the activity lifecylce when the screen is off and someone can shed light there.

I tried using the wakelocks to turn the screen on but that didnt do any good.

Below is the code for the Activity.

Also I am sorry but removing the comment for the license to make it short here.

    package com.thopedia.snapper; /***
 Copyright (c) 2008-2012 CommonsWare, LLC
*/
import all;

public class CameraActivity1 extends Activity {
    private PreviewFrameLayout frame=null;
    private SurfaceView preview=null;
    private SurfaceHolder previewHolder=null;
    private Camera camera=null;
    private boolean inPreview=false;
    private boolean cameraConfigured=false;
    private  PowerManager.WakeLock wakeLock;
    private PowerManager powerManager;

    @SuppressWarnings("deprecation")
    @Override
    public void onCreate(Bundle savedInstanceState) {
       /* powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, getClass()
                .getName());*/
        Log.v(GlobalVariables.TAG,"CameraActivity On create called");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        frame=(PreviewFrameLayout)findViewById(R.id.frame);
        preview=(SurfaceView)findViewById(R.id.preview);
        previewHolder=preview.getHolder();
        previewHolder.addCallback(surfaceCallback);
        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
     }

    @TargetApi(Build.VERSION_CODES.GINGERBREAD)
    @Override
    public void onResume() {
       // wakeLock.acquire();
        Log.v(GlobalVariables.TAG,"camera activity onResume called");
       super.onResume();
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {
            Camera.CameraInfo info=new Camera.CameraInfo();

            for (int i=0; i < Camera.getNumberOfCameras(); i++) {
                Camera.getCameraInfo(i, info);

                if (info.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {
                    try{
                        camera=Camera.open(i);
                    }catch (Exception e){
                        Log.v(GlobalVariables.TAG,"Camera Opening Exception");
                        if(!isFinishing()) {
                            finish();
                        }}}}}
        if (camera == null) {
            try{
                camera=Camera.open();
            }catch (Exception e){
                if(!isFinishing()) {
                    finish();
                }
                Log.v(GlobalVariables.TAG,"Camera opening exception");
            }
        }

        startPreview();
        preview.post(new Runnable() {
            @Override
            public void run() {
                if (inPreview) {
                    camera.takePicture(null, null, photoCallback);
                    inPreview=false;
                }
            }
        });
    }
    @Override
    public void onPause() {
        super.onPause();
        Log.v(GlobalVariables.TAG,"Camera activity onPause called");
        if (inPreview) {
            if(camera!=null) {
                camera.stopPreview();
            }
        }
        if(camera!=null) {
            camera.release();
            camera = null;
        }
        inPreview=false;
    }

    @Override
    protected void onDestroy() {
        Log.v(GlobalVariables.TAG,"Camera activity onDestroy called!");
        super.onDestroy();
        if(camera!=null){
            camera.release();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        new MenuInflater(this).inflate(R.menu.options, menu);
        return(super.onCreateOptionsMenu(menu));
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.camera) {
            if (inPreview) {
                camera.takePicture(null, null, photoCallback);
                inPreview=false;
            }
        }
        return(super.onOptionsItemSelected(item));
    }

    private Camera.Size getBestPreviewSize(int width, int height,
                                           Camera.Parameters parameters) {
        Camera.Size result=null;
        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                    result=size;
                }
                else {
                    int resultArea=result.width * result.height;
                    int newArea=size.width * size.height;
                    if (newArea > resultArea) {
                        result=size;
                    }
                }
            }
        }
        return(result);
    }

    private Camera.Size getSmallestPictureSize(Camera.Parameters parameters) {
        Camera.Size result=null;
        for (Camera.Size size : parameters.getSupportedPictureSizes()) {
            if (result == null) {
                result=size;
            }
            else {
                int resultArea=result.width * result.height;
                int newArea=size.width * size.height;

                if (newArea < resultArea) {
                    result=size;
                }
            }
        }
        return(result);
    }

    private void initPreview(int width, int height) {
        if (camera != null && previewHolder.getSurface() != null) {
            try {
                camera.setPreviewDisplay(previewHolder);
            }
            catch (Throwable t) {
                Log.e("PreviewDemo-surfaceCallback",
                        "Exception in setPreviewDisplay()", t);
                Toast.makeText(CameraActivity1.this, t.getMessage(),
                        Toast.LENGTH_LONG).show();
            }

            if (!cameraConfigured) {
                Camera.Parameters parameters=camera.getParameters();
                Camera.Size size=getBestPreviewSize(width, height, parameters);
                Camera.Size pictureSize=getSmallestPictureSize(parameters);

                if (size != null && pictureSize != null) {
                    parameters.setPreviewSize(size.width, size.height);
                    parameters.setPictureSize(pictureSize.width,
                            pictureSize.height);
                    parameters.setPictureFormat(ImageFormat.JPEG);
                    frame.setAspectRatio((double)size.width / size.height);
                    camera.setParameters(parameters);
                    cameraConfigured=true;
                }
            }
        }
    }

    private void startPreview() {
        if (cameraConfigured && camera != null) {
            camera.startPreview();
            inPreview=true;
        }
    }

    SurfaceHolder.Callback surfaceCallback=new SurfaceHolder.Callback() {
        public void surfaceCreated(SurfaceHolder holder) {
            // no-op -- wait until surfaceChanged()
        }

        public void surfaceChanged(SurfaceHolder holder, int format,
                                   int width, int height) {
            initPreview(width, height);
            startPreview();
        }

        public void surfaceDestroyed(SurfaceHolder holder) {
            // no-op
        }
    };

    Camera.PictureCallback photoCallback=new Camera.PictureCallback() {
        public void onPictureTaken(byte[] data, Camera camera) {
            new SavePhotoTask().execute(data);
            camera.startPreview();
            inPreview=true;
            if(!isFinishing()) {
                finish();
            }
        }
    };

I use the following piece of code to click a picture after the preview surface is properly created in onResume().

preview.post(new Runnable() {
            @Override
            public void run() {
                if (inPreview) {
                    camera.takePicture(null, null, photoCallback);
                    inPreview=false;
                }
            }
        });

Any help is appreciated.Thanks

like image 709
SteveIrwin Avatar asked Oct 20 '22 02:10

SteveIrwin


1 Answers

I think you can use WakeLock to make sure that Screen-Off does not occur. Below is the sample code/algorithm by which you can turn on screen whenever it goes off. Hope This Helps!

  1. Register a broadcast receiver on Intent.ACTION_SCREEN_OFF.
  2. Whenever you get screen off broadcast intent, wake-up by using below code.

    PowerManager pm = (PowerManager) context
                            .getSystemService(Context.POWER_SERVICE);
                    WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
                            | PowerManager.ACQUIRE_CAUSES_WAKEUP
                            | PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
                    wakeLock.acquire();
    
like image 103
srs Avatar answered Oct 29 '22 18:10

srs