Bienvenidos sean a este post, hoy veremos como agregar la posibiidad de añadir fotos a nuestra app  por medio de la galeria o de la camara. Comencemos abriendo nuestra app MisLugares, si no la creaste te recomiendo este post,y luego vamos a la clase VistaLugar donde agregaremos los siguientes atributos:

Anuncios
private ImageViews imageview;
final static int RESULTADO_EDITAR = 1;
final static int RESULTADO_GALERIA = 1;
final static int RESULTADO_FOTO = 1;

Aca creamos un objeto para de la clase ImageVIew y tres constantes para nuestras siguientes modificaciones, ahora vamos a agregar el siguiente vinculo entre elemento del layout y nuestro codigo:

imageview = (ImageView) findViewById(R.id.foto);

Esta linea debe ir dentro del metodo onCreate() y encima del metodo actualizarVistas(), ahora deberemos agregar un nuevo metodo, por fuera de onCreate(), en la clase VistaLugar, veamos el metodo:

public void galeria(View view){
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("image/*");
    startActivityForResult(intent, RESULTADO_GALERIA);
}

Este metodo se encargara de darnos la posibilidad de poder cargar fotos desde la galeria del dispositivo, aca utilizaremos dos intenciones implicitas. La primera nos permitira conseguir contenido y la segunda la hara disponible para abrirla, en el siguiente caso el setType() seteara el tipo de imagen a utilizar, en este caso al usar un comodin nos permitira usar cualquiera y por ultimo ejecuta la actividad en base al constante enviado, esto es por medio del metodo startActivityForResult(), antes de modificar el metodo onActivityResult() para poder utilizar nuestro nuevo metodo vamos a crear el siguiente metodo:

protected void ponerFoto(ImageView imageview, String uri){
    if (uri != null) {
        imageview.setImageURI(Uri.parse(uri));
    } else {
        imageview.setImageBitmap(null);
    }
}

Este metodo se encargara de poner la foto seleccionada, en caso de existir una de lo contrario no hara nada, ahora si procedamos a modificar el metodo onActivityResult() de la siguiente forma:

if (requestCode==1234){
    actualizarVistas();
    findViewById(R.id.scrollView1).invalidate();
} else if(requestCode == RESULTADO_GALERIA
        && resultCode == Activity.RESULT_OK){
    lugar.setFoto(data.getDataString());
    ponerFoto(imageview, lugar.getFoto());
}
Anuncios

En este caso solo agregamos el bloque perteneciente al else if, donde verificara si requestCode es igual RESULTADO_GALERIA y la actividad devuelva un estado Ok para el valor resultCode, en caso afirmativo seteara la foto para el lugar y luego llamara al metodo creado anteriormente. Pasemos a hacer dos modificaciones mas para poder probar nuestra app, primero debemos ir a nuestro achivo vista_lugar.xml para modificar el siguiente elemento:

<ImageView
     android:layout_width="40dp"
     android:layout_height="40dp"
     android:contentDescription="@string/vista_galeria"
     android:src="@android:drawable/ic_menu_gallery"
     android:onClick="galeria" />

A este elemento le agregamos el listener onClick para poder escuchar el evento click y llamar al metodo galeria() ahora solo nos falta una modificacion mas para poder trabajar sin errores, para ello debemos ir al archivo AndroidManifest.xml y agregar la siguiente modificacion:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Esta linea nos permitira tener acceso a las dispositivos de almacenamiento externos, veamos como queda el codigo de nuestro archivo:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.example.mislugares">

    <application
         android:allowBackup="true"
         android:icon="@mipmap/ic_launcher"
         android:label="@string/app_name"
         android:roundIcon="@mipmap/ic_launcher_round"
         android:supportsRtl="true"
         android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category
                     android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity android:name=".AcercaDe"
             android:label="Acerca De..."
             android:theme="@android:style/Theme.Dialog" />
        <activity android:name=".VistaLugar"
             android:label="@string/menu_buscar" />
        <activity android:name=".EdicionLugar"
             android:label="Editar" />
    </application>
    <uses-permission
         android:name="android.permission.READ_EXTERNAL_STORAGE" />
