raj*_*121 93 android android-hardware android-camera
if android.hardware.Camera is deprecated and you cannot use the variable Camera, then what would be the alternative to this?
小智 97
按照Android开发指南的android.hardware.Camera,他们陈述:
我们建议将新的android.hardware.camera2 API用于新的应用程序.
在关于android.hardware.camera2(上面链接)的信息页面上,陈述:
android.hardware.camera2包为连接到Android设备的各个相机设备提供接口.它取代了已弃用的Camera类.
当您检查该文档时,您会发现这两个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;
}
Run Code Online (Sandbox Code Playgroud)
与 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;
}
}
Run Code Online (Sandbox Code Playgroud)
这使得很难从一个切换到另一个并编写可以处理这两种实现的代码.
请注意,在这个单独的代码示例中,我已经不得不解决这样的事实:olde相机API使用int相机ID的基元,而新的相机ID则适用于String对象.对于这个例子,我通过在新API中使用int作为索引来快速修复它.如果返回的相机并不总是以相同的顺序,则这将导致问题.替代方法是使用String对象和旧int cameraIDs的String表示,这可能更安全.
现在要解决这个巨大的差异,您可以先实现一个接口,然后在代码中引用该接口.
在这里,我将列出该接口和2个实现的一些代码.您可以将实现限制为实际使用相机API以限制工作量.
在下一节中,我将快速解释如何加载一个或另一个.
包装所有你需要的界面,为了限制这个例子我这里只有2个方法.
public interface CameraSupport {
CameraSupport open(int cameraId);
int getOrientation(int cameraId);
}
Run Code Online (Sandbox Code Playgroud)
现在有一个老相机硬件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;
}
}
Run Code Online (Sandbox Code Playgroud)
另一个用于新硬件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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在要加载你的CameraOld或CameraNew类,你必须检查API级别,因为CameraNew只能从api级别21获得.
如果已经设置了依赖项注入,则可以在提供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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不使用DI,您可以只使用实用程序或使用工厂模式来创建正确的.重要的是检查API级别.
小智 6
面对同样的问题,通过不推荐的相机API支持旧设备,并且需要新的Camera2 API用于当前设备并进入未来; 我遇到了同样的问题 - 并没有找到连接2个API的第三方库,可能是因为它们非常不同,我转向基本的OOP主体.
这两个API明显不同,因此对于期望旧API中提供的接口的客户端对象来说,交换它们会产生问题.新API使用不同的体系结构,使用不同的方法构建不同的对象.得到了谷歌的爱,但ragnabbit!这令人沮丧.
因此,我创建了一个仅关注我的应用程序所需的相机功能的界面,并为实现该界面的两个 API 创建了一个简单的包装器.这样我的相机活动就不必关心它在哪个平台上运行......
我还设置了一个Singleton来管理API; 使用我的旧Android OS设备界面实现旧API的包装器,以及使用新API的新API的新API包装器类.单例具有获取API级别的典型代码,然后实例化正确的对象.
两个包装器类都使用相同的接口,因此无论App在Jellybean还是Marshmallow上运行都无关紧要 - 只要界面使用相同的方法签名为我的应用程序提供所需的Camera API; 对于新旧版本的Android,相机在应用程序中的运行方式相同.
Singleton还可以做一些与API无关的相关事情 - 比如检测设备上确实有摄像头,并保存到媒体库.
我希望这个想法可以帮助你.
| 归档时间: |
|
| 查看次数: |
99602 次 |
| 最近记录: |