5

私はカメラ API を使用してアプリを作成しています: プレビューを表示し、写真を撮ります。最初のバージョンは非常にうまく機能します。クラス Preview では、SurfaceView を拡張し、SurfaceHolder.Callback を実装します。

public void surfaceCreated(SurfaceHolder holder) {
    // The Surface has been created, acquire the camera and tell it where
    // to draw.
    camera = Camera.open();
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();

    } catch (IOException e) {
        e.printStackTrace();
    }

    hasSurface = true;
}


public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
    // It will be called immediately after surfaceCreated
    // I move it to Resume.
    setCameraPreviewParameters();

    camera.startPreview();

}

主なアクティビティでは:

public class CameraDemo extends Activity

メンバーも設定しました: CameraUnit ui; それは:

public class CameraUnit extends LinearLayout

onCreate では、

    @Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    ui = new CameraUnit(this);
    setContentView((View) ui); 

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

それは、surfaceView とカメラ ボタンを含む LinearLayout オブジェクトを作成します。

onResume は次のとおりです。

    @Override
protected void onResume() {
    super.onResume();
}

動作しますが、onResume を空にするべきではないと思います。また、有名な Android アプリの例である OCRTestで surfaceCreated と surfaceChanged が空であることも確認しました 。したがって、surfaceCreated と surfaceChanged のコマンドを onResume に移動する方が適切であり、実現可能であると考えています。

私のアプリの最初のバージョンのフロー チャットは次のようになるはずです: メイン アクティビティ onCreate (LinearLayout とその surfaceView、カメラ ボタンが作成される場所)、surfaceCreated と surfaceChanged が onResume と呼ばれます。

したがって、surfaceCreated と surfaceChanged のコマンドを onResume に移動するだけです。しかし、うまくいきません!デバッグを使用して、サーフェスが null であることを確認しました。surfaceCreatd が呼び出されていないと思います。私のアプリは、メイン アクティビティに SurfaceHolder.Callback を実装する OCRTest とは異なります。SurfaceView に SurfaceHolder.Callback を実装します。

class Preview extends SurfaceView implements SurfaceHolder.Callback

だから私は onResume に他の2行を追加します

        ui.preview.surfaceCreated(ui.preview.mHolder);
    ui.preview.surfaceChanged(ui.preview.mHolder, 0, 800, 400);

最後の 3 つの整数引数をランダムに設定しました。アクティビティを開始すると、Android フォンのエラー ウィンドウが表示されます。「原因: java.lang.RuntimeException: カメラ サービスへの接続に失敗しました」と表示されます。しかし、それを修正する方法???? どうもありがとう!

エラーは次のとおりです。

    01-07 00:27:57.173: W/dalvikvm(11625): threadid=1: thread exiting with uncaught exception (group=0x4001d5a0)
01-07 00:27:57.173: E/AndroidRuntime(11625): FATAL EXCEPTION: main
01-07 00:27:57.173: E/AndroidRuntime(11625): java.lang.RuntimeException: Unable to resume activity {com.example/com.example.CameraDemo}: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2460)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:2481)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:1847)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.access$1500(ActivityThread.java:132)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1038)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Handler.dispatchMessage(Handler.java:99)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.os.Looper.loop(Looper.java:150)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.main(ActivityThread.java:4263)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invokeNative(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at java.lang.reflect.Method.invoke(Method.java:507)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at dalvik.system.NativeStart.main(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625): Caused by: java.lang.RuntimeException: Fail to connect to camera service
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.native_setup(Native Method)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.<init>(Camera.java:265)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.hardware.Camera.open(Camera.java:241)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.Preview.surfaceCreated(Preview.java:60)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at com.example.CameraDemo.onResume(CameraDemo.java:64)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1242)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.Activity.performResume(Activity.java:3904)
01-07 00:27:57.173: E/AndroidRuntime(11625):    at android.app.ActivityThread.performResumeActivity(ActivityThread.java:2450)
01-07 00:27:57.173: E/AndroidRuntime(11625):    ... 12 more
01-07 00:27:59.455: I/Process(11625): Sending signal. PID: 11625 SIG: 9
4

3 に答える 3

5

あなたはこれを手に入れます

java.lang.RuntimeException: Fail to connect to camera service

例外、カメラが他のアプリケーションで使用されている場合。しかし、他のアプリケーションはあなたのアプリケーションそのものだと思います。カメラを離す必要があります。

これらは、カメラを解放する必要がある場合です。

プレビュークラスの場合:

public void surfaceDestroyed(SurfaceHolder holder) {

    // empty. Take care of releasing the Camera preview in your activity.
    if (mCamera != null) {
        mCamera.release();
    }
}

アクティビティ:

@Override
public void onBackPressed() {
    super.onBackPressed();
    if (myCamera != null) {
        myCamera.release();
    }
    finish();
}

@Override
protected void onPause() {
    // TODO Auto-generated method stub
    super.onPause();
    if (myCamera != null) {
        myCamera.release();
    }
}

また、[キャンセル]をクリックしたとき、およびカメラの使用が終了したとき、つまり、画像がキャプチャされてアクティビティに戻ったとき。

また、これを試してください:

public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {

    if (mHolder.getSurface() == null) {
        return;
    }

    try {
        mCamera.stopPreview();
    } catch (Exception e) {
        //You can ignore this, because this means the Preview doesn't Exist
        //So, no need to try stopping
    }

    try {
        mCamera.setPreviewDisplay(mHolder);
        mCamera.startPreview();
    } catch (Exception e) {
        //Catch this
    }
}
于 2013-01-07T06:43:05.900 に答える
0

いくつかの例では、カメラのオープンコードがsurfaceChangedとonResumeの両方に含まれており、繰り返しを避けるためにif文を使用しています。多分これは問題を解決する一つの方法です。

于 2013-01-16T18:13:24.887 に答える