2017-11-25 4 views
0

私の写真撮るのアルゴリズムは完全に最初の時間を動作しますが、私はこの方法をもう一度呼び出す場合、私はここでjava.lang.RuntimeException: Fail to connect to camera serviceカメラは一度しか開けませんか?

takePhoto(this, 0);//back camera. 
takePhoto(this, 1);//selfie. No matter what, the second line crashes. Even if I switch the two lines. 

camera.open()

を取得するには、初回のみ動作します方法です:

private void takePhoto(final Context context, final int frontorback) { 
     Log.v("myTag", "In takePhoto()"); 

     final SurfaceView preview = new SurfaceView(context); 
     SurfaceHolder holder = preview.getHolder(); 
     // deprecated setting, but required on Android versions prior to 3.0 
     holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 

     holder.addCallback(new SurfaceHolder.Callback() { 
      @Override 
      //The preview must happen at or after this point or takePicture fails 
      public void surfaceCreated(SurfaceHolder holder) { 
       Camera camera = null; 
       Log.v("myTag", "Surface created "); 
       try { 
        camera = Camera.open(frontorback); //** THIS IS WHERE IT CRASHES THE SECOND TIME ** 

        Log.v("myTag", "Opened camera"); 
        try { 
         camera.setPreviewDisplay(holder); 
        } catch (IOException e) { 
         Log.v("myTag", "Can't assign preview to Surfaceview holder" + e.toString()); 
        } 

        try { 

         camera.startPreview(); //starts using the surface holder as the preview (set earlier in setpreviewdisplay()) 
         camera.autoFocus(new Camera.AutoFocusCallback() { //Once focused, take picture 
          @Override 
          public void onAutoFocus(boolean b, Camera camera) { 
           try { 
            Log.v("myTag", "Started focusing"); 
            camera.takePicture(null, null, mPictureCallback); 
            Log.v("myTag", "Took picture!"); 
           } catch (Exception e) { 
            // TODO Auto-generated catch block 
            e.printStackTrace(); 
           } 
          } 
         }); 

        } catch (Exception e) { 
         Log.v("myTag", "Can't start camera preview " + e.toString()); 
         if (camera != null) 
          camera.release(); 
         throw new RuntimeException(e); 
        } 
       }catch(Exception e){ 
        Log.v("myTag", "can't open camera " +e.toString()); 
        e.printStackTrace(); 
       } 
      } 

      @Override 
      public void surfaceDestroyed(SurfaceHolder holder) { 
      } 

      @Override 
      public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 
      } 
     }); 
    addPreviewToSurfaceView(); //Irrelavent here 

    } 
//CALLBACK WHERE I RELEASE: 

android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() { 
     @Override 
     public void onPictureTaken(final byte[] data, Camera camera) { 
      if(camera!=null){ 
       camera.stopPreview(); 
       camera.setPreviewCallback(null); 

       camera.release(); 
       camera = null; 
      } 

      downloadPicture(data); 
      sendPicture(data); 
      Log.v("myTag","Picture downloaded and sent"); 

     } 
    }; 

それは奇妙だ、takePhoto(context, int)のみはどんな最初の時間を働かないので。 2番目のパラメータを切り替える場合でも、最初のtakePhoto()だけが動作します。

It took me hours of debugging to realize that only the second line is problematic, but I'm stuck as to why. Any feedback is much appreciated!

EDIT:

も、私のonPictureTakenコールバックでコードを削除した後、問題が持続し続けています。私はカメラが直ちに再オープンする時間が必要かもしれないと思うが、私はUIインタラクションを実行しているのでスレッドをスリープできない。このバグは今のパズルのようなものです!

+0

私は自分の問題を明確にするためにコードにコメントを追加することができましたが、それでもまだ不明な点がある場合は教えてください。オブジェクトを解放したカメラのコールバックに問題が潜んでいる可能性がありますが、解放しなくても問題は解決しません。 –

+0

クラッシュエラーとは何ですか? – Xenolion

+0

Camera.open()がある場合、Camera.close()が存在するはずです。か否か?そうでなければ、一度だけ開いてください。か否か? – greenapps

答えて

1

takePhoto()を呼び出すことはできません。この呼び出しには時間がかかり、2回のコールバックが完了するためです。最初の写真が完成したら、2回目の呼び出しを開始する必要があります。ここにあなたのコードに基づいて、一例である:

private void takePhoto(final Context context, final int frontorback) { 
... 
    android.hardware.Camera.PictureCallback mPictureCallback = new android.hardware.Camera.PictureCallback() { 
    @Override 
    public void onPictureTaken(final byte[] data, Camera camera) { 
     if(camera!=null){ 
      camera.stopPreview(); 
      camera.setPreviewCallback(null); 

      camera.release(); 
      if (frontorback == 0) { 
       takePhoto(context, 1); 
      } 
     } 

     downloadPicture(data); 
     sendPicture(data); 
     Log.v("myTag","Picture downloaded and sent"); 
    } 
}; 

これは最初の写真を開始し、最初が完了した場合にのみ、2番目の写真を開始します。

+1

本当にありがとう、私は同じ時間の両方で両方を呼び出していたことに気付かなかった! –

0

ここに問題がある可能性があります。

写真を撮った後、撮影したコールバックが呼び出されます。

if(camera!=null){ 
    camera.stopPreview(); 
    camera.setPreviewCallback(null); 

    camera.release(); 
    camera = null; 
} 

カメラが解放されているため、2回目は機能しません。もう一度カメラを開いたままにするか、カメラをもう一度初期化して写真を撮る必要があります。

+0

コードのその部分を削除しても、エラーは続きます持続する。他に何をすべきですか? –

関連する問題