1. ホーム
  2. android

[解決済み] アンドロイドカメラ android.hardware.Camera 非推奨

2022-11-20 06:02:28

質問

もし android.hardware.Camera が非推奨であり、変数 Camera という変数が使えないのですが、ではこれに代わるものは何でしょうか?

どのように解決するのですか?

APIドキュメント

によると Android 開発者ガイド には android.hardware.Camera を使用すると、彼らは述べています。

私たちは、新しい android.hardware.camera2 APIを使用することをお勧めします。

に関する情報ページで android.hardware.camera2 , (上記リンク)に記載されています。

android.hardware.camera2 パッケージは、Android デバイスに接続された個々のカメラデバイスへのインターフェイスを提供します。 非推奨のCameraクラスを置き換えます。

問題点

このドキュメントを確認すると、これら2つのカメラAPIの実装は非常に異なっていることがわかります。

例えば、カメラの向きを取得する android.hardware.camera

@Override
public int getOrientation(final int cameraId) {
    Camera.CameraInfo info = new Camera.CameraInfo();
    Camera.getCameraInfo(cameraId, info);
    return info.orientation;
}

対訳 android.hardware.camera2

@Override
public int getOrientation(final int cameraId) {
    try {
        CameraManager manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
        String[] cameraIds = manager.getCameraIdList();
        CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
        return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
    } catch (CameraAccessException e) {
        // TODO handle error properly or pass it on
        return 0;
    }
}

このため、どちらかに切り替えて、両方の実装を扱えるようなコードを書くことは困難です。

この単一のコード例で、私はすでに古いカメラ API が int プリミティブでカメラ ID を指定するのに対し、新しい API では String オブジェクトで動作します。この例では、新しいAPIでインデックスとしてintを使用することで、すぐに修正しました。もし、返されるカメラの順番がいつも同じでない場合、これはすでに問題を引き起こします。別のアプローチとして、Stringオブジェクトと古いint型カメラIDのString表現で作業するのが、おそらくより安全でしょう。

1 つの離れた周辺

この大きな違いを回避するには、まずインターフェイスを実装し、コード内でそのインターフェイスを参照すればよいのです。

ここでは、そのインターフェイスと2つの実装のコードをリストアップします。カメラAPIを実際に使用するものに限定して実装することで、作業量を抑えることができます。

次のセクションでは、1つまたは別のものをロードする方法を簡単に説明します。

この例では、必要なものをすべて包むインターフェイス、ここでは2つのメソッドだけにしています。

public interface CameraSupport {
    CameraSupport open(int cameraId);
    int getOrientation(int cameraId);
}

これで、古いカメラのハードウェアapi用のクラスができました。

@SuppressWarnings("deprecation")
public class CameraOld implements CameraSupport {

    private Camera camera;

    @Override
    public CameraSupport open(final int cameraId) {
        this.camera = Camera.open(cameraId);
        return this;
    }

    @Override
    public int getOrientation(final int cameraId) {
       Camera.CameraInfo info = new Camera.CameraInfo();
       Camera.getCameraInfo(cameraId, info);
       return info.orientation;
    }
}

そしてもうひとつは新しいハードウェアapiのためのものです。

public class CameraNew implements CameraSupport {

    private CameraDevice camera;
    private CameraManager manager;

    public CameraNew(final Context context) {
        this.manager = (CameraManager) context.getSystemService(Context.CAMERA_SERVICE);
    }

    @Override
    public CameraSupport open(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            manager.openCamera(cameraIds[cameraId], new CameraDevice.StateCallback() {
                @Override
                public void onOpened(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                }

                @Override
                public void onDisconnected(CameraDevice camera) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }

                @Override
                public void onError(CameraDevice camera, int error) {
                    CameraNew.this.camera = camera;
                    // TODO handle
                }
            }, null);
        } catch (Exception e) {
            // TODO handle
        }
        return this;
    }

    @Override
    public int getOrientation(final int cameraId) {
        try {
            String[] cameraIds = manager.getCameraIdList();
            CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraIds[cameraId]);
            return characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
        } catch (CameraAccessException e) {
            // TODO handle
            return 0;
        }
    }
}

適切なAPIをロードする

さて、あなたの CameraOld または CameraNew クラスの場合、API レベルを確認する必要があります。 CameraNew はAPIレベル21からしか利用できないので、APIレベルを確認する必要があります。

依存性注入をすでに設定している場合、モジュール内で CameraSupport の実装を提供するときに、モジュール内でそうすることができます。例を挙げます。

@Module public class CameraModule {

    @Provides
    CameraSupport provideCameraSupport(){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            return new CameraNew(context);
        } else {
            return new CameraOld();
        }
    } 
}

DIを使用しない場合は、ユーティリティを作成するか、Factoryパターンを使用して適切なものを作成すればよいでしょう。重要なのは、APIレベルをチェックすることです。