Android.hardware.Camera
が非推奨であり、変数Camera
を使用できない場合、これに代わるものは何ですか?
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はカメラIDのint
プリミティブで動作し、新しいものはString
オブジェクトで動作するという事実を回避する必要があったことに注意してください。この例では、intを新しいAPIのインデックスとして使用することで、すぐに修正しました。カメラが返される順序が常に同じではない場合、これはすでに問題を引き起こしています。別のアプローチは、おそらくより安全なStringオブジェクトと古いint cameraIDのString表現を使用することです。
この大きな違いを回避するには、最初にインターフェイスを実装し、コードでそのインターフェイスを参照します。
ここでは、そのインターフェイスと2つの実装のコードをリストします。実装をカメラAPIの実際の使用に制限して、作業量を制限できます。
次のセクションでは、いずれかのロード方法を簡単に説明します。
必要なすべてをラップするインターフェイス。この例を制限するために、ここには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のもう1つ:
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;
}
}
}
CameraOld
またはCameraNew
クラスのいずれかを読み込むには、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レベルがチェックされることです。
同じ問題に直面、非推奨のカメラAPIを介して古いデバイスをサポートし、現在のデバイスと将来への移行の両方に新しいCamera2 APIを必要とします。私は同じ問題に遭遇しました-そして、notが2つのAPIを橋渡しするサードパーティのライブラリを見つけました。おそらくそれらは非常に異なるためです私は基本的なOOPになりました_プリンシパル。
2つのAPIは著しく異なるため、古いAPIで提示されたインターフェースを期待しているクライアントオブジェクトにとっては、それらの交換が問題になります。新しいAPIには、異なるアーキテクチャを使用して構築された異なるメソッドを持つ異なるオブジェクトがあります。 Googleが大好きになったが、ラグナビット!それはイライラします。
つまり、アプリが必要とするカメラ機能のみに焦点を当てたインターフェイスを作成し、bothそのインターフェイスを実装するAPIのシンプルなラッパーを作成しました。そのようにカメラのアクティビティはどのプラットフォームで実行されているかを気にする必要があります...
APIを管理するシングルトンも設定しました。古いAndroid OSデバイス用のインターフェースで古いAPIのラッパーをインスタンス化し、新しいAPIを使用して新しいデバイス用の新しいAPIのラッパークラスをインスタンス化します。シングルトンには、APIレベルを取得して正しいオブジェクトをインスタンス化するための典型的なコードがあります。
両方のラッパークラスで同じインターフェイスが使用されます。したがって、アプリがJellybeanとMarshmallowのどちらで実行されるかは関係ありません。インターフェイスがカメラAPIから必要なものをアプリに提供する限り、同じメソッドシグネチャを使用します。カメラは、Androidの新しいバージョンと古いバージョンの両方で同じ方法でアプリで実行されます。
Singletonは、APIに関連付けられていないいくつかの関連する処理も実行できます。たとえば、デバイス上に実際にカメラがあることを検出し、メディアライブラリに保存します。
このアイデアがお役に立てば幸いです。
Android.hardware.Cameraが非推奨になったため、Android.hardware.camera2を使用する必要があります。これは、API> 23 FlashLightでのみ動作します
public class MainActivity extends AppCompatActivity {
Button button;
Boolean light=true;
CameraDevice cameraDevice;
private CameraManager cameraManager;
private CameraCharacteristics cameraCharacteristics;
String cameraId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button=(Button)findViewById(R.id.button);
cameraManager = (CameraManager)
getSystemService(Context.CAMERA_SERVICE);
try {
cameraId = cameraManager.getCameraIdList()[0];
} catch (CameraAccessException e) {
e.printStackTrace();
}
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(light){
try {
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=false;}
else {
try {
cameraManager.setTorchMode(cameraId,false);
} catch (CameraAccessException e) {
e.printStackTrace();
}
light=true;
}
}
});
}
}
どのカメラAPIを使用するかについての回答は間違っています。それとも不十分だと言った方がいい。
一部の電話(Samsung Galaxy S6など)は、APIレベル21を超える可能性がありますが、Camera2 APIはまだサポートされていない場合があります。
CameraCharacteristics mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId);
Integer level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
if (level == null || level == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY) {
return false;
}
Camera2ApiのCameraManagerクラスには、カメラの特性を読み取るメソッドがあります。ハードウェアに関するデバイスがCamera2 Apiをサポートしているかどうかを確認する必要があります。
しかし、真剣なアプリケーションで本当に機能させたい場合は、さらに対処する必要がある問題があります。たとえば、自動フラッシュオプションが一部のデバイスで機能しない場合や、電話のバッテリーレベルがカメラでRuntimeExceptionを作成したり、電話が無効な値を返す場合がありますカメラIDなど.
最善の方法は、何らかの理由でCamera2の起動に失敗するフォールバックメカニズムを使用することです。Camera1を試すことができ、失敗した場合はAndroidを呼び出してデフォルトのカメラを開くことができます。