I am having a slight problem with my camera implementation. Currently when i open the camera preview and i lock the phone and then unlock it when coming back the preview is okay and still there running.

Problem is that when i press the phone's home button the preview is not showing anymore when coming back to the application, just a black screen, no crash but also no preview.

Here's my code. I am guessing the mistake should be somewhere the methods onResume(), onPause(), onStop() but i am not able to figure it out exactly.

THIS IS MY UPDATED SOULUTION:::::

package ro.gebs.captoom.activities;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.Toast;

import java.io.File;
import java.io.IOException;
import java.util.List;

import ro.gebs.captoom.R;
import ro.gebs.captoom.asynctasks.SavePictAsync;
import ro.gebs.captoom.interfaces.FinishTakePictureCallback;
import ro.gebs.captoom.utils.Utils;
import ro.gebs.captoom.utils.fonts.CustomFontButton;
import ro.gebs.captoom.utils.fonts.TopMenu;

@SuppressLint("SimpleDateFormat")
public class TakePicture extends Activity implements FinishTakePictureCallback {


    private SurfaceView surfaceView = null;
    private Camera camera = null;
    private Button buttonTakePicture;
    private boolean isFlashOn = false;
    private long the_folder_id;
    private boolean inPreview = true;

    Camera.AutoFocusCallback myAutoFocusCallback = new Camera.AutoFocusCallback() {
        @Override
        public void onAutoFocus(boolean success, Camera arg1) {
            if (success) {
                camera.takePicture(null, null, myPictureCallback_JPG);
            } else {
                Utils.showToast(TakePicture.this, "Not focused, try again", Toast.LENGTH_SHORT);
                buttonTakePicture.setEnabled(true);
            }
        }
    };

    final Camera.PictureCallback myPictureCallback_JPG = new Camera.PictureCallback() {
        @Override
        public void onPictureTaken(byte[] arg0, Camera arg1) {
            new SavePictAsync(arg0, TakePicture.this, camera, the_folder_id, buttonTakePicture).execute();
        }
    };


    @Override
    protected void onCreate(Bundle savedInstanceState) {

        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);

        super.onCreate(savedInstanceState);

        setContentView(R.layout.camera_control);

        surfaceView = (SurfaceView) findViewById(R.id.preview);
        surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().addCallback(new SurfaceHolder.Callback() {

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                System.out.println("------------ surf Created");

                if (camera == null) {
                    camera = Camera.open();
                    Camera.Parameters params = camera.getParameters();
                    params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    camera.setParameters(params);

                    try {
                        System.out.println("------------ 1");

                        camera.setPreviewDisplay(holder);

                        Camera.Parameters parameters = camera.getParameters();

                        List<Size> sizes = parameters.getSupportedPreviewSizes();
                        for (Size size : sizes) {
                            Log.d("TakePicture", size.height + "X" + size.width + "height" + surfaceView.getHeight() + "width" + surfaceView.getWidth());
                        }
                        Size optimalSize = getOptimalPreviewSize(sizes, surfaceView.getHeight(), surfaceView.getWidth());
                        parameters.setPreviewSize(optimalSize.width, optimalSize.height);

                        camera.setDisplayOrientation(90);
                        camera.setParameters(parameters);

                        camera.startPreview();
                        inPreview = true;
                    } catch (IOException e) {
                        Log.e("Take Picture", "Error", e);
                    }
                }
            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                System.out.println("------------ surf Destroyed");
                if (inPreview) {
                    try {
                        if (camera != null) {
                            camera.cancelAutoFocus();
                            camera.stopPreview();
                        }
                        inPreview = false;
                    } catch (RuntimeException e) {
                        e.printStackTrace();
                    } finally {
                        if (camera != null) {
                            camera.release();
                            camera = null;
                        }
                    }
                }
            }


            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
                if (!inPreview) {
                    try {
                        System.out.println("------------ surf Changed");
                        camera = Camera.open();
                        camera.setPreviewDisplay(surfaceView.getHolder());
                        camera.setDisplayOrientation(90);
                        camera.startPreview();
                        inPreview = true;
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }


        }

        );

