活动重启时相机预览停止

时间:2013-07-01 12:18:36

标签: android camera preview

我为Android制作了一个相机预览应用程序,即使我按下电源按钮使设备处于睡眠状态并再次唤醒它,一切正常。但是当我的活动进入后台(比如按下主页按钮)然后再次进入前台时,程序就停止了。

这是我的活动代码:

package com.example.campreview;

import com.example.campreview.CameraPreview;
import com.example.campreview.R;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.Menu;
import android.view.View;

public class ScanActivity extends Activity  {

    private CameraPreview CamPrev = null;
    private FrameLayout PreviewFrm; 

    private Camera cam = null;    
    private Handler atfcs;
    private ImageScanner scnr;

    private boolean hascam = false;
    private boolean prvng = true;
    private boolean paused = false; 

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);     
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        PreviewFrm = (FrameLayout)findViewById(R.id.PreviewFrm); 

        StartCamera();
        if (cam != null) {
            hascam = true;
            atfcs = new Handler();
            CamPrev = new CameraPreview(this, cam, PreviewCB, AutoFocusCB);
            PreviewFrm.addView(CamPrev);
        }    
    }

    @Override
    public void onPause() { 
        ReleaseCamera();
        paused = true;
        super.onPause();  
    }

    @Override
    public void onResume() {
        super.onResume();
        if (paused) StartPreview();
    }

    private boolean StartCamera() {
        boolean r = true;
        if (cam == null) {
            try {
                cam = Camera.open();
            } catch (Exception e) {
                cam = null;
                r = false;
            }
            if (cam != null) {
                try {
                    Camera.Parameters p = cam.getParameters();          
                    if (p.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO))
                        p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    if (p.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_OFF))
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    if (p.getSupportedPreviewFormats().contains(ImageFormat.NV21))
                        p.setPreviewFormat(ImageFormat.NV21);
                    Camera.Size s = null;
                    int a = 0, b;       
                    for (Camera.Size z : p.getSupportedPreviewSizes()) {
                        b = z.width * z.height;
                        if (Math.abs(b - 307200) < Math.abs(a - 307200)) { //640x480 is the best
                            s = z;
                            a = b;
                        }   
                    }
                    if (a != 0) p.setPreviewSize(s.width, s.height);    
                    cam.setParameters(p);
                    cam.setDisplayOrientation(90);          
                    if (CamPrev != null) cam.setPreviewDisplay(CamPrev.getHolder());    
                } catch (Exception e) {
                    r = false;
                    cam.release();
                    cam = null;
                }
            }
        }
        return r;
    }

    private void ReleaseCamera() {
        if (cam != null) {
            StopPreview();
            cam.release();
            cam = null;
        }
    }

    public void StartPreview() {
        if ((!prvng) & hascam) {
            if (StartCamera()) {
                cam.setPreviewCallback(PreviewCB);
                cam.startPreview();
                cam.autoFocus(AutoFocusCB);
                prvng = true;               
            }
        }
    }

    public void StopPreview() {
        if (prvng) {
            cam.stopPreview();
            cam.setPreviewCallback(null);
            prvng = false;   
        }
    }

    private Runnable DoAutoFocus = new Runnable() {
        public void run() {
            if (prvng) cam.autoFocus(AutoFocusCB);
        }
    };

    AutoFocusCallback AutoFocusCB = new AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            atfcs.postDelayed(DoAutoFocus, 1000);
        }
    };

    PreviewCallback PreviewCB = new PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {             
             //
         }
     };

}

这是预览代码:

package com.example.campreview;

import java.io.IOException;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.content.Context;
import android.hardware.Camera;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.AutoFocusCallback;

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {
    private SurfaceHolder hldr;
    private Camera cam;
    private PreviewCallback pcb;
    private AutoFocusCallback afcb;

    public CameraPreview(Context context, Camera camera, PreviewCallback previewCb, AutoFocusCallback autoFocusCb) {
        super(context);
        cam = camera;
        pcb = previewCb;
        afcb = autoFocusCb;
        hldr = getHolder();
        hldr.addCallback(this);
        //hldr.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }

    public void surfaceCreated(SurfaceHolder holder) {
        try {
            cam.setPreviewDisplay(holder);            
        } catch (IOException e) {
            // No Code
        }
    }

    public void surfaceDestroyed(SurfaceHolder holder) {}

    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
        if (hldr.getSurface() == null) return;
        try {
            cam.stopPreview();
        } catch (Exception e){
            // No Code
        }
        try {
            cam.setPreviewDisplay(hldr);
            cam.setPreviewCallback(pcb);
            cam.startPreview();
            cam.autoFocus(afcb);
        } catch (Exception e) {
            // No Code
        }
    }
}

