---
author: eamanu
blogspot: true
date: Apr 24, 2017
tags: Old-Blog
title: "Integrar la c\xE1mara en una APP – Android"
---
# Integrar la cámara en una APP – Android
En esta entrada voy a explicar cómo se puede integrar la cámara de los dispositivos Android a una actividad. Esto quiere decir, que si tienes una app que necesita sacar una foto, no hace falta que hagas uso de otra app para tomar la foto, sino que ya viene incluida en la APP que estamos diseñando.
Android nos brinda una API para poder manejar la cámara, ya sea para tomar fotos o grabar un vídeo, y obtener las características de la misma. En esta entrada vamos a ver la clase Camera. Existe otra clase nueva, con mayores funcionalidades que es la Camera2, pero esta trabaja con versiones mayores a Android 5.0 (API 25).
El ejemplo que desarrollaré aquí, pertenece al código de la app Rescate Animal (Github:
``` ### Uso de características Le indicamos a Android que vamos a utilizar las características de la cámara ``` ``` Layout ### activity\_denuncia.xml ### fragment\_camera2.xml```version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/Denuncia" android:layout_width="match_parent" android:layout_height="match_parent" app:layout_behavior="@string/appbar_scrolling_view_behavior" android:background="#DFE0E2"> android:layout_height="wrap_content" android:id="@+id/bar" android:layout_width="match_parent" android:theme="@style/AppTheme.AppBarOverlay"> android:id="@+id/toolbar" android:layout_width="match_parent" android:layout_height="?attr/actionBarSize" android:background="#000818" app:popupTheme="@style/AppTheme.PopupOverlay" > android:layout_width="match_parent" android:layout_height="match_parent"> android:layout_width="100dp" android:layout_height="wrap_content" android:background="@drawable/selector" android:layout_alignParentRight="true" android:id="@+id/btnSiguiente" android:onClick="btnNext" android:gravity="end" android:textAlignment="textEnd" android:layout_marginTop="20dp" android:layout_marginRight="10dp" android:textSize="20dp"/> > > > android:layout_width="match_parent" android:layout_height="match_parent" android:layout_below="@+id/bar" android:layout_above="@+id/BtnMap"> android:layout_width="match_parent" android:layout_height="match_parent"> xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/container_pic" android:background="#000" tools:context="com.example.android.camera2basic.DenunciaActivity"/> > > > ```Accediendo a la cámara - Ahora pasamos a lo más importante. Para acceder a la clase Camera e instanciar la cámara debemos usar este sencillo código: ``````version="1.0" encoding="utf-8"?>
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent">android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/texture" android:layout_alignParentStart="true" android:layout_alignParentTop="true"/> android:layout_width="match_parent" android:layout_height="wrap_content" android:id="@+id/control" android:layout_alignParentBottom="true" android:layout_alignParentStart="true" android:layout_alignParentLeft="true" android:background="#fff"> android:id="@+id/BtnCamera" android:background="@drawable/ic_camera" android:layout_width="50dp" android:layout_height="50dp" android:layout_gravity="center"/> > > ``` ``` Vemos que primero creamos un objecto Camera llamado c, y utilizamos el método Camera.open(). CAMERA\_FACING\_BACK es un int que nos indica que queremos abrir la cámara trasera (Si queremos abrir la cámara frontal utilizamos CAMERA\_FACING\_FRONT). Lo ideal sería comprobar la cantidad de cámaras que existen con el método [Camera.getNumberOfCameras() ](https://developer.android.com/reference/android/hardware/Camera.html#getNumberOfCameras())para conocer si existe una cámara frontal o no. Creando una Preview - Otro paso importante, una vez que tengamos la cámara instanciada, es necesario mostrarla en un *SurfaceView*. Creamos una clase PreviewPic que extiende a ViewGroup e implementa un SurfaceHolder.Callback.
public static Camera getCameraInstance(){ Camera c = null; try { c = android.hardware.Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); // attempt to get a Camera instance } // Camera is not available (in use or does not exist) Log.e(TAG, "Error en la instanciación de la Cámara"); } return c; // returns null if camera is unavailable }Seteamos la cámara Necesitamos setear la cámara para se muestre correctamente en el SurfaceView. ``````public class PreviewPic extends ViewGroup implements SurfaceHolder.Callback { private final String TAG = "PreviewPic"; SurfaceView mSurfaceView; SurfaceHolder mHolder; Camera mCamera; Camera.Size mPreviewSize; List<Camera.Size> mSupportedPreviewSizes; PreviewPic(Context context, SurfaceView sv, Camera cam) { super(context); setCamera(cam); mSurfaceView = sv; //addView(mSurfaceView); // Install a SurfaceHolder.Callback so we get notified when the // underlying surface is created and destroyed. mHolder = mSurfaceView.getHolder(); mHolder.addCallback(this); mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); } // ... } `````` Implementamos los métodos del Surface.Callback - ```public void setCamera ( Camera camera ){ if (camera == null){return;} mCamera = camera; mSupportedPreviewSizes = mCamera.getParameters().getSupportedPreviewSizes(); requestLayout(); // get Camera params Camera.Parameters params = mCamera.getParameters(); List<String> focusMode = params.getSupportedFocusModes(); if(focusMode.contains(Camera.Parameters.FOCUS_MODE_AUTO)){ // set the focus mode params.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); //set Camera parameters mCamera.setParameters(params); }``` Cuando esto se implementa y se hace funcionar la imagen aparecerá rotada. Para arreglar esto en el método *surfaceChanged(…)* donde se encuentra el comentario es necesario aplicar el siguiente código: ```@Override public void surfaceCreated(SurfaceHolder holder) { try{ if (mCamera != null){ mCamera.setPreviewDisplay(holder); mCamera.startPreview(); } }catch (IOException e){ Log.e(TAG, "Exception caused by setPreviewDisplay()", e); } } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { if(mHolder.getSurface() == null){ //doesn't exist return; } try { mCamera.stopPreview(); }catch(Exception e){ Log.e(TAG, e.getMessage()); } if (mCamera != null){ Camera.Parameters params = mCamera.getParameters(); // Aqui debemos rotar la imagen o cambiar el tamaño requestLayout(); mCamera.setParameters(params); mCamera.startPreview(); } } @Override public void surfaceDestroyed(SurfaceHolder holder) { if (mCamera != null) mCamera.stopPreview(); }``` Esto hace que la imagen se rote, y se muestre correctamente. Conclusiones En este entrada se mostró de forma muy sencilla las partes importantes que el código debe contener a la hora de desarrollar una APP que incluya una cámara. Para ver el código completo lo pudes hacer desde el [github](https://github.com/eamanu/Rescate-Animal). Y te invito a contribuir en el código.Display display = ((WindowManager)getContext().getSystemService(WINDOW_SERVICE)).getDefaultDisplay(); if(display.getRotation() == Surface.ROTATION_0) { params.setPreviewSize(height, width); mCamera.setDisplayOrientation(90); } if(display.getRotation() == Surface.ROTATION_90) { params.setPreviewSize(width, height); } if(display.getRotation() == Surface.ROTATION_180) { params.setPreviewSize(height, width); } if(display.getRotation() == Surface.ROTATION_270) { params.setPreviewSize(width, height); mCamera.setDisplayOrientation(180); }