简体   繁体   English

从睡眠状态返回时,相机强制关闭。 Android的

[英]Camera force close when returning from sleep. Android

In my app I'm capturing an image. 在我的应用中,我正在捕获图像。 Everything is working fine unless the phone goes to sleep while the preview is running. 除非预览运行时手机进入睡眠状态,否则一切都会正常进行。 Not really sure how to handle it, I'm thinking that it may be best just to prevent the phone from automatically going to sleep while this process is in action. 我不太确定如何处理它,我认为这可能是最好的做法,只是防止手机在此过程开始时自动进入睡眠状态。 Which i do not know how to do. 我不知道该怎么办。 and if i do that will it prevent the phone from sleeping when i press the power button? 如果我这样做,是否可以防止在我按下电源按钮时手机进入休眠状态? perhaps there is a deeper issue here. 也许这里有一个更深层次的问题。

LogCat: 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 activity: 拍照活动:

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

    }

Preview surfaceview: 预览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();
      }


    }

I've added a wake lock to prevent the phone from dimming, I feel this is a temporary solution though as there is still a force close when the device is forced to sleep via power button. 我添加了唤醒锁以防止手机变暗,尽管这仍然是一个临时解决方案,但是当通过电源按钮强制设备进入睡眠状态时,仍然有一个力闭合。

Why are you calling invalidate() for every preview frame? 为什么要为每个预览帧调用invalidate()? The camera display should update without it. 没有它,相机显示应该更新。

Either remove the preview callback altogether (since you don't seem to be doing anything else anyway), or try setting camera.setPreviewCallback(null) in onResume() before you release so that it doesn't try to call it after you have freed the cameras resources. 要么完全删除预览回调(因为您似乎仍然没有做任何其他事情),要么尝试在释放前在onResume()中设置camera.setPreviewCallback(null) ,以便在拥有后不再尝试调用它。释放了相机资源。 You are getting an exception because you are trying to access the camera somewhere after you have released it. 之所以会出现异常,是因为您尝试在释放相机后尝试访问相机。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM