2010-08-28 72 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