studio picture intent getdata from example data android android-intent android-camera

android - picture - La cámara no funciona/se guarda cuando se usa Cache Uri como MediaStore.EXTRA_OUTPUT



onactivityresult camera android (3)

¿Por qué no guardarlo en un archivo nuevo?

final File root = new File(Environment.getExternalStorageDirectory() + File.separator + "MyDir" + File.separator); root.mkdirs(); final String fname = "img_"+ System.currentTimeMillis() + ".jpg"; final File sdImageMainDirectory = new File(root, fname); mImageUri = Uri.fromFile(sdImageMainDirectory);

Y luego pasar ese uri al intento.

cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri);

Estoy tratando de obtener la imagen completa después de tomar una foto de un Fragment .

Si uso el Uri del archivo ( Uri.fromFile(file) ), la cámara no saldrá después de tomar la foto y tocar el botón "ok" (parece que no se puede escribir al Uri o quién sabe qué) .

Usando la String File , en la forma de ''/data/data/com.package.bla/cache/img198346262jpg'' , no funciona tan bien (el archivo está ahí, pero está vacío porque la cámara no está guardando nada) .

Lo que intenté hasta ahora:

  • Eliminar el archivo después de crearlo, como lo hace este ejemplo . Sin embargo, el archivo no existe después de que la cámara sale.
  • Agregado permiso de almacenamiento externo LEER, por si acaso

Así que no tengo idea de por qué la imagen no se está guardando y ya se gastó / perdió mucho tiempo probando y pensando por qué no está funcionando.

Fragmento:

private void launchCamera() { Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); File outputDir = getActivity().getCacheDir(); File file = null; try { file = File.createTempFile("img", "jpg", outputDir); } catch (IOException e) { e.printStackTrace(); } if (file != null) { mImageUri = Uri.fromFile(file); //using Uri is not even exiting the camera //mImageUri = File.toString(); //If I use String instead of an Uri, it works better (ie, can accept camera photo) cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, mImageUri); startActivityForResult(cameraIntent, RESULT_TAKE_IMAGE); } } public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == Activity.RESULT_OK) { Bitmap original = BitmapFactory.decodeFile(mImageUri.toString(), bounds); } }

Código editado, mImageUri. Como expliqué, si uso Uri ni siquiera puedo aceptar la foto en la aplicación de la cámara. El uso de una cadena me permitirá aceptar la foto, aunque la foto no está realmente guardada (es decir, el archivo tiene 0 bytes en su interior).

EXPLICACIÓN : El problema estaba relacionado con guardar en el directorio de caché. Tal vez sea un error, me falta un permiso o la aplicación de la cámara simplemente no puede guardar en el directorio de datos privados de su aplicación. Agregar permiso FLAG_GRANT_WRITE_URI_PERMISSION no lo resolvió. Publicaciones relacionadas: Almacene la imagen de la cámara en el directorio de caché de la aplicación privada Y Guarde los datos de la cámara en la caché cuando se inicie a través de la intención

ACTUALIZACIÓN Desde Android 2.2 en adelante, se puede usar el método getExternalCacheDir() lugar de getCacheDir()


desde Android 26+ Uri.fromFile no funcionará, debes usar el proveedor de archivos en su lugar.

AndroidManifest.xml

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application ......... <provider android:name="android.support.v4.content.FileProvider" android:authorities="com.mydomain.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application>

res / xml / file_paths.xml

<?xml version="1.0" encoding="utf-8"?> <paths> <external-path name="external" path="." /> </paths>

finalmente

final Intent takeVideoIntent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE); // output file File path = new File(Environment.getExternalStorageDirectory(), "tmp.mp4"); // com.mydomain.fileprovider is authorities (manifest) // getUri from file Uri uri = FileProvider.getUriForFile(this, "com.mydomain.fileprovider", path); takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(takeVideoIntent, 99);

probado en Android 8.0 y 5.1.1

Actualización: en algunos dispositivos, la cámara incorporada no sería compatible con EXTRA_OUTPUT, por lo que si desea trabajar en todos los dispositivos, cree su propio módulo de cámara.


Intenta esto está trabajando a la perfección conmigo.

private String selectedImagePath = ""; final private int PICK_IMAGE = 1; final private int CAPTURE_IMAGE = 2; public Uri setImageUri() { // Store image in dcim File file = new File(Environment.getExternalStorageDirectory() + "/DCIM/", "image" + new Date().getTime() + ".png"); Uri imgUri = Uri.fromFile(file); this.imgPath = file.getAbsolutePath(); return imgUri; } public String getImagePath() { return imgPath; } btnGallery.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); startActivityForResult(Intent.createChooser(intent, ""), PICK_IMAGE); } }); btnCapture.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { final Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, setImageUri()); startActivityForResult(intent, CAPTURE_IMAGE); } }); @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (resultCode != Activity.RESULT_CANCELED) { if (requestCode == PICK_IMAGE) { selectedImagePath = getAbsolutePath(data.getData()); imgUser.setImageBitmap(decodeFile(selectedImagePath)); } else if (requestCode == CAPTURE_IMAGE) { selectedImagePath = getImagePath(); imgUser.setImageBitmap(decodeFile(selectedImagePath)); } else { super.onActivityResult(requestCode, resultCode, data); } } } public Bitmap decodeFile(String path) { try { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeFile(path, o); // The new size we want to scale to final int REQUIRED_SIZE = 70; // Find the correct scale value. It should be the power of 2. int scale = 1; while (o.outWidth / scale / 2 >= REQUIRED_SIZE && o.outHeight / scale / 2 >= REQUIRED_SIZE) scale *= 2; // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeFile(path, o2); } catch (Throwable e) { e.printStackTrace(); } return null; } public String getAbsolutePath(Uri uri) { String[] projection = { MediaColumns.DATA }; @SuppressWarnings("deprecation") Cursor cursor = managedQuery(uri, projection, null, null, null); if (cursor != null) { int column_index = cursor.getColumnIndexOrThrow(MediaColumns.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } else return null; }