</manifest>

Una vez realizada todas estas modificaciones solo nos falta una mas en la clase VistaLugar para actualizar nuestra nueva foto, para ello debemos agregar la siguiente linea en el metodo actualizarVistas():

ponerFoto(imageview, lugar.getFoto());

Con todas estas modificaciones realizadas veamos el codigo final de nuestra clase VistaLugar:

Anuncios
package org.example.mislugares;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.text.DateFormat;
import java.util.Date;

public class VistaLugar extends AppCompatActivity {
    private long id;
    private Lugar lugar;
    private ImageView imageview;
    final static int RESULTADO_EDITAR = 1;
    final static int RESULTADO_GALERIA = 1;
    final static int RESULTADO_FOTO = 1;

    @Override
    protected void onCreate(Bundle savedInstancestate){
        super.onCreate(savedInstancestate);
        setContentView(R.layout.vista_lugar);
        Bundle extras = getIntent().getExtras();
        id = extras.getLong("id", -1);
        lugar = Lugares.elemento((int) id);
        imageview = (ImageView) findViewById(R.id.foto);
        actualizarVistas();
    }

    public void actualizarVistas(){
        TextView nombre = (TextView) findViewById(R.id.nombre);
        nombre.setText(lugar.getNombre());
        ImageView logo_tipo = (ImageView) findViewById(R.id.logo_tipo);
        logo_tipo.setImageResource(lugar.getTipo().getRecurso());
        TextView tipo = (TextView) findViewById(R.id.tipo);
        tipo.setText(lugar.getTipo().getTexto());
        TextView direccion = (TextView) findViewById(R.id.direccion);
        direccion.setText(lugar.getDireccion());
        TextView telefono = (TextView) findViewById(R.id.telefono);
        telefono.setText(Integer.toString(lugar.getTelefono()));
        TextView url = (TextView) findViewById(R.id.url);
        url.setText(lugar.getUrl());
        TextView comentario = (TextView) findViewById(R.id.comentario);
        comentario.setText(lugar.getComentario());
        TextView fecha = (TextView) findViewById(R.id.fecha);
        fecha.setText(DateFormat.getDateInstance().format(
                new Date(lugar.getFecha())));
        TextView hora = (TextView) findViewById(R.id.hora);
        hora.setText(DateFormat.getTimeInstance().format(
                new Date(lugar.getFecha())));
        RatingBar valoracion=(RatingBar) findViewById(R.id.valoracion);
        valoracion.setRating(lugar.getValoracion());
        valoracion.setOnRatingBarChangeListener(
                new RatingBar.OnRatingBarChangeListener() {
                    @Override
                    public void onRatingChanged(RatingBar ratingBar,
                                         float valor, boolean fromUser) {
                        lugar.setValoracion(valor);
                    }
                }
        );
        ponerFoto(imageview, lugar.getFoto());
    }

    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.menu_vista_lugar, menu);
        return true;
    }

    public void lanzarBorrar(){
        new AlertDialog.Builder(this)
                .setTitle("Borrado de lugar")
                .setMessage("Estas seguro de querer eliminar este lugar?")
                .setPositiveButton("Ok",
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog,
                                        int cualBoton) {
                        Lugares.borrar((int) id);
                        finish();
                    }
                })
                .setNegativeButton("Cancelar", null)
                .show();
    }

    public void lanzarEditarLugar(View view){
        Intent i = new Intent(VistaLugar.this,
                EdicionLugar.class);
        i.putExtra("id", id);
        startActivityForResult(i,1234);
    }

    public void onActivityResult(int requestCode, int resultCode,
                                 Intent data){
        if (requestCode==1234){
            actualizarVistas();
            findViewById(R.id.scrollView1).invalidate();
        } else if(requestCode == RESULTADO_GALERIA
                && resultCode == Activity.RESULT_OK){
            lugar.setFoto(data.getDataString());
            ponerFoto(imageview, lugar.getFoto());
        }
    }

    public boolean onOptionsItemSelected(MenuItem item){
        switch(item.getItemId()){
            case R.id.accion_compartir:
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_TEXT,
                        lugar.getNombre()+ " - " + lugar.getUrl());
                startActivity(intent);
                return true;

            case R.id.accion_llegar:
                verMapa(null);
                return true;

            case R.id.accion_borrar:
                lanzarBorrar();
                return true;

            case R.id.accion_editar:
                lanzarEditarLugar(null);
                return true;

            default:
                return super.onOptionsItemSelected(item);

        }
    }

    public void verMapa(View view){
        Uri uri;
        double lat = lugar.getPosicion().getLatitud();
        double lon = lugar.getPosicion().getLongitud();
        if (lat != 0 || lon != 0) {
            uri = Uri.parse("geo:" + lat + "," + lon);
        } else {
            uri = Uri.parse("geo:0,0?q=" + lugar.getDireccion());
        }
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }

    public void llamadaTelefono(View view){
        startActivity(new Intent(Intent.ACTION_DIAL,
                Uri.parse("tel:" + lugar.getTelefono())));
    }

    public void paginaWeb(View view){
        startActivity(new Intent(Intent.ACTION_VIEW,
                Uri.parse(lugar.getUrl())));
    }

    public void galeria(View view){
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        startActivityForResult(intent, RESULTADO_GALERIA);
    }

    protected void ponerFoto(ImageView imageview, String uri){
        if (uri != null) {
            imageview.setImageURI(Uri.parse(uri));
        } else {
            imageview.setImageBitmap(null);
        }
    }
}

