Intereting Posts
Как закрыть диалоговое окно в Android программно? EditText не показывает клавиатуру Функция запуска триггера при нажатии кнопки на Android Android-таймер? Как? Android – Apache Mime & httpClient Android zxing – предварительный просмотр камеры / просмотр поверхности растянут / искажен Изменить цвет текста кнопки при нажатии Установите максимальный уровень масштабирования в построителе LatLngBounds Как сделать QR-код для Android-рынка Android и магазина приложений Замена строки в AndroidManifest.xml для buildvariant не работает для версии Gradle Android Plugin> 0.5.4 Могут ли быть запущены и разработаны автономные части реактивно-родного пакета автономно? Как настроить Cordova-android 4.0 с белым списком Почему Android webview показывает «Далее» на клавиатуре, только если type = «number», а не с типом = «текст»? ListView с первым видимым элементом, имеющим разный макет Android скрывает / скрывает значок приложения программно

Android-камера android.hardware.Camera устарела

Если android.hardware.Camera устарела, и вы не можете использовать переменную Camera , то какова будет альтернатива этому?

Solutions Collecting From Web of "Android-камера android.hardware.Camera устарела"

Документация по API

Согласно руководству Android-разработчиков для android.hardware.Camera , они заявляют:

Мы рекомендуем использовать новый API android.hardware.camera2 для новых приложений.

На странице с информацией об android.hardware.camera2 (ссылка выше) указано:

Пакет android.hardware.camera2 предоставляет интерфейс для отдельных устройств камеры, подключенных к устройству Android. Он заменяет класс устаревших камер.

Проблема

Когда вы проверите эту документацию, вы обнаружите, что реализация этих двух API-интерфейсов камеры очень отличается.

Например, для ориентации камеры на 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; } } 

Это затрудняет переход от одного к другому и запись кода, который может обрабатывать обе реализации.

Обратите внимание, что в этом примере с одним кодом мне уже пришлось обойти тот факт, что API старой программы работает с int примитивами для идентификаторов камеры, а новый работает со String объектами. В этом примере я быстро исправил это, используя индекс int в новом API. Если возвращенная камера не всегда в том же порядке, это уже вызовет проблемы. Альтернативный подход заключается в работе с объектами 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:

 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 или CameraOld вам нужно будет проверить уровень API, поскольку CameraNew доступен только с 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, вы можете просто сделать утилиту или использовать шаблон Factory, чтобы создать правильный. Важная часть заключается в том, что проверяется уровень API.

Столкнувшись с той же проблемой , поддерживая устаревшие устройства через устаревший API-интерфейс камеры и нуждаясь в новом API Camera2 для обоих текущих устройств и перемещаясь в будущее; Я столкнулся с теми же проблемами – и не нашел стороннюю библиотеку, которая объединяет 2 API, вероятно, потому что они очень разные, я обратился к основным принципам ООП .

Два API-интерфейса заметно отличаются, что делает их проблемными для клиентских объектов, ожидая интерфейсов, представленных в старом API. Новый API имеет разные объекты с различными методами, построенными с использованием другой архитектуры. Получил любовь к Google, но ragnabbit! Это расстраивает.

Поэтому я создал интерфейс, ориентированный только на функциональность камеры, которую мне нужно для приложения, и создал простую оболочку для обоих API, которые реализуют этот интерфейс. Таким образом, моя активность камеры не должна заботиться о том, на какой платформе она работает …

Я также создал Singleton для управления API (-ами); Инсталляция старой оболочки API с моим интерфейсом для более старых устройств ОС Android и новый класс API-интерфейса для новых устройств с использованием нового API. Singleton имеет типичный код для получения уровня API, а затем экземпляр правильного объекта.

Тот же интерфейс используется обеими классами-оболочками , поэтому не имеет значения, работает ли приложение на Jellybean или Marshmallow – пока интерфейс предоставляет мое приложение тем, что ему нужно от любого API-камеры, используя те же сигнатуры методов; Камера работает в приложении так же, как для новых, так и для старых версий Android.

Синглтон также может делать некоторые связанные вещи, не привязанные к API-интерфейсам, – например, обнаружение на самом деле камеры на устройстве и сохранение в медиа-библиотеке.

Надеюсь, эта идея поможет вам.

Теперь мы должны использовать 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; } } }); } }