Tomar foto en android

Generalmente vamos a necesitar Tomar foto en android para nuestras apps , actualmente lo uso para tomar foto de perfil al usuario, y muchas veces hay que pedir permisos especiales para tomar una foto.

pues hoy traigo un pequeño codigo que nos tomara una foto sin pedir permisos especiales en  la app

Tomar foto de forma sencilla

primero que debemos hacer es poner en nuestro manifest el siguiente código

<uses-feature
    android:name="android.hardware.camera"
    android:required="true" />

Esto activa la cámara de modo que no pedirá permisos especiales al usuario

por ejemplo yo tengo en mi vista lo siguiente:

<ImageView
    android:id="@+id/imgPhotoUser"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:clickable="true"
    app:srcCompat="@drawable/ic_ic_rg_add_photo"
    tools:layout_editor_absoluteX="307dp"
    tools:layout_editor_absoluteY="8dp" />

que es una imagen de una cámara y le doy a la propiedad al imageview el método de click =  android:clickable=”true”

en mi clase java , asocio mi imagen y le doy el evento onClick

ImageView addPhoto = (ImageView) findViewById(R.id.imgPhotoUser);
addPhoto.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        //codigo
    }
});

Dentro vamos a hacer un Intent, la cual llamará a la acción de capturar una imagen y si todo va bien vamos a visualizarlo en nuesto ImageView

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
    startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}

startActivityForResult es un método de android que es llamado cuando el intent trae algo para mostrar, así que pasamos el intent y request image que es una variable static en 1, esta variable es una respuesta de correcto.

lo siguiente es pasar la foto que va anexado en un extras de data , data es el intent que enviamos anteriormente, y luego lo compertimos en bitmap para poder mostrarlo en nuesta pantalla

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bundle extras = data.getExtras();
        Bitmap imageBitmap = (Bitmap) extras.get("data");
        addPhoto.setImageBitmap(imageBitmap);
    }
}

Codigo Completo:

ImageView addPhoto = (ImageView) findViewById(R.id.imgPhotoUser);
addPhoto.setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
 if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
 startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
 }

 }
 });
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
 Bundle extras = data.getExtras();
 Bitmap imageBitmap = (Bitmap) extras.get("data");
 addPhoto.setImageBitmap(imageBitmap);
 }
}

 

Elegir entre tomar foto en android o elegir de la galería

ahora si buscan el menú donde les dice que app quieren abrir como la siguiente imagen

Elegir entre tomar foto en android o galeria

Se hace insertando dos Intent y creando una propiedad que se llama createChooser, esta es una propiedad nativa de intent, este lo que hace es hacer un nuevo intent pero del tipo Chooser  y podremos poner las app que queremos abrir.

Creamos un lista de Intent y definimos el intent de la cámara que vimos anteriormente:

final List<Intent> cameraIntents = new ArrayList<Intent>();
final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);

usaremos PackageManager que es una clase para recuperar diversos tipos de información relacionada con los paquetes de aplicaciones que están actualmente instalados en el dispositivo. Puedes encontrar esta clase a través de getPackageManager().

final PackageManager packageManager = getPackageManager();
final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
for(ResolveInfo res : listCam) {
    final String packageName = res.activityInfo.packageName;
    final Intent intent = new Intent(captureIntent);
    intent.setComponent(new ComponentName(packageName, res.activityInfo.name));
    intent.setPackage(packageName);
    cameraIntents.add(intent);
}

hasta aca, es para la cámara, este codigo es para abrir la galeria (contenido de tipo fotos)

Intent galleryIntent = new Intent();
galleryIntent.setType("image/*");
galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

ahora vamos a hacer el chooser, y agregaremos con un put extra nuestro intent de la cámara y al final iniciamos el startActivityForResult

Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));

startActivityForResult(chooserIntent, REQUEST_IMAGE_CAPTURE);

Saber si elegiste Tomar una foto en android o abrir galería

Aquí sí que me rompí la cabeza  ya que no puedes pasar un putExtra, ni usar una variable, como no encontraba la solución (no sabia ni como buscar), hice un debug y me encontré con lo siguiente.

Si seleccionamos tomar una foto, esta trae un un valor(putExtra) del tipo “data”, a diferencia de la galería, esta no trae nada en el extra si no que trae un dato (Uri) que encontramos en getData, así podemos saber que vamos a hacer.

un extra añadido, es que las imágenes que traes de galería son 1:1 y tenemos que hacer un escalado por bitmap.

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

            if (data.getExtras()!= null) {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                addPhoto.setImageBitmap(imageBitmap);
            } else {
                Uri selectedimg = data.getData();
                try {
                    Bitmap mBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedimg);
                    int width = mBitmap.getWidth();
                    int height = mBitmap.getHeight();
                    float scaleWidth = ((float) 300) / width;
                    float scaleHeight = ((float) 400) / height;
                    Matrix matrix = new Matrix();
                    matrix.postScale(scaleWidth, scaleHeight);
                    Bitmap bit = Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, false);
                    addPhoto.setImageBitmap(bit);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

    }

}

 

codigo completo a continuación

ImageView addPhoto;

addPhoto = (ImageView) findViewById(R.id.imgPhotoUser);

addPhoto.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v) {
        final List<Intent> cameraIntents = new ArrayList<Intent>();
        final Intent captureIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        final PackageManager packageManager = getPackageManager();
        final List<ResolveInfo> listCam = packageManager.queryIntentActivities(captureIntent, 0);
        for(ResolveInfo res : listCam) {
            final String packageName = res.activityInfo.packageName;
            final Intent intent = new Intent(captureIntent);
            intent.setComponent(new ComponentName(packageName, res.activityInfo.name));
            intent.setPackage(packageName);
            cameraIntents.add(intent);
        }

        Intent galleryIntent = new Intent();
        galleryIntent.setType("image/*");
        galleryIntent.setAction(Intent.ACTION_GET_CONTENT);

        Intent chooserIntent = Intent.createChooser(galleryIntent, "Select Source");
        chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, cameraIntents.toArray(new Parcelable[cameraIntents.size()]));

        startActivityForResult(chooserIntent, REQUEST_IMAGE_CAPTURE);


    }
});

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

            if (data.getExtras()!= null) {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                addPhoto.setImageBitmap(imageBitmap);
            } else {
                Uri selectedimg = data.getData();
                try {
                    Bitmap mBitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedimg);
                    int width = mBitmap.getWidth();
                    int height = mBitmap.getHeight();
                    float scaleWidth = ((float) 300) / width;
                    float scaleHeight = ((float) 400) / height;
                    // create a matrix for the manipulation
                    Matrix matrix = new Matrix();
                    // resize the bit map
                    matrix.postScale(scaleWidth, scaleHeight);
                    // recreate the new Bitmap
                    Bitmap bit = Bitmap.createBitmap(mBitmap, 0, 0, width, height, matrix, false);
                    addPhoto.setImageBitmap(bit);
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

    }

}

 

por Cesar Flores

Programador de tiempo completo, Gamer de medio tiempo y fotógrafo ocasionalmente, me gusta el front-end y mi framework favorito es angular aunque no por eso le hago el feo a un nuevo lenguaje.

Deja un comentario

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.