gpt4 book ai didi

Android 相机 android.hardware.Camera 已弃用

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:04:04 27 4
gpt4 key购买 nike

如果 android.hardware.Camera 被弃用并且您不能使用变量 Camera,那么有什么替代方案?

最佳答案

API 文档

根据Android developers guide对于 android.hardware.Camera,他们声明:

We recommend using the new android.hardware.camera2 API for new applications.

在关于 android.hardware.camera2 的信息页面上,(链接在上面),声明:

The android.hardware.camera2 package provides an interface to individual camera devices connected to an Android device. It replaces the deprecated Camera class.

问题

当您查看该文档时,您会发现这两个 Camera 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 原语,而新相机 API 使用 String 对象。对于此示例,我通过使用 int 作为新 API 中的索引快速修复了该问题。如果相机的退回顺序不总是相同,这已经会导致问题。替代方法是使用 String 对象和旧 int cameraID 的 String 表示形式,这可能更安全。

一个客场

现在要解决这个巨大的差异,您可以先实现一个接口(interface)并在您的代码中引用该接口(interface)。

在这里,我将列出该接口(interface)的一些代码和 2 个实现。您可以将实现限制为您实际使用的相机 API,以限制工作量。

在下一节中,我将快速解释如何加载一个或另一个。

接口(interface)包装了所有你需要的,为了限制这个例子,我这​​里只有 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

现在要加载您的 CameraOldCameraNew 类,您必须检查 API 级别,因为 CameraNew 仅在 api 级别可用21.

如果您已经设置了依赖注入(inject),您可以在提供 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 级别。

关于Android 相机 android.hardware.Camera 已弃用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27086078/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com