場合はandroid.hardware.Camera
廃止され、あなたは変数を使用することはできませんCamera
、そして、何がこれに代わるだろうか?
場合は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;
}
}
これにより、1つのスイッチから別のスイッチに切り替えたり、両方の実装を処理できるコードを記述したりすることが難しくなります。
この単一のコード例では、古いカメラAPI int
がカメラIDのプリミティブで動作する一方で、新しいカメラAPI がString
オブジェクトで動作するという事実を回避する必要があったことに注意してください。この例では、新しいAPIでインデックスとしてintを使用することで、それをすばやく修正しました。カメラが返される順序が常に同じとは限らない場合は、既に問題が発生しています。別のアプローチは、おそらく安全な古いint cameraIDのStringオブジェクトと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を使用しない場合は、ユーティリティを作成するか、ファクトリパターンを使用して適切なユーティリティを作成できます。重要な部分は、APIレベルがチェックされることです。
@SuppressWarnings
、このQAのでstackoverflow.com/questions/7397996/...
同じ問題に直面し、非推奨のカメラAPIを介して古いデバイスをサポートし、現在のデバイスと将来の両方のデバイスに新しいCamera2 APIが必要です。私は同じ問題に遭遇しました- おそらく2つのAPIを橋渡しするサードパーティのライブラリを見つけられませんでした。恐らく、APIが非常に異なるため、基本的なOOPプリンシパルに目を向けました。
2つのAPIは著しく異なっており、古いAPIで提供されているインターフェースを想定しているクライアントオブジェクトにとって、2つのAPIを交換すると問題が生じます。新しいAPIには、異なるアーキテクチャを使用して構築された、異なるメソッドを持つ異なるオブジェクトがあります。グーグルが大好きになりましたが、ラグナビット!それはイライラします。
そこで、アプリに必要なカメラ機能のみに焦点を当てたインターフェイスを作成し、そのインターフェイスを実装する両方の APIの単純なラッパーを作成しました。そうすれば、私のカメラアクティビティは、どのプラットフォームで実行されているかを気にする必要がなくなります...
また、APIを管理するためにシングルトンをセットアップしました。古いAPIのラッパーを古いAndroid OSデバイス用のインターフェースでインスタンス化し、新しいAPIのラッパークラスを新しいAPIを使用する新しいデバイス用にインスタンス化します。シングルトンには、APIレベルを取得して適切なオブジェクトをインスタンス化するための典型的なコードがあります。
両方のラッパークラスで同じインターフェイスが使用されるため、アプリがJellybeanとMarshmallowのどちらで実行されているかは関係ありません。インターフェイスが同じメソッドシグネチャを使用して、どちらかのCamera APIから必要なものをアプリに提供する限り、カメラは、Androidの新旧両方のバージョンで同じようにアプリで実行されます。
シングルトンは、APIに関連付けられていない関連することもいくつか実行できます。たとえば、デバイスに実際にカメラがあることを検出したり、メディアライブラリに保存したりできます。
このアイデアがお役に立てば幸いです。
public interface AllCameraInterface { void open(); boolean setDirection(); Bitmap preview(); Bitmap takePhoto(); void close(); }
public interface AllCameraInterface { void open(); Bitmap takePhoto(); void close(); etc... }
public class NCamera implements AllCameraInterface...
public class OCamera implements AllCameraInterface...
public class AllCamera { private static AllCamera ourInstance = new AllCamera(); public static AllCamera getInstance() {...} private AllCameraInterface camera; private AllCamera() { if (android.os.Build.VERSION.SDK_INT <= 20) { camera = new OCamera(); } else { camera = new NCamera(); } }
それを返すメソッド...
camera2
か?私は本当に混乱しています...私はちょうど必要とするenableAutofocus
:カメラを開き、フォーカスを設定する方法をstackoverflow.com/questions/19076316/...
次に、android.hardware.camera2を使用する必要があります。android.hardware.Cameraは非推奨であり、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を呼び出してデフォルトのカメラを開くことができます。
if ( getActivity().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
CameraManager cameraManager=(CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
try {
String cameraId = cameraManager.getCameraIdList()[0];
cameraManager.setTorchMode(cameraId,true);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
android.hardware.camera2