Як використовувати API камери або camera2 для Android для підтримки старих і нових версій API без заміток на заставлення?


135

Новий API2 camera2 мене бентежить. Я хочу розробити додаток (для Android API 10 - 21), який використовує камеру пристрою. Як зазначено тут , я повинен використовувати API "Камера".

Однак, коли я намагаюся додати API "Camera" (android.hardware.Camera) до функції користувача маніфесту, він позначається як застарілий . З іншого боку, я не можу змінити його на API "camera2" (android.hardware.camera2), оскільки він сумісний лише з Android API 21+ (Android 5 - Lollipop). 2 посилання.

Я не тільки хочу, щоб мій додаток працював на старих версіях Android, але і на найновішій ...

Відповіді:


152

Незважаючи на те, що старий API камери позначений як устарений, він все ще є повністю функціональним і буде залишатися таким протягом довгого часу (оскільки майже всі програми, які використовують камери в Play Store, використовують його зараз).

Вам доведеться ігнорувати скарги Android Studio на те, що його застаріло, але якщо ви хочете підтримувати версії Android раніше 21 року, вам потрібно використовувати старий API.

На рівні 21 API ви, звичайно, можете використовувати новий API та його нові функції, але в даний час вам доведеться підтримувати повністю окремий потік у вашій програмі, якщо ви переходите між API. На жаль, два інтерфейси API мають досить різний світогляд, що важко написати бібліотеку підтримки, яка дозволила б використовувати щось на зразок нового API і на старих пристроях (де бібліотека відображається від нового API до старого API, якщо ні в API 21+).


1
Хороша відповідь. Тож якщо ви хочете підтримувати API рівня 16 і вище, краще дотримуватися старої камери зараз, правда?
Loolooii

5
тож єдиним способом є використання if оператора та android.os.Build.VERSION.SDK_INT для відокремлення коду?
хаді

Отже, для розробника, якщо ви орієнтуєтеся лише на API 21 і новіші версії, використовуйте Camera2, але якщо вам потрібна підтримка застарілого, використовуйте камеру? Або ви рекомендуєте виявити версії збірки та кодувати 2 різні методи за допомогою різних API?
john.weland

2
Це залежить від того, що робить ваша програма. Якщо функціональність камери є простою стрілковою стрілкою та ви хочете націлити старі API, просто скористайтеся старим API камери. Але якщо ви хочете зробити щось більше, ніж просто захопити JPEG та зробити попередній перегляд, або якщо ви просто орієнтуєтесь на нові API, займіться камерою2. У (жорсткій) середині знаходяться додатки, які хочуть запропонувати фантазійні додаткові функції на camera2, але також працюють і на старих пристроях. Там ви повинні побудувати два окремих кодових шляху, по одному для кожного API.
Едді Талвала

21
Оскарження API камери було помилкою, вони повинні були запровадити розширений API Camera (для розширених програм, таких як повноцінні програми для камери) - інакше (у більшості) програм, які використовують камеру лише для фотографування, доведеться підтримувати 2 apis. Google повинен був принаймні представити компактну бібліотеку (як завжди)
Sudara

38

Покладіть всі потрібні методи з камери в інтерфейс, а потім створіть такий екземпляр камери

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        Log.d(TAG, "camera2 selected");
        this.camera = new Camera2(getContext());
    } else {
        Log.d(TAG, "camera1 selected");
        this.camera = new Camera1(getContext());
    }

Таким чином у вас все розіб'ється, і це полегшить ваше життя.

Слово поради - життя з камерою2 не таке вже й велике. Вендери все ще виконують лайно, і тому вам доведеться додати багато умов і шляхів вирішення.

Приклад 1 - S6 повідомляє, що він не підтримує спалах :) Приклад 2 - Пристрій LG повідомляє про список підтримуваних розмірів зображень - однак далеко не всі вони підтримуються !!


14
Це правда. API Camera 2 насправді розділяє пристрої камери на три категорії: LEGACY, LIMITED та FULL. Якщо камеру класифікують як LEGACY, то всі виклики API2 camera2 переводяться в камеру1 під кришкою, тому це дійсно не варто турбуватися. Моя пропозиція - зателефонувати CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID); if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)... та вибрати старий API, якщо це правда.
панонскі