Ahora con todas nuestras modificaciones realizadas podemos probar nuestra app, como se ve en el siguiente video

Anuncios

Como pueden ver en el video ahora no tendremos una foto por defecto del lugar sino que se habilitara el boton para cargarlo desde la galeria de nuestro dispositivo, vamos a agregarle la posibilidad de poder agregarle una foto pero desde nuestra camara, para ello debenos volver a nuestra clase VistaLugar y agregaremos el siguiente objeto:

private Uri uriFoto;

Como antes ya creamos una constante para la camara ahora crearemos un metodo para poder usar la misma, veamos el metodo en cuestion:

public void tomarFoto(View view){
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    uriFoto = Uri.fromFile(new File(
            Environment.getExternalStorageDirectory() + File.separator
            + "img_" + (System.currentTimeMillis() / 1000) + ".jpg"));
    intent.putExtra(MediaStore.EXTRA_OUTPUT,uriFoto);
    startActivityForResult(intent,RESULTADO_FOTO);        
}

En este metodo utilizaremos una intencion para llamar a la camara, en la siguiente linea crearemos el archivo para guardar la foto y armaremos el nombre con img + la cantidad de tiempo en formato UNIX, es decir la cantidad de segundos transcurridos desde el 1ero de Enero de 1970 hasta la fecha y por ultimo la extension, este metodo nos permitira generar un nombre distinto para cada una de nuestras fotos, en nuestra siguiente linea enviaremos el nombre del archivo generado y por ultimo ejecutamos la actividad como en el caso anterior pero esta vez con la constante RESULTADO_FOTO. ahora solo nos falta una condicion en onActivityResult():

Anuncios
if (requestCode==1234){
    actualizarVistas();
    findViewById(R.id.scrollView1).invalidate();
} else if (requestCode == RESULTADO_FOTO
        && resultCode == Activity.RESULT_OK
        && lugar!=null && uriFoto!=null ){
    lugar.setFoto(uriFoto.toString());
    ponerFoto(imageview,lugar.getFoto());
} else if(requestCode == RESULTADO_GALERIA
        && resultCode == Activity.RESULT_OK){
    lugar.setFoto(data.getDataString());
    ponerFoto(imageview, lugar.getFoto());
}

