1

ネイティブカメラを使用するアプリがあり、ビデオを作成してからカメラを切り替え、別のカメラを作成して追加する必要があります。問題は、カメラを離すと、2 番目のビデオを録画すると、次のように表示されることです: release() 後にメソッドを呼び出すことはできません。カメラを解放しないと、2 番目のカメラを変更するときに次のように表示されます。 カメラ サービスに接続できません。

これは、カメラを切り替える機能です。

 cameraFlipButton.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                if (recording) {
                    wasrecording = true;
                }
                LogService.log(TAG, "--------------SWITCH CAMERA PRESSED");
                LogService.log(TAG, "Camera: " + mCameraDevice.getCamera().getParameters() + "camera id: " + mCameraId);
                if (mCameraId == 0) {
                    mCameraId = 1;
                    mCurrentModule.mPendingSwitchCameraId = 1;
                } else if (mCameraId == 1) {
                    mCameraId = 0;
                    mCurrentModule.mPendingSwitchCameraId = 0;
                }
                if (recording) {
                    recording = false;
                    recordButton.setImageResource(R.drawable.shutter);
                    if (timer != null) {
                        LogService.log(TAG, "---------------Timer2: " + timer);
                        timer.cancel();
                        timer.purge();
                    }
                    timer = null;
                    Handler han = new Handler();
                    han.postDelayed(new Runnable() {

                        @Override
                        public void run() {
                            mCurrentModule.switchCamera();

                        }
                    }, 200);

                } else {
                    mCurrentModule.switchCamera();
                }
            }
        });

これは、カメラ マネージャーからカメラを切り替える関数です (mCurrentModule.switchCamera()):

public void switchCamera() {
    if (mPaused)
        return;

    Log.i(TAG, "MAMAMAMAMAMAM Start to switch camera. VIDEO MODULE (switchCamera)");
    mCameraId = mPendingSwitchCameraId;
    mPendingSwitchCameraId = -1;
    setCameraId(mCameraId);
    Log.i(TAG, "MAMAMAMAMAMAM after settting camera id VIDEO MODULE (switchCamera)");

    CameraHolder.instance().release();
    Log.i(TAG, "MAMAMAMAMAMAM after release VIDEO MODULE (switchCamera)");
    videoFragment.mCameraDevice = null;
    mPreviewing = false;
    Log.i(TAG, "MAMAMAMAMAMAM before open camera VIDEO MODULE (switchCamera)");
    openCamera();
    Log.i(TAG, "MAMAMAMAMAMAM after open camera VIDEO MODULE (switchCamera)");
    getDesiredPreviewSize();
    Log.i(TAG, "MAMAMAMAMAMAM after get desired size VIDEO MODULE (switchCamera)");
    startPreview();
    Log.i(TAG, "MAMAMAMAMAMAM after start preview VIDEO MODULE (switchCamera)");
    resizeForPreviewAspectRatio();
    Log.i(TAG, "MAMAMAMAMAMAM before handler VIDEO MODULE (switchCamera)");
    if (ApiHelper.HAS_SURFACE_TEXTURE) {
        // Start switch camera animation. Post a message because
        // onFrameAvailable from the old camera may already exist.
        mHandler.sendEmptyMessage(SWITCH_CAMERA_START_ANIMATION);
    }
}

CameraHolder.instance().release();この関数から、これを行うカメラを解放するハンドラーを呼び出します。

public synchronized void release() {

    if (mCameraDevice == null)
        return;

    mCameraOpened = false;
    mCameraDevice.release();
    mCameraDevice = null;
    // We must set this to null because it has a reference to Camera.
    // Camera has references to the listeners.
    mParameters = null;
    mCameraId = -1;
}

リリースした後、カメラを再度開きます。

public synchronized CameraProxy open(int cameraId) throws CameraHardwareException {
    // Log.i(TAG,
    // "MAMAMAMAMAMAM before release from open CAMERA HOLDER open() CameraProxy");
    if (mCameraOpened) {
        Log.i(TAG, "MAMAMAMAMAMAM before release CAMERA OPENED CAMERA HOLDER open() CameraProxy ");
        mCameraDevice.release();
    }
    if (mCameraDevice != null) {
        Log.i(TAG, "MAMAMAMAMAMAM before release from open mCameraId != cameraId CAMERA HOLDER open() CameraProxy");
        mCameraDevice.release();
        mCameraDevice = null;
        mCameraId = -1;
    }
    if (mCameraDevice == null) {
        try {
            Log.i(TAG, "MAMAMAMAMAMAM open camera " + cameraId);
            if (mMockCameraInfo == null) {
                mCameraDevice = CameraManager.instance().cameraOpen(cameraId);
            } else {
                if (mMockCamera == null)
                    throw new RuntimeException();
                mCameraDevice = mMockCamera[cameraId];
            }
            mCameraId = cameraId;
        } catch (RuntimeException e) {
            Log.e(TAG, "fail to connect Camera", e);
            throw new CameraHardwareException(e);
        }
        mParameters = mCameraDevice.getParameters();
    } else {
        try {
            mCameraDevice.reconnect();
        } catch (IOException e) {
            Log.e(TAG, "reconnect failed.");
            throw new CameraHardwareException(e);
        }
        mCameraDevice.setParameters(mParameters);
    }
    mCameraOpened = true;
    mHandler.removeMessages(RELEASE_CAMERA);
    mKeepBeforeTime = 0;
    return mCameraDevice;
}

この後、画面のサイズを取得し、プレビューなどを設定します。その後、もう一度記録ボタンを押すと、「release() 後にメソッドを呼び出すことができません」でクラッシュします。リリースしないと、カメラ サービスへの接続に失敗するため、カメラを切り替えるときにクラッシュします。これを回避する方法はありますか?どうすればカメラを解放し、それでも記録できるようになりますか?

4

1 に答える 1