拍照后如何返回相机的取景器?

时间:2015-01-24 12:41:00

标签: android android-camera

我正在Android上制作一个相机示例,目前只需要拍照并将其保存在设备的(内部)内存中。 拍完照片后,屏幕在最后点击的图片上保持冻结,我必须退出应用程序并再次打开它以拍摄另一张照片。 这是我的代码:

MainActivity.java:

package com.example.camera;

import android.app.Activity;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.Menu;
import android.view.Surface;
import android.view.View;
import android.widget.FrameLayout;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MainActivity extends Activity
{
    private Camera mCamera;
    private ShowCamera showCamera;
    public Camera isCameraAvailable()
    {
        Camera camera=null;
        Log.d("isCameraAvailable","Camera object set to null.");
        try
        {
            camera = Camera.open();
            Log.d("isCameraAvailable","Camera opened.");
        }
        catch (Exception e)
        {
            Log.d("isCameraAvailable",e.toString());
        }
        return camera;
    }
    private static File getOutputMediaFile()
    {
        File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"com.example.camera");
        if (!mediaStorageDir.exists())
        {
            if (!mediaStorageDir.mkdirs())
            {
                Log.d("getOutputMediaFile","Failed to create directory.");
                return null;
            }
        }
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        File mediaFile;
        mediaFile = new File(mediaStorageDir.getPath() + File.separator+ "IMG_" + timeStamp + ".jpg");
        Log.d("getOutputMediaFile","Filename created.");
        return mediaFile;
    }
    private PictureCallback capturedIt = new PictureCallback()
    {
        @Override
        public void onPictureTaken(byte[] data, Camera camera)
        {
            File pictureFile = getOutputMediaFile();
            if (pictureFile == null)
            {
                Log.d("onPictureTaken","pictureFile=null");
                return;
            }
            try
            {
                FileOutputStream fos = new FileOutputStream(pictureFile);
                fos.write(data);
                Log.d("onPictureTaken","File written.");
                fos.close();
                Log.d("onPictureTaken","File closed.");
                Toast.makeText(MainActivity.this,pictureFile.toString()+" saved!", Toast.LENGTH_LONG).show();
                return;
            }
            catch (FileNotFoundException e)
            {
                Log.e("onPictureTaken",e.toString());
            }
            catch (IOException e)
            {
                Log.d("onPictureTaken",e.toString());
            }
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mCamera = isCameraAvailable();
        setCameraDisplayOrientation(this,0,mCamera);
        Log.d("onCreate","Camera instance taken.");
        showCamera = new ShowCamera(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.flCameraPreview);
        preview.addView(showCamera);
        Log.d("onCreate","Camera view in initialized");
        preview.setOnClickListener(new View.OnClickListener()
        {
            @Override
            public void onClick(View v)
            {
                mCamera.takePicture(null, null, capturedIt);
                Log.d("onClick","Button Clicked.");
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu)
    {
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }
    public static void 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;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT)
        {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;
        }
        else
        {
            result = (info.orientation - degrees + 360) % 360;
        }
        camera.setDisplayOrientation(result);
    }
}

ShowCamera.java:

package com.example.camera;

import android.content.Context;
import android.hardware.Camera;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

import java.io.IOException;

public class ShowCamera extends SurfaceView implements     SurfaceHolder.Callback
{
    private SurfaceHolder holdMe;
    private Camera mCamera;
    public ShowCamera(Context context,Camera camera)
    {
        super(context);
        this.mCamera = camera;
        this.holdMe = getHolder();
        this.holdMe.addCallback(this);
        this.holdMe.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
    @Override
    public void surfaceChanged(SurfaceHolder surfaceHolder, int format,int width, int height)
    {
        try
        {
            mCamera.setPreviewDisplay(surfaceHolder);
            mCamera.startPreview();
        }
        catch (Exception e)
        {
            Log.d("surfaceChanged",e.toString());
        }
    }
    @Override
    public void surfaceCreated(SurfaceHolder holder)
    {
        try
        {
            mCamera.setPreviewDisplay(holder);
            mCamera.startPreview();
        }
        catch (IOException e)
        {
            Log.e("surfaceCreated",e.toString());
        }
    }
    @Override
    public void surfaceDestroyed(SurfaceHolder surfaceHolder)
    {
        mCamera.stopPreview();
        mCamera.release();
    }
}

拍摄照片并将其保存到内存后,如果再次单击该屏幕,应用程序将崩溃。

1 个答案:

答案 0 :(得分:0)

  

你在surfaceDestroyed中有stopPreview。但当它回来时。你必须在onResume中重启相机。缺少

public void onResume()
{
    mCamera = getCameraInstance(); // i have created this i
                                                    // static method here
    //mCamera.setPreviewCallback(previewCallback);//it depends on you need
    try
    {
        mCamera.setPreviewDisplay(mHolder);

        mCamera.startPreview();
    }
    catch (IOException ioexception)
    {
        Log.e("MyCamera",
                (new StringBuilder()).append("PreviewDisplay Error => ")
                        .append(ioexception.getMessage()).toString());
    }

}

public static Camera getCameraInstance()
    {
        Camera camera1;
        try
        {
            if (android.os.Build.VERSION.SDK_INT >= 9) 
            {
                return Camera.open(cameraId); 
            }
            camera1 = Camera.open();
        }
        catch (Exception exception)
        {
            Log.e("NightVision",
                    (new StringBuilder()).append("ErrorCameraInit: ")
                            .append(exception.getMessage()).toString());
            return null;
        }
        return camera1;
    }