[解決済み] アンドロイドカメラ android.hardware.Camera 非推奨
質問
もし
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レベルをチェックすることです。
関連
-
[解決済み] Android getResources().getDrawable() 非推奨 API 22
-
[解決済み] Androidのソフトキーボードをプログラムで閉じる/隠すにはどうすればよいですか?
-
[解決済み] Androidでアクティビティ起動時にEditTextにフォーカスが当たらないようにする方法
-
[解決済み] インスタンス状態の保存を使用してアクティビティ状態を保存するにはどうすればよいですか?
-
[解決済み] Androidの「コンテキスト」とは何ですか?
-
[解決済み] Bitmapオブジェクトに画像を読み込む際にOutOfMemoryが発生する問題
-
[解決済み] AndroidでstartActivityForResultを管理する方法
-
[解決済み】Android UserManager.isUserAGoat()の正しい使用例?)
-
[解決済み] DialogFragmentを正しく終了させるには?
-
[解決済み] Android: xml リソースからの整数値
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] RecyclerView.Stateを使って、RecyclerViewのスクロール位置を保存するには?
-
[解決済み] アンドロイドフラグメント onRestoreInstanceState
-
[解決済み] Androidの連絡先リストを呼び出すには?
-
[解決済み] バイト配列の画像ファイルをビットマップに変換するには?
-
[解決済み] FloatingActionButtonのサンプルとサポートライブラリ
-
[解決済み] これはどういうことですか?失敗 [INSTALL_FAILED_CONTAINER_ERROR]?
-
[解決済み] フラグメント間の値の受け渡し方法
-
[解決済み] FragmentPagerAdapterのgetItemが呼び出されない
-
[解決済み] キャンバスに複数行のテキストを描画する
-
[解決済み] LayoutParamsの高さを密度に依存しないピクセル数でプログラム的に設定する。