Aca le diremos que si se cumple la condicion de que requestCode es RESULTADO_FOTO, resultCode es RESULT_OK, lugar es distinto de null y uriFoto tambien distinto de null, utilizara el metodo setFoto() para asignarle el valor almacenado en uriFoto y por ultimo utilizara el metodo ponerFoto() para asignarle la nueva foto, ahora solo nos falta una modificacion pero antes veamos el codigo final de VistaLugar:

package org.example.mislugares;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import android.widget.RatingBar;
import android.widget.TextView;

import org.w3c.dom.Text;

import java.io.File;
import java.text.DateFormat;
import java.util.Date;

public class VistaLugar extends AppCompatActivity {
    private long id;
    private Lugar lugar;
    private ImageView imageview;
    private Uri uriFoto;

    final static int RESULTADO_EDITAR = 1;
    final static int RESULTADO_GALERIA = 1;
    final static int RESULTADO_FOTO = 1;

    @Override
    protected void onCreate(Bundle savedInstancestate){
        super.onCreate(savedInstancestate);
        setContentView(R.layout.vista_lugar);
        Bundle extras = getIntent().getExtras();
        id = extras.getLong("id", -1);
        lugar = Lugares.elemento((int) id);
        imageview = (ImageView) findViewById(R.id.foto);
        actualizarVistas();
    }

    public void actualizarVistas(){
        TextView nombre = (TextView) findViewById(R.id.nombre);
        nombre.setText(lugar.getNombre());
        ImageView logo_tipo = (ImageView) findViewById(R.id.logo_tipo);
        logo_tipo.setImageResource(lugar.getTipo().getRecurso());
        TextView tipo = (TextView) findViewById(R.id.tipo);
        tipo.setText(lugar.getTipo().getTexto());
        TextView direccion = (TextView) findViewById(R.id.direccion);
        direccion.setText(lugar.getDireccion());
        TextView telefono = (TextView) findViewById(R.id.telefono);
        telefono.setText(Integer.toString(lugar.getTelefono()));
        TextView url = (TextView) findViewById(R.id.url);
        url.setText(lugar.getUrl());
        TextView comentario = (TextView) findViewById(R.id.comentario);
        comentario.setText(lugar.getComentario());
        TextView fecha = (TextView) findViewById(R.id.fecha);
        fecha.setText(DateFormat.getDateInstance().format(
                new Date(lugar.getFecha())));
        TextView hora = (TextView) findViewById(R.id.hora);
        hora.setText(DateFormat.getTimeInstance().format(
                new Date(lugar.getFecha())));
        RatingBar valoracion=(RatingBar) findViewById(R.id.valoracion);
        valoracion.setRating(lugar.getValoracion());
        valoracion.setOnRatingBarChangeListener(
                new RatingBar.OnRatingBarChangeListener() {
                    @Override
                    public void onRatingChanged(RatingBar ratingBar,
                                          float valor, boolean fromUser) {
                        lugar.setValoracion(valor);
                    }
                }
        );
        ponerFoto(imageview, lugar.getFoto());
    }

    public boolean onCreateOptionsMenu(Menu menu){
        getMenuInflater().inflate(R.menu.menu_vista_lugar, menu);
        return true;
    }

