Android Camera Android.Hardware.Camera Deprecated

Android camera android.hardware.Camera deprecated

API Documentation

According to the Android developers guide for android.hardware.Camera, they state:

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

On the information page about android.hardware.camera2, (linked above), it is stated:

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

The problem

When you check that documentation you'll find that the implementation of these 2 Camera API's are very different.

For example getting camera orientation on android.hardware.camera

@Override
public int getOrientation(final int cameraId) {
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
return info.orientation;
}

Versus 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;
}
}

This makes it hard to switch from one to another and write code that can handle both implementations.

Note that in this single code example I already had to work around the fact that the olde camera API works with int primitives for camera IDs while the new one works with String objects. For this example I quickly fixed that by using the int as an index in the new API. If the camera's returned aren't always in the same order this will already cause issues. Alternative approach is to work with String objects and String representation of the old int cameraIDs which is probably safer.

One away around

Now to work around this huge difference you can implement an interface first and reference that interface in your code.

Here I'll list some code for that interface and the 2 implementations. You can limit the implementation to what you actually use of the camera API to limit the amount of work.

In the next section I'll quickly explain how to load one or another.

The interface wrapping all you need, to limit this example I only have 2 methods here.

public interface CameraSupport {
CameraSupport open(int cameraId);
int getOrientation(int cameraId);
}

Now have a class for the old camera hardware 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;
}
}

And another one for the new hardware 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;
}
}
}

Loading the proper API

Now to load either your CameraOld or CameraNew class you'll have to check the API level since CameraNew is only available from api level 21.

If you have dependency injection set up already you can do so in your module when providing the CameraSupport implementation. Example:

@Module public class CameraModule {

@Provides
CameraSupport provideCameraSupport(){
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
return new CameraNew(context);
} else {
return new CameraOld();
}
}
}

If you don't use DI you can just make a utility or use Factory pattern to create the proper one. Important part is that the API level is checked.

Android deprecated android.hardware.Camera and now recommend using android.hardware.camera2 but this is not available in anything below API 21

you would use

if(Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
//use old camera API
}else{
//use new camera API
}

then you can support what you want

android deprecated camera class

If you tried to run it in Android Marshmallow you need to ask for permission dynamically rather than just declaring the Camera permission in manifest.
Here's a list of permissions which need to be asked dynamically from marshmallow
http://developer.android.com/guide/topics/security/permissions.html#normal-dangerous

What is the alternative filter for deprecated android.hardware.camera.autofocus?

I know that the filter "android.hardware.camera.autofocus" is deprecated from sdk 21.

It has not been deprecated, at least according to the documentation and the documentation.

isn't there an alternative filter

You can use <uses-feature> for android.hardware.camera.autofocus, as it does not appear to be deprecated.

Torch / Flashlight app (android.hardware.camera is deprecated)

First, the deprecated android.hardware.Camera API still works fine, and if you need to support Android releases older than 5.0 Lollipop, you'll still need to use it.

The easiest option for the newest Android releases (Android Marshmallow or newer) is the new direct flashlight control: CameraManager.setTorchMode

It's very simple to use, and does not require the camera permission.

So I would recommend the following:

Pre-API 23, use the deprecated Camera API and your existing approach (don't forget to set a preview display as well, a dummy SurfaceTexture is simplest). You'll need the camera permission and runtime permission request handling.

API 23 or newer, use the setTorchMode call, and you don't even need to ask for any particular runtime permissions.

Google Developers won't let me use android.hardware.Camera or camera2

You added:

<uses-feature android:name="android.hardware.camera" />

But you'll also need:

<uses-permission android:name="android.permission.CAMERA" />

And maybe also:

<uses-feature android:name="android.hardware.camera.autofocus" />

Check https://developer.android.com/guide/topics/media/camera.html and https://developer.android.com/reference/android/hardware/Camera.html for all requirements

Where does android.hardware.camera2.full come from?

As always, it's best to look in Android source code itself:

* A given camera device may provide support at one of two levels: limited or
* full. If a device only supports the limited level, then Camera2 exposes a
* feature set that is roughly equivalent to the older
* {@link android.hardware.Camera Camera} API, although with a cleaner and more
* efficient interface. Devices that implement the full level of support
* provide substantially improved capabilities over the older camera
* API. Applications that target the limited level devices will run unchanged on
* the full-level devices; if your application requires a full-level device for
* proper operation, declare the "android.hardware.camera2.full" feature in your
* manifest.</p>

I hope that clarifies the nature of the feature you mentioned.

As for the camera2 apis - those were introduced in Android 5 (api level 21) as an attempt to create cleaner apis for interaction with the camera as opposed to the old camera api.



Related Topics



Leave a reply



Submit