--- 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: ). Lo que haremos será, primero tener una actividad (activity\_denuncia.xml) que tendrá incrustada un fragment (fragment\_camera2.xml). Ademas de esto tendremos, una clase *DenunciaActivity.java* que controla a *activity\_denuncia.xml* y una *CameraFragment.java* que controla a *fragment\_camera2.xml*. Manifest -- Lo primero que debemos realizar es agregar los permisos necesarios en el AndroidManifest.xml ### Permiso de la cámara Le indicamos a Android que vamos a utilizar la cámara ```

```

### Uso de características

Le indicamos a Android que vamos a utilizar las características de la cámara

```

```

Layout




### activity\_denuncia.xml

[Source code](#codesyntax_13 "Click to show/hide code block")[![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/code.png)](#codesyntax_13 "Show code only") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png)](#codesyntax_13 "Print code") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif)](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/About.html "Show plugin information")
```
 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"/>
        >
    >
>
```

### fragment\_camera2.xml
[Source code](#codesyntax_14 "Click to show/hide code block")[![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/code.png)](#codesyntax_14 "Show code only") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png)](#codesyntax_14 "Print code") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif)](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/About.html "Show plugin information")
```
 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"/>
 
    >
 
>
```

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: ```
  1. public static Camera getCameraInstance(){
  2. Camera c = null;
  3.  
  4. try {
  5. c = android.hardware.Camera.open(Camera.CameraInfo.CAMERA_FACING_BACK); // attempt to get a Camera instance
  6. }
  7. catch (Exception e){
  8. // Camera is not available (in use or does not exist)
  9. Log.e(TAG, "Error en la instanciación de la Cámara");
  10. }
  11. return c; // returns null if camera is unavailable
  12. }
``` 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.
[Source code](#codesyntax_16 "Click to show/hide code block")[![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/code.png)](#codesyntax_16 "Show code only") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/printer.png)](#codesyntax_16 "Print code") [![](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/themes/default/images/info.gif)](https://eamanu.com/blog/wp-content/plugins/wp-synhighlight/About.html "Show plugin information")
```
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);
 
 
    }
    // ...
}
```

Seteamos la cámara Necesitamos setear la cámara para se muestre correctamente en el SurfaceView. ```
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);
    }
``` Implementamos los métodos del Surface.Callback - ```
@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();
}
``` 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: ```
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);
}
``` 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.