2010-08-28 31 views
2

在我的應用程序中,我正在捕捉圖像。除非手機在預覽運行時進入睡眠狀態,否則一切正常。不確定如何處理它,我認爲最好的做法是防止手機在啓動過程中自動進入睡眠狀態。我不知道該怎麼做。如果我這樣做,它會阻止手機睡覺時,我按下電源按鈕?也許這裏有更深層次的問題。從睡眠中返回時,相機強制關閉。 Android

的logcat:

 

08-28 16:17:10.879: WARN/dalvikvm(9652): threadid=3: thread exiting with uncaught exception (group=0x4001b390) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652): Uncaught handler: thread main exiting due to uncaught exception 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652): java.lang.RuntimeException: Method called after release() 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.hardware.Camera.setHasPreviewCallback(Native Method) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.hardware.Camera.access$600(Camera.java:58) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.hardware.Camera$EventHandler.handleMessage(Camera.java:339) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.os.Handler.dispatchMessage(Handler.java:99) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.os.Looper.loop(Looper.java:123) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at android.app.ActivityThread.main(ActivityThread.java:4595) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at java.lang.reflect.Method.invokeNative(Native Method) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at java.lang.reflect.Method.invoke(Method.java:521) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) 
08-28 16:17:10.879: ERROR/AndroidRuntime(9652):  at dalvik.system.NativeStart.main(Native Method) 

takephoto活動:

public class takephoto extends Activity { 
    private static final String TAG = "GrowJournalDemo"; 
     Preview preview; // <1> 
     Button buttonClick; // <2> 
     String journ_id; 
     String plant_id; 
    // private String plantid = ((resource) this.getApplication()).getplantId(); 
     /** Called when the activity is first created. */ 
     @Override 
     public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     setContentView(R.layout.photo); 

     preview = new Preview(this); // <3> 
     ((FrameLayout) findViewById(R.id.preview)).addView(preview); // <4> 
     String journalid = ((resource) this.getApplication()).getjournalName(); 
     plant_id = ((resource) this.getApplication()).getplantId(); 
     journ_id = journalid; 
     buttonClick = (Button) findViewById(R.id.buttonClick); 
     buttonClick.setOnClickListener(new OnClickListener() { 
      public void onClick(View v) { // <5> 

      // preview.camera.takePicture(shutterCallback, rawCallback, jpegCallback); 
       preview.camera.autoFocus(new Camera.AutoFocusCallback() { 
        Camera.ShutterCallback shutterCallback = new Camera.ShutterCallback() { 
        public void onShutter() { 
         // Play your sound here. 
        } 
        }; 
        public void onAutoFocus(boolean success, Camera camera) { 
        preview.camera.takePicture(null, null, jpegCallback); 
        } 
       }); 

      } 
     }); 

     Log.d(TAG, "onCreate'd"); 
     } 

     // Called when shutter is opened 
     ShutterCallback shutterCallback = new ShutterCallback() { // <6> 
     public void onShutter() { 
      Log.d(TAG, "onShutter'd"); 
     } 
     }; 

     // Handles data for raw picture 
     PictureCallback rawCallback = new PictureCallback() { // <7> 
     public void onPictureTaken(byte[] data, Camera camera) { 
      Log.d(TAG, "onPictureTaken - raw"); 
     } 
     }; 

     // Handles data for jpeg picture 
     PictureCallback jpegCallback = new PictureCallback() { // <8> 
     public void onPictureTaken(byte[] data, Camera camera) { 
      FileOutputStream outStream = null; 
      try { 
       android.os.Environment.getExternalStorageState(); 
      // create a File object for the parent directory 
       File PhotoDirectory = new File(
         android.os.Environment.getExternalStorageDirectory()+ 
         "/GrowJournalPhotos/"+journ_id+"/"+plant_id+"/"); 
       // have the object build the directory structure, if needed. 
       PhotoDirectory.mkdirs(); 
       // create a File object for the output file 
       File outputFile = new File(PhotoDirectory, "photo.jpg"); 
       // now attach the OutputStream to the file object, instead of a String representation 
       outStream = new FileOutputStream(outputFile); 

      outStream.write(data); 
      outStream.close(); 
      Log.d(TAG, "onPictureTaken - wrote bytes: " + data.length); 
      setResult(RESULT_OK); 
      finish(); 

      } catch (FileNotFoundException e) { // <10> 
      e.printStackTrace(); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } finally { 
      } 
      Log.d(TAG, "onPictureTaken - jpeg"); 
     } 
     }; 

    } 

預覽surfaceview:

public class Preview extends SurfaceView implements SurfaceHolder.Callback { 
    private static final String TAG = "Preview"; 

     SurfaceHolder mHolder; // <2> 
     public Camera camera; // <3> 

     Preview(Context context) { 
     super(context); 

     // Install a SurfaceHolder.Callback so we get notified when the 
     // underlying surface is created and destroyed. 
     mHolder = getHolder(); // <4> 
     mHolder.addCallback(this); // <5> 
     mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // <6> 
     } 

     // Called once the holder is ready 
     public void surfaceCreated(SurfaceHolder holder) { // <7> 
     // The Surface has been created, acquire the camera and tell it where 
     // to draw. 
     camera = Camera.open(); // <8> 
     try { 
      camera.setPreviewDisplay(holder); // <9> 

      camera.setPreviewCallback(new PreviewCallback() { // <10> 
      // Called for each frame previewed 
      public void onPreviewFrame(byte[] data, Camera camera) { // <11> 
       Log.d(TAG, "onPreviewFrame called at: " + System.currentTimeMillis()); 
       Preview.this.invalidate(); // <12> 
      } 
      }); 
     } catch (IOException e) { // <13> 
      e.printStackTrace(); 
     } 
     } 

     // Called when the holder is destroyed 
     public void surfaceDestroyed(SurfaceHolder holder) { // <14> 
     camera.stopPreview(); 
     camera.release(); 
     camera = null; 
     } 

     // Called when holder has changed 
     public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) { // <15> 
     camera.startPreview(); 
     } 


    } 

我添加了一個喚醒鎖防止手機從調光,我覺得這是一種臨時解決方案,因爲當設備被強行通過電源按鈕睡眠時仍然有力量關閉。

回答

1

你爲什麼要爲每個預覽幀調用invalidate()?沒有它,相機顯示屏應該更新。

要麼完全刪除預覽回調(因爲您似乎還沒有做其他任何事情),或者在釋放之前嘗試在onResume()中設置camera.setPreviewCallback(null),以便它在釋放後不會嘗試調用它相機資源。您發生異常是因爲您在釋放相機後嘗試在某處訪問相機。

+0

刪除預覽回調修復它。謝謝。 – Brian 2010-09-03 21:09:08