有什么想法可以解决这个问题吗?

1 个答案:

答案 0 :(得分:0)

我发现了问题。似乎在程序中制作的SurfaceView会在活动停止时销毁。所以我在布局中用SurfaceView替换它。

package com.example.campreview;

import com.example.campreview.R;

import java.io.IOException;

import android.graphics.ImageFormat;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;

public class ScanActivity extends Activity implements OnClickListener  {

    private SurfaceView PreviewSfc;

    private Camera cam = null;    
    private Handler atfcs;

    private boolean hascam = false;
    private boolean validdisplay = false; 
    private boolean prvng = false;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_scan);     
        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);

        PreviewSfc = (SurfaceView)findViewById(R.id.PreviewSfc);
        PreviewSfc.getHolder().addCallback(SurfaceCB);
        //PreviewSfc.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        StartCamera();      
        if (cam != null) {
            hascam = true;
            atfcs = new Handler();
        }    
    }

    @Override
    public void onPause() { 
        ReleaseCamera();
        super.onPause();  
    }

    @Override
    public void onResume() {
        super.onResume();
        StartPreview();
    }

    private boolean StartCamera() {
        boolean r = true;
        if (cam == null) {
            try {
                cam = Camera.open();
            } catch (Exception e) {
                cam = null;
                r = false;
            }
            if (cam != null) {
                try {
                    Camera.Parameters p = cam.getParameters();          
                    if (p.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_AUTO))
                        p.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO);
                    if (p.getSupportedFlashModes().contains(Camera.Parameters.FLASH_MODE_OFF))
                        p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
                    if (p.getSupportedPreviewFormats().contains(ImageFormat.NV21))
                        p.setPreviewFormat(ImageFormat.NV21);
                    Camera.Size s = null;
                    int a = 0, b;       
                    for (Camera.Size z : p.getSupportedPreviewSizes()) {
                        b = z.width * z.height;
                        if (Math.abs(b - 307200) < Math.abs(a - 307200)) { //640x480 is the best
                            s = z;
                            a = b;
                        }   
                    }
                    if (a != 0) p.setPreviewSize(s.width, s.height);    
                    cam.setParameters(p);
                    cam.setDisplayOrientation(90);          
                    if (validdisplay) cam.setPreviewDisplay(PreviewSfc.getHolder());
                } catch (Exception e) {
                    r = false;
                    cam.release();
                    cam = null;
                }
            }
        }
        //if (!r) Error message that failed to start camera
        return r;
    }

    private void ReleaseCamera() {
        if (cam != null) {
            StopPreview();
            cam.release();
            cam = null;
        }
    }

    public void StartPreview() {
        if ((!prvng) & (hascam) & (validdisplay)) {
            if (StartCamera()) {
                cam.setPreviewCallback(PreviewCB);
                cam.startPreview();
                cam.autoFocus(AutoFocusCB);
                prvng = true;   
            }
        }
    }

    public void StopPreview() {
        if (prvng) {
            cam.stopPreview();
            cam.setPreviewCallback(null);
            prvng = false;  
        }   
    }

    private Runnable DoAutoFocus = new Runnable() {
        public void run() {
            if (prvng) cam.autoFocus(AutoFocusCB);
        }
    };

    AutoFocusCallback AutoFocusCB = new AutoFocusCallback() {
        public void onAutoFocus(boolean success, Camera camera) {
            atfcs.postDelayed(DoAutoFocus, 1000);
        }
    };

    PreviewCallback PreviewCB = new PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera camera) {             
             //
         }
     };

     SurfaceHolder.Callback SurfaceCB = new SurfaceHolder.Callback() {
         public void surfaceCreated(SurfaceHolder holder) {
             if (cam != null) {
                 try {
                     cam.setPreviewDisplay(holder);              
                 } catch (IOException e) {
                     // No Code
                 }
             }
         }

         public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
             validdisplay = true;
             StartPreview();         
         }

         public void surfaceDestroyed(SurfaceHolder holder) {
             validdisplay = false;
         }
     };

}