9

Для підтримки api, який ви хочете, скористайтеся наведеним нижче кодом. Просто визначте, чи відповідні назви відповідали рівню api. Наприклад, API 21 - це LOLLIPOP, а API 15 - ICE_CREAM_SANDWICH_MR1.

 if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)  
                                    && ((Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP))) {
           // your code here - is between 15-21

 } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
           // your code here - is api 21
 }

33
це навряд чи практично для повної реалізації камери. плюс, тепер вам доведеться підтримувати два кодові шляхи. перевірка версій має своє використання в розробці Android, але це не все.
катценхут

5
Що станеться, якщо користувач працює на Build.VERSION_CODES.LOLLIPOP_MR1? Або щось вище цього? Я думаю, що ваша друга перевірка повинна бути "інакше, якщо (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP)"
Ральф Піна

Шановні, як я можу створити те саме APK camera2 та старий api, якщо мої програми працюватимуть у 16 ​​та новіших api? Ароматизатори корисні для цієї роботи?
Матеус

Ви повинні реалізувати обидва apis. Просто зберігайте інтерфейс і два класи, де реалізована функціональність камери. Перш ніж створити один із екземплярів для запуску камери, зателефонуйте вищезгаданому методу, щоб він міг з’ясувати, до якого класу та функціональності звертатись
користувач0770

3

Хоча, що Google рекомендує використовувати Camera2 Api> = 21, але у вас можуть виникнути проблеми з налаштуваннями вручну.

Коли вам потрібно застосувати додаток для фотографування в режимі автоматичного налаштування, воно буде добре працювати. Але! Якщо вам потрібно створити додаток із реалізацією режиму ручного налаштування, для пристроїв, які мають API> = 21, по-перше, потрібно перевірити підтримуваний рівень рівня обладнання:

Виберіть камеру (передня, лицьова), отримайте її характеристики та перевірте РІВНІ ТЕХНІКИ

mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId)

val level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)

Характеристики камери представляють наступні підтримувані рівні: ОБМЕЖЕНИЙ, ПОВНИЙ, ЛЕГАЦІЯ, LEVEL_3, ВНІШНІЙ.

На високому рівні рівні:

Пристрої LEGACY працюють у режимі зворотної сумісності для старих пристроїв Android та мають дуже обмежені можливості.

Обмежені пристрої представляють базовий набір функцій, а також можуть включати додаткові можливості, які є підмножинами FULL.

Повні пристрої додатково підтримують кадрове ручне управління сенсором, спалахом, об'єктивами та налаштуваннями після обробки та зйомку зображення з високою швидкістю.

Пристрої LEVEL_3 додатково підтримують переробку YUV та захоплення зображення RAW разом з додатковими конфігураціями вихідного потоку.

Якщо ви отримали рівень підтримки LEGACY , вам слід використовувати стару камеру Api .



0

Підключення для читання Plz Підтримка версії камери Вони стверджують, що ....
Camera API1
Android 5.0 застарілий Camera API1, який продовжує припинятися, оскільки розробка нової платформи орієнтована на Camera API2. Однак період припинення роботи буде тривалим, і випуски Android продовжуватимуть підтримувати програми Camera API1 ще деякий час. Зокрема, підтримка продовжується:

  • Інтерфейси камери API1 для додатків. Додатки для камер, побудовані поверх API Camera API1, повинні працювати так само, як на пристроях, що працюють на попередніх версіях Android-версій.
  • Версії камери HAL Включає підтримку для камери HAL1.0.

  • -1

    Я з’ясував, що найкращим варіантом є створення двох видів діяльності. Використовуйте загальний спосіб перевірити наявність поточного API пристрою

    Intent i;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
        i = new Intent(context,camera2.class)
    } else {
        i = new Intent(context,camera.class);
    }
    startActivity(i);

    Таким чином, мені не доведеться багато плутанини, коли оглядаюсь код. Код легко змінювати, оскільки він відокремлений.

    Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
    Licensed under cc by-sa 3.0 with attribution required.