miércoles, 4 de diciembre de 2013

Tutorial Android: Utilizar el Intent de cámara para guardar y mostrar imagen en nuestra aplicación

Buenas tardes!
Hoy he hecho un tutorial para principiantes de cómo utilizar la cámara en nuestra aplicación android. La finalidad del tutorial es hacer la foto guardarla en la memoria del teléfono y a continuación mostrarla en la aplicación utilizando un ImageView.

Para empezar tendremos nuestro .xml con un botón que será el encargado de acceder a la cámara y un ImageView que será el encargado de mostrar la imagen una vez grabada. Este mismo proceso se puede hacer de muchas maneras, yo e intentado coger la más simple para que se entienda bien y se pueda practicar con ella.


Para empezar muestro como debe quedar el .xml:
<RelativeLayout 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"
    tools:context=".MainActivity" >

    <Button
        android:id="@+id/button1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="26dp"
        android:text="Hacer Foto" />

    <ImageView
        android:id="@+id/imageView1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button1"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="20dp"/>

</RelativeLayout>
con eso ya tendremos nuestra pantalla, ahora pasemos a ver nuestro .java totalmente comentado de una manera muy sencilla.
package com.tywors.photocolor;

import java.io.File;

import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

public class MainActivity extends Activity {
   //Necesitamos un Boton y un imageView
   private Button bt_hacerfoto;  
   private ImageView img; 
 
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      //Relacionamos con el XML
      img = (ImageView)this.findViewById(R.id.imageView1);
      bt_hacerfoto = (Button) this.findViewById(R.id.button1);
      //Añadimos el Listener Boton
      bt_hacerfoto.setOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick(View v) {
         //Creamos el Intent para llamar a la Camara
         Intent cameraIntent = new Intent(
            android.provider.MediaStore.ACTION_IMAGE_CAPTURE); 
         //Creamos una carpeta en la memeria del terminal
         File imagesFolder = new File(
            Environment.getExternalStorageDirectory(), "Tutorialeshtml5");
         imagesFolder.mkdirs();   
         //añadimos el nombre de la imagen
         File image = new File(imagesFolder, "foto.jpg"); 
         Uri uriSavedImage = Uri.fromFile(image);
         //Le decimos al Intent que queremos grabar la imagen
         cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
         //Lanzamos la aplicacion de la camara con retorno (forResult)
         startActivityForResult(cameraIntent, 1);
         }});
   }

   protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
         //Comprovamos que la foto se a realizado
         if (requestCode == 1 && resultCode == RESULT_OK) {  
  //Creamos un bitmap con la imagen recientemente 
         //almacenada en la memoria
            Bitmap bMap = BitmapFactory.decodeFile(
              Environment.getExternalStorageDirectory()+
                 "/Tutorialeshtml5/"+"foto.jpg");
            //Añadimos el bitmap al imageView para 
            //mostrarlo por pantalla
            img.setImageBitmap(bMap);        
 } 
    }
}
Para finalizar no hay que olvidarse de añadir este permiso de escritura en la memoria en nuestro manifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Adjunto el proyecto para descargar:


Muchas gracias a todos!
Espero vuestras dudas y comentarios!

