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
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(); } } } }