если android.hardware.Camera
устарело и вы не можете использовать переменную Camera
, то что может быть альтернативой этому?
Android-камера android.hardware.Camera устарела
Ответы (4)
Документация API
Согласно руководству для разработчиков Android для android.hardware.Camera
, они утверждают:
Мы рекомендуем использовать новый API android.hardware.camera2. для новых приложений.
На информационной странице о android.hardware.camera2
(ссылка выше) указано:
Пакет android.hardware.camera2 предоставляет интерфейс для отдельных камер, подключенных к устройству Android. Он заменяет устаревший класс 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 камеры работает с int
примитивами для идентификаторов камеры, а новый работает с String
объектами. В этом примере я быстро исправил это, используя int в качестве индекса в новом API. Если возвращаемые камеры не всегда в одном и том же порядке, это уже вызовет проблемы. Альтернативный подход заключается в работе со строковыми объектами и строковым представлением старых идентификаторов камеры int, что, вероятно, более безопасно.
Один далеко вокруг
Теперь, чтобы обойти эту огромную разницу, вы можете сначала реализовать интерфейс и ссылаться на этот интерфейс в своем коде.
Здесь я перечислю некоторый код для этого интерфейса и 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:
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
Теперь, чтобы загрузить класс 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();
}
}
}
Если вы не используете DI, вы можете просто создать утилиту или использовать шаблон Factory, чтобы создать правильный. Важной частью является то, что уровень API проверяется.
@SuppressWarnings
в этом QA в android"> stackoverflow.com/questions/7397996/
- person ; 10.02.2015
Столкнулись с той же проблемой, поддерживая старые устройства через устаревший API камеры и нуждаясь в новом API Camera2 как для текущих устройств, так и в будущем; Я столкнулся с теми же проблемами и не нашел стороннюю библиотеку, которая связывала бы два API, вероятно, потому, что они очень разные, я обратился к основным принципам ООП.
Два API заметно различаются, что затрудняет их замену для клиентских объектов, ожидающих интерфейсы, представленные в старом API. В новом API есть разные объекты с разными методами, построенные с использованием другой архитектуры. Есть любовь к Google, но сброд! это расстраивает.
Поэтому я создал интерфейс, ориентированный только на функции камеры, которые нужны моему приложению, и создал простую оболочку для обоих API, реализующих этот интерфейс. Таким образом, моя активность камеры не нужно заботиться о том, на какой платформе он работает...
Я также настроил Singleton для управления API; создание экземпляра оболочки старого API с моим интерфейсом для старых устройств с ОС Android и класса-оболочки нового API для более новых устройств, использующих новый API. Синглтон имеет типичный код для получения уровня API, а затем создает правильный объект.
Один и тот же интерфейс используется обоими классами-оболочками, поэтому не имеет значения, работает ли приложение на Jellybean или Marshmallow — до тех пор, пока интерфейс предоставляет моему приложению то, что ему нужно, из API камеры, использование тех же сигнатур метода; камера работает в приложении одинаково как для новых, так и для старых версий Android.
Синглтон также может выполнять некоторые связанные действия, не привязанные к API, например определять, что на устройстве действительно есть камера, и сохранять в медиатеку.
Надеюсь, идея вам поможет.
public interface AllCameraInterface { void open(); boolean setDirection(); Bitmap preview(); Bitmap takePhoto(); void close(); }
- person Robert Sherman; 16.06.2016
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(); } }
Затем метод, чтобы вернуть его...
- person Robert Sherman; 16.06.2016
camera2
? Я действительно запутался... Мне просто нужен метод enableAutofocus
, чтобы открыть камеру и установить ее фокус: stackoverflow.com/questions/19076316/
- person ; 13.06.2017
Теперь мы должны использовать 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, но по-прежнему могут не поддерживать API Camera2.
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;
}
Класс CameraManager в Camera2Api имеет метод для чтения характеристик камеры. Вы должны проверить, поддерживает ли аппаратное устройство Camera2 Api или нет.
Но есть и другие проблемы, которые нужно решить, если вы действительно хотите, чтобы это работало для серьезного приложения: например, опция автоматической прошивки может не работать для некоторых устройств, или уровень заряда батареи телефона может создать RuntimeException на камере, или телефон может вернуть недопустимый идентификатор камеры и т. д.
Поэтому лучший подход — иметь резервный механизм, поскольку по какой-то причине Camera2 не запускается, вы можете попробовать Camera1, и если это также не удается, вы можете позвонить в Android, чтобы открыть для вас камеру по умолчанию.
android.hardware.camera2
- person ozbek   schedule 21.01.2015