Android Камера android.аппаратура.Камера устарела
Если android.hardware.Camera
устарела, и вы не можете использовать переменную Camera
, тогда какова была бы альтернатива этому?
3 ответа:
документация API
по словам руководство для разработчиков Android на
android.hardware.Camera
, они заявляют:мы рекомендуем использовать новый тег android.аппаратура.camera2 API для новых приложений.
на странице информации о компании
android.hardware.camera2
, (ссылка выше), указано:андроид.аппаратура.пакет 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; }
и
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 olde camera работает с
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, вы можете просто сделать утилиту или использовать заводской шаблон для создания правильного. Важной частью является то, что уровень API проверяется.
столкнулся с той же проблемой, поддерживая старые устройства через устаревший API камеры и нуждаясь в новом API Camera2 как для текущих устройств, так и для перемещения в будущее; я столкнулся с теми же проблемами-и есть не нашел стороннюю библиотеку, которая соединяет 2 API, вероятно, потому, что они очень разные,Я обратился к основным принципам ООП.
2 API заметно отличаются, что делает их взаимозаменяемость проблематичной для клиента объекты, ожидающие интерфейсы, представленные в старом API. Новый API имеет различные объекты с различными методами, используя различные архитектуры. Получил любовь к Google, но ragnabbit! это расстраивает.
поэтому я создал интерфейс, фокусирующийся только на функциональности камеры, необходимой моему приложению, и создал простую оболочку для и API, который реализует этот интерфейс. таким образом, моя активность камеры не должна заботиться о том, какая платформа ее бежим дальше...
Я также настроил Синглтон для управления API(АМИ); создание экземпляра оболочки старого API с помощью моего интерфейса для старых устройств ОС Android и класса оболочки нового API для новых устройств с использованием нового API. Синглтон имеет типичный код для получения уровня API, а затем экземпляры правильного объекта.
один и тот же интерфейс используется обоими классами-оболочками, поэтому не имеет значения, работает ли приложение на Jellybean или Marshmallow-до тех пор, пока интерфейс предоставляет моему приложению то, что ему нужно от любого API камеры, используя те же сигнатуры метода; камера работает в приложении одинаково как для более новых, так и для более старых версий Android.
Синглтон также может делать некоторые связанные вещи, не связанные с API-интерфейсами-например, обнаруживать, что на устройстве действительно есть камера, и сохранять в медиатеку.
Я надеюсь, что идея поможет вам.
теперь мы должны использовать Android.аппаратура.camera2 как android.аппаратура.Камера устарела, которая будет работать только на API > 23 фонарик
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; } } }); } }