    public void lanzarBorrar(){
        new AlertDialog.Builder(this)
                .setTitle("Borrado de lugar")
                .setMessage("Estas seguro de querer eliminar este lugar?")
                .setPositiveButton("Ok",
                        new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog,
                                        int cualBoton) {
                        Lugares.borrar((int) id);
                        finish();
                    }
                })
                .setNegativeButton("Cancelar", null)
                .show();
    }

    public void lanzarEditarLugar(View view){
        Intent i = new Intent(VistaLugar.this,
                EdicionLugar.class);
        i.putExtra("id", id);
        startActivityForResult(i,1234);
    }

    public void onActivityResult(int requestCode, int resultCode,
                                 Intent data){
        if (requestCode==1234){
            actualizarVistas();
            findViewById(R.id.scrollView1).invalidate();
        } else if (requestCode == RESULTADO_FOTO
                && resultCode == Activity.RESULT_OK
                && lugar!=null && uriFoto!=null ){
            lugar.setFoto(uriFoto.toString());
            ponerFoto(imageview,lugar.getFoto());
        } else if(requestCode == RESULTADO_GALERIA
                && resultCode == Activity.RESULT_OK){
            lugar.setFoto(data.getDataString());
            ponerFoto(imageview, lugar.getFoto());
        }
    }

    public boolean onOptionsItemSelected(MenuItem item){
        switch(item.getItemId()){
            case R.id.accion_compartir:
                Intent intent = new Intent(Intent.ACTION_SEND);
                intent.setType("text/plain");
                intent.putExtra(Intent.EXTRA_TEXT,
                        lugar.getNombre()+ " - " + lugar.getUrl());
                startActivity(intent);
                return true;

            case R.id.accion_llegar:
                verMapa(null);
                return true;

            case R.id.accion_borrar:
                lanzarBorrar();
                return true;

            case R.id.accion_editar:
                lanzarEditarLugar(null);
                return true;

            default:
                return super.onOptionsItemSelected(item);

        }
    }

    public void verMapa(View view){
        Uri uri;
        double lat = lugar.getPosicion().getLatitud();
        double lon = lugar.getPosicion().getLongitud();
        if (lat != 0 || lon != 0) {
            uri = Uri.parse("geo:" + lat + "," + lon);
        } else {
            uri = Uri.parse("geo:0,0?q=" + lugar.getDireccion());
        }
        Intent intent = new Intent(Intent.ACTION_VIEW, uri);
        startActivity(intent);
    }

    public void llamadaTelefono(View view){
        startActivity(new Intent(Intent.ACTION_DIAL,
                Uri.parse("tel:" + lugar.getTelefono())));
    }

    public void paginaWeb(View view){
        startActivity(new Intent(Intent.ACTION_VIEW,
                Uri.parse(lugar.getUrl())));
    }

    public void galeria(View view){
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.setType("image/*");
        startActivityForResult(intent, RESULTADO_GALERIA);
    }

    protected void ponerFoto(ImageView imageview, String uri){
        if (uri != null) {
            imageview.setImageURI(Uri.parse(uri));
        } else {
            imageview.setImageBitmap(null);
        }
    }

    public void tomarFoto(View view){
        Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
        uriFoto = Uri.fromFile(new File(
                Environment.getExternalStorageDirectory() + File.separator
                + "img_" + (System.currentTimeMillis() / 1000) + ".jpg"));
        //uriFoto = Uri.fromFile(new File("/sdcard/prueba.jpg"));
        intent.putExtra(MediaStore.EXTRA_OUTPUT,uriFoto);
        startActivityForResult(intent,RESULTADO_FOTO);
    }
}

Nuestra ultima modificacion sera en el archivo vista_lugar.xml, donde agregaremos un listener para el evento click, veamos el elemento a modificar:

<ImageView
     android:layout_width="40dp"
     android:layout_height="40dp"
     android:contentDescription="@string/vista_camara"
     android:src="@android:drawable/ic_menu_camera"
     android:onClick="tomarFoto" />

Con esta modificacion realizada podremos probar nuevamente nuestra app, veamos el siguiente video

Como pueden ver en el video logramos llamar a la camara para poder utilizarla y asignarla como imagen del lugar seleccionado. Si lograron lo mismo que en el video, Felicitaciones!!! Hemos dado unos buenos pasos para conocer como es la manipulacion de algunos componentes en nuestro dispositivo movil.

Anuncios

En resumen, hoy hemos visto como añadir fotos, desde la galeria de nuestro dispositivo, desde la camara, como las intenciones y actividades nos facilitan estas tareas, algunas excepciones agregadas dentro del manifest para permitir a la app poder acceder a ciertos lugares y como trabaja el tiempo UNIX, espero les haya sido util, sigueme en Twitter, Facebook o Google+ para recibir una notificacion cada vez que subo un nuevo post en este blog, nos vemos en el proximo post.

Tambien podes donar

Es para mantenimiento del sitio, gracias!

$1.00