        LayoutInflater controlInflater = LayoutInflater.from(getBaseContext());
        ViewGroup viewControl = (ViewGroup) controlInflater.inflate(R.layout.camera_control, null);

        assert viewControl != null;
        final CustomFontButton cancel_btn = (CustomFontButton) findViewById(R.id.cancel_btn);
        cancel_btn.setOnClickListener(new View.OnClickListener()

        {
            @Override
            public void onClick(View v) {
                finish();
            }
        }

        );

        buttonTakePicture = (Button) findViewById(R.id.take_picture);

        buttonTakePicture.setOnClickListener(new Button.OnClickListener()

        {
            @Override
            public void onClick(View arg0) {
                try {
                    Utils.showToast(TakePicture.this, "Focusing...", Toast.LENGTH_SHORT);
                    camera.autoFocus(myAutoFocusCallback);
                    buttonTakePicture.setEnabled(false);
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
            }
        }

        );

        RelativeLayout headerView = (RelativeLayout) findViewById(R.id.top_header_green);
        ImageButton menu_btn = (ImageButton) findViewById(R.id.menu_btn);
        new

                TopMenu(this, this, headerView, menu_btn);


        ImageButton flashBtn = (ImageButton) findViewById(R.id.flash_btn);
        flashBtn.setOnClickListener(new View.OnClickListener()

        {
            @Override
            public void onClick(View view) {
                Context context = getApplicationContext();
                if (context.getPackageManager().hasSystemFeature(getPackageManager().FEATURE_CAMERA_FLASH)) {
                    Camera.Parameters params = camera.getParameters();
                    if (isFlashOn) {
                        params.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                        camera.setParameters(params);
                        isFlashOn = false;
                        Utils.showToast(context, getString(R.string.FlashOff), Toast.LENGTH_SHORT);
                    } else {
                        params.setFlashMode(Camera.Parameters.FLASH_MODE_AUTO);
                        camera.setParameters(params);
                        isFlashOn = true;
                        Utils.showToast(context, getString(R.string.FlashAuto), Toast.LENGTH_SHORT);
                    }
                }
            }

        }

        );

    }

    @Override
    public void finishTakePicture() {
        finish();
    }

    @Override
    protected void onResume() {
        the_folder_id = getIntent().getLongExtra("the_folder_id", 0);
        buttonTakePicture.setEnabled(true);
        super.onResume();
    }

    @Override
    public void onBackPressed() {
        super.onBackPressed();
        if (PreviewPhoto.photos != null) {
            for (String image : PreviewPhoto.photos) {
                File file = new File(image);
                file.delete();
            }
            PreviewPhoto.photos.clear();
        }
    }

    private Size getOptimalPreviewSize(List<Size> sizes, int w, int h) {
        final double ASPECT_TOLERANCE = 0.1;
        double targetRatio = (double) w / h;
        if (sizes == null)
            return null;

        Log.d("TakePicture", "TargetRatio: " + targetRatio);
        Size optimalSize = null;
        double minDiff = Double.MAX_VALUE;

        for (Size size : sizes) {
            double ratio = (double) size.width / size.height;
            if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE)
                continue;
            if (Math.abs(size.height - h) < minDiff) {
                optimalSize = size;
                minDiff = Math.abs(size.height - h);
            }
        }

        if (optimalSize == null) {
            minDiff = Double.MAX_VALUE;
            for (Size size : sizes) {
                if (Math.abs(size.height - h) < minDiff) {
                    optimalSize = size;
                    minDiff = Math.abs(size.height - h);
                }
            }
        }
        Log.d("TakePicture", "The optimal size is:" + optimalSize.height + "X" + optimalSize.width);
        return optimalSize;
    }
}

Since i was already overriding surfaceDestroyed, surfaceCreated there was not much left to do in the onPause, onResume methods.

Hope this question helps out a lot of people since it proves to be a good Camera impementation for android.

What do you think?

Since this is a working solution i was wondering if you guys think this is an efficient implementation? I am asking this because i have only tested it on some devices...

有帮助吗?

解决方案

Put some breakpoints in the onPause and onResume methods and see what happens. This is kinda odd what you is happening. Also try taking a picture or record a video when the preview is black and see what happens. Post the logcat

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top