30 comentarios:

  1. Interesante y muy útil sin duda alguna me servirá mucho

    ResponderEliminar
  2. Excelente Víctor, está claro y es muy cierto que cuando experimentas con más código, se avanza más!!, gracias nuevamente. Aprovecho en hacerte una consulta, estoy buscando un ejemplo en el que pueda convertir la imágen de la foto a otro color, es decir a color Sepia, pero con código nativo o NDK., de hecho hay que hacerlo en C, quizás tengas algún link donde puede estudiar el tema.
    Gracias!!

    ResponderEliminar
  3. Hola Víctor, te comento que al girar mi Tablet, veo que la foto tomada desaparece. Cómo se puede solucionar ello?

    ResponderEliminar
  4. Hola buen dia, una duda, hay alguna forma de tomar la foto sin que se abra la interfaz de la camara y se tenga que elegir guardar la foto? es decir dar click al boton "tomar foto" y que se muestre inmediatamente

    ResponderEliminar
  5. para que no se te desaparesca la imagen de la foto al girar la camara devesw de bloquear el sensor de el movil esto es muy facil y el codigo esta en internet solo es copiar y pegar y listo

    ResponderEliminar
  6. hola, como seria para que tome automaticamente la foto (sin que le de click en el boton sacar) y guardarlo automaticamente?

    ResponderEliminar
    Respuestas
    1. Sería através de un viewlayout, no des de intent como en este caso.
      En cuanto tenga tiempo pondré un tutorial sobre el view layout y la cámara de fotos

      Eliminar
    2. GRACIAS!!!!!! Victor, estare averiguando como hacerlo con un viewlayout. me sirvio de mucho el codigo que pusiste, me aclaro muchas dudas

      Eliminar
  7. Hola, oye amigo no logro encontrar la carpeta donde se guardan las fotos tomadas, busque directamente en la sd y nada, te agradecería y me ayudaras a saber como puedo sacar u obtener las fotos tomadas, de antema gracias, muy buen tuto XD

    ResponderEliminar
    Respuestas
    1. Si sigues este tutorial se guarda en el teléfono no en la SD, y dentro de una carpeta llamada tutorialeshtml5

      Eliminar
  8. me sale error en esto protected void onActivityResult(int requestCode, int resultCode, Intent data) void is an invalid type for the variable onActivityResult

    ResponderEliminar
    Respuestas
    1. Debe ser porque es:

      @Override
      protected void onActivityResult(int requestCode, int resultCode, Intent data){...}

      Eliminar
  9. Me llama la atencion que se utilice java cuando se supne deberia ser con html5 y herramientas locales no de java, como javascript o jquery mobile, hay algun otro tutorial que no sea con java????

    ResponderEliminar
  10. Hola. Buen tutorial.

    Podrías subir el proyecto nuevamente?

    Gracias de antemano.

    ResponderEliminar
    Respuestas
    1. so me puedes ayudar. Resulta que estoy haciendo una app para tomar fotos y videos cuando corro el codigo end in cl con carama funciona perfectamente, pero cuando lo corro en in cl sin camara me sale el tipico mensaje " Unfortunately the app has stopped" y por mas que le busco no we cual es el problems. Espero me puedas ayudar gracias

      Eliminar
  11. Tengo problemas con la visualización de la imagen en el ImageView, ya verifiqué y efectivamente guarda la foto pero al parecer la alta resolución de la foto no me permite visualizarla.

    ResponderEliminar
  12. Hola, me saca la foto y se me guarda en galeria perfectmente.
    Pero no me sale la foto en el Image View, ¿Qué puede ser?

    ResponderEliminar
  13. Me encanto el tutorial, me sirvió muchísimo :)

    ResponderEliminar
  14. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  15. Hola muchas gracias por el tutorial ya pude hacerlo funcionar, pero tengo una duda, como podría generar nuevos nombres de archivo, por ejemplo foto01, foto02, ya que se sobreescriben y luego buscarlos? existe alguna manera de hacerlo en android?

    y lo otro es limitar el tamaño de la imagen a 1mp 0 2 por defecto, es posible?

    ResponderEliminar
    Respuestas
    1. No se si te sirve todavia pero este metodo lo encontre en otro tutorial
      /**
      * Metodo privado que genera un codigo unico segun la hora y fecha del sistema
      * @return photoCode

      * */
      @SuppressLint("SimpleDateFormat")
      private String getCode()
      {
      SimpleDateFormat dateFormat = new SimpleDateFormat("yyyymmddhhmmss");
      String date = dateFormat.format(new Date() );
      String photoCode = "pic_" + date;
      return photoCode;
      }

      Eliminar
    2. Una consulta se le puede asignar un nombre como marca de agua a un imagenview y al guardarlo salga la foto con la marca de agua
      ..?
      Algún libro que recomienden .. !!
      Gracias de antemano.

      Eliminar
  16. Disculpa, quise descargar el proyecto, y resulta que el link está caido :(

    ResponderEliminar
  17. Hola ... quisiera saber que linea de codigo tengo q aregar si deseo poner un botton para que se almacene la imagen

    ResponderEliminar
  18. hola.....como guardar varias fotos???

    ResponderEliminar
    Respuestas
    1. guarda la imagen con diferente nombre (utiliza la hora actual);

      Eliminar
  19. cuando se inserta la foto en la imagen view esta rota horizontalmente ¿Como puedo evitar eso?

    ResponderEliminar