2013-07-01 142 views
2

我做了一個android的相機預覽應用程序,一切正常,即使我按下電源按鈕讓設備睡着,並再次醒來。但是,當我的活動進入後臺(如按下home鍵),然後再次到達前臺,程序將停止。相機預覽停止在活動重新啓動

這是我的活動代碼:

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 
     } 
    } 
} 

有什麼想法,我怎麼能解決這個問題?

+0

也許您的內存不足? –

+0

@Seraphim我不這麼認爲,這是簡單的輕應用程序,任何其他相機應用程序在這種情況下工作正常。 – Vahid

回答

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; 
     } 
    }; 

}