¿Cómo utilizar la cámara de Android o la API de camera2 para admitir versiones de API antiguas y nuevas sin notas de desaprobación?

135

La nueva API camera2 me confunde. Quiero desarrollar una aplicación (para las API de Android 10 - 21) que usa la cámara del dispositivo. Como se indicó aquí , debería usar la API "Cámara".

Sin embargo, cuando trato de agregar la API "Cámara" (android.hardware.Camera) a las características del usuario del manifiesto, se marca como obsoleto . Por otro lado, no puedo cambiarlo a la API "camera2" (android.hardware.camera2) ya que solo es compatible con Android API 21+ (Android 5 - Lollipop): también lo habría vinculado, pero solo puedo agregar 2 enlaces.

No solo quiero que mi aplicación se ejecute en versiones anteriores de Android, sino también la más nueva ...

Caramba
fuente

Respuestas:

152

Aunque la antigua API de la cámara está marcada como obsoleta, sigue siendo completamente funcional y lo seguirá siendo durante bastante tiempo (ya que casi todas las aplicaciones que usan la cámara en Play Store la usan actualmente).

Tendrá que ignorar las quejas de Android Studio sobre su desaprobación, pero si desea admitir versiones de Android anteriores a la 21, debe usar la API anterior.

En el nivel 21 de la API, ciertamente puede usar la nueva API y sus nuevas características, pero actualmente tendrá que mantener un flujo completamente separado en su aplicación si cambia entre las API. Desafortunadamente, las dos API tienen una visión del mundo lo suficientemente diferente que es difícil escribir una biblioteca de soporte que le permita usar algo como la nueva API en dispositivos más antiguos (donde la biblioteca se asigna de la nueva API a la antigua API si no en API 21+).

Eddy Talvala
fuente
1
Buena respuesta. Entonces, si desea admitir API de nivel 16 y superior, es mejor quedarse con la cámara vieja por ahora, ¿verdad?
Loolooii
55
Entonces, ¿la única forma es usar la instrucción if y android.os.Build.VERSION.SDK_INT para separar el código?
hadi
Entonces, para un desarrollador, si solo está apuntando a API 21 y posterior, use Camera2 pero si necesita soporte heredado, ¿usa Camera? ¿O recomendaría detectar versiones de compilación y codificar 2 métodos diferentes utilizando las diferentes API?
john.weland
2
Depende de lo que haga tu aplicación. Si la funcionalidad de la cámara es simple, apunta y dispara, y quieres apuntar a las API antiguas, solo usa la API de la cámara anterior. Pero si está buscando hacer algo más que simplemente tomar JPEG y dibujar una vista previa, o si solo está apuntando a nuevas API, vaya con camera2. En el medio (duro) hay aplicaciones que desean ofrecer características opcionales elegantes en la cámara2, pero también funcionan en dispositivos antiguos. Allí, debe crear dos rutas de código separadas, una para cada API.
Eddy Talvala
21
Depreciar la API de la cámara fue un error, deberían haber introducido una API avanzada de la cámara (para aplicaciones avanzadas como aplicaciones de cámara completas); de lo contrario (la mayoría) las aplicaciones que usan la cámara solo para tomar una fotografía tendrían que mantener 2 apis. Google debería haber introducido al menos una biblioteca compacta (como siempre)
Sudara
38

Coloque todos los métodos de la cámara que necesita en una interfaz y luego cree una instancia de cámara como esta

    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());
    }

De esta forma tendrás todo dividido y te hará la vida mucho más fácil.

Un consejo: la vida con camera2 no es tan genial. Los vendedores todavía hacen implementaciones de basura y, por lo tanto, tendrá que agregar muchas condiciones y soluciones alternativas.

Ejemplo 1: S6 informa que no es compatible con flash :) Ejemplo 2: un dispositivo LG informa una lista de tamaños de imagen admitidos; sin embargo, ¡no todos son compatibles!

slott
fuente
14
Esto es verdad. La API de cámara 2 en realidad divide los dispositivos de cámara en tres categorías: LEGADO, LIMITADO y COMPLETO. Si la cámara está clasificada como LEGACY, entonces todas las llamadas API de camera2 se están traduciendo en camera1 debajo del capó, por lo que realmente no vale la pena. Mi sugerencia es llamar CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID); if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)... y elegir la antigua API si es cierta.
panonski
9

Para admitir la API que desee, use el siguiente código. Simplemente determine los nombres apropiados correspondientes a los niveles de API. Por ejemplo, API 21 es LOLLIPOP y API 15 es 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
 }
usuario0770
fuente
33
Esto no es práctico para una implementación de cámara completa. Además, ahora tienes que mantener dos rutas de código. la verificación de versión tiene su uso en el desarrollo de Android, pero no es así.
Katzenhut
55
¿Qué sucede si un usuario ejecuta Build.VERSION_CODES.LOLLIPOP_MR1? O algo por encima de eso? Creo que su segunda verificación debería ser "else if (Build.VERSION.SDK_INT> = Build.VERSION_CODES.LOLLIPOP)"
Ralph Pina
Queridos, ¿cómo puedo construir en la misma cámara apk2 y la API anterior si mis aplicaciones deberían funcionar en la API 16 y posteriores? ¿Sabores es bueno para este trabajo?
Mateus
Tienes que implementar ambas apis. Simplemente mantenga una interfaz y dos clases, donde se implementa la funcionalidad de la cámara. Antes de crear una de las instancias para ejecutar la cámara, llame al método mencionado anteriormente, para que pueda averiguar a qué clase y funcionalidad llamar
user0770
3

Aunque, lo que Google recomienda usar Camera2 Api> = 21, pero podría tener problemas con la configuración manual.

Cuando necesite implementar la aplicación para tomar fotos con el Modo de configuración automática, funcionará bien. ¡Pero! Si necesita crear una aplicación con la implementación del Modo de configuración manual, para dispositivos que tienen API> = 21, en primer lugar, necesita verificar el NIVEL DE HARDWARE compatible:

Seleccione la cámara (frontal, frontal), obtenga las características y compruebe el NIVEL DE HARDWARE.

mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId)

val level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)

Las características de la cámara representan los siguientes niveles admitidos: LIMITADO, COMPLETO, LEGADO, NIVEL_3, EXTERNO.

En un nivel alto, los niveles son:

Los dispositivos LEGACY funcionan en un modo de compatibilidad con versiones anteriores para dispositivos Android más antiguos y tienen capacidades muy limitadas.

Los dispositivos LIMITADOS representan el conjunto de características de línea de base y también pueden incluir capacidades adicionales que son subconjuntos de FULL.

Los dispositivos COMPLETOS también admiten el control manual por cuadro de la configuración del sensor, flash, lente y posprocesamiento, y la captura de imágenes a alta velocidad.

Los dispositivos LEVEL_3 también admiten el reprocesamiento YUV y la captura de imágenes RAW, junto con configuraciones de flujo de salida adicionales.

Si obtuviste el nivel de soporte de LEGACY , debes usar la antigua Camera Api .

Serj
fuente
1

Usa la anotación de soporte

    @TargetApi(21)

para evitar comprobar

Prudhvi Raj Kumar
fuente
1
¡Entonces no es compatible con los dispositivos Android antes del 21!
Mina F. Beshay
0

Por favor, lea el enlace Soporte de la versión de la cámara. Dicen que ...
Camera API1
Android 5.0 desaprobó la Camera API1, que continúa siendo eliminada a medida que el desarrollo de la nueva plataforma se centra en Camera API2. Sin embargo, el período de eliminación será prolongado, y las versiones de Android continuarán admitiendo aplicaciones Camera API1 durante algún tiempo. Específicamente, el soporte continúa para:

  • Interfaces de cámara API1 para aplicaciones. Las aplicaciones de cámara creadas sobre Camera API1 deberían funcionar como lo hacen en dispositivos que ejecutan versiones anteriores de Android.
  • Versiones de cámara HAL. Incluye soporte para la cámara HAL1.0.
  • rajesh780
    fuente
    -1

    Descubrí que la mejor opción es crear dos actividades. Use la forma general de verificar la API del dispositivo actual

    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);
    

    De esta manera no tengo que tener mucha confusión cuando miro hacia atrás el código. El código es fácil de modificar ya que se separó.

    teck wei
    fuente