Cámara Android: la intención de datos devuelve nulo

Tengo una aplicación para Android que contiene múltiples actividades.

En uno de ellos estoy usando un botón que llamará a la cámara del dispositivo:

public void onClick(View view) { Intent photoIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(photoIntent, IMAGE_CAPTURE); } 

En la misma actividad, llamo al método OnActivityResult para el resultado de la imagen:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == IMAGE_CAPTURE) { if (resultCode == RESULT_OK) { Bitmap image = (Bitmap) data.getExtras().get("data"); ImageView imageview = (ImageView) findViewById(R.id.pic); imageview.setImageBitmap(image); } else if (resultCode == RESULT_CANCELED) { Toast.makeText(this, "CANCELED ", Toast.LENGTH_LONG).show(); } } } 

El problema es que los data intención son nulos y el método OnActivityResult se dirige directamente a (resultCode == RESULT_CANCELED) y la aplicación vuelve a la actividad anterior.

¿Cómo puedo solucionar este problema y, después de llamar a la cámara, la aplicación vuelve a la actividad actual que contiene un ImageView que contendrá la imagen tomada?

Gracias

La aplicación de cámara predeterminada de Android devuelve un bash no nulo solo al reenviar una miniatura en el Intento devuelto. Si pasa EXTRA_OUTPUT con un URI para escribir, devolverá un bash null y la imagen estará en el URI que pasó.

Puede verificar esto mirando el código fuente de la aplicación de la cámara en GitHub:

Supongo que está pasando EXTRA_OUTPUT alguna manera, o la aplicación de la cámara en su teléfono funciona de manera diferente.

Encontré una respuesta fácil. ¡¡funciona!!

o

 private void openCameraForResult(int requestCode){ Intent photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri uri = Uri.parse("file:///sdcard/photo.jpg"); photo.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, uri); startActivityForResult(photo,requestCode); } if (requestCode == CAMERA_REQUEST_CODE) { if (resultCode == Activity.RESULT_OK) { File file = new File(Environment.getExternalStorageDirectory().getPath(), "photo.jpg"); Uri uri = Uri.fromFile(file); Bitmap bitmap; try { bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri); bitmap = crupAndScale(bitmap, 300); // if you mind scaling pofileImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } 

si desea recortar y escalar esta imagen

 public static Bitmap crupAndScale (Bitmap source,int scale){ int factor = source.getHeight() <= source.getWidth() ? source.getHeight(): source.getWidth(); int longer = source.getHeight() >= source.getWidth() ? source.getHeight(): source.getWidth(); int x = source.getHeight() >= source.getWidth() ?0:(longer-factor)/2; int y = source.getHeight() <= source.getWidth() ?0:(longer-factor)/2; source = Bitmap.createBitmap(source, x, y, factor, factor); source = Bitmap.createScaledBitmap(source, scale, scale, false); return source; } 

Aplicación de cámara de trabajo simple que evita el problema de bash nulo

– todo el código modificado incluido en esta respuesta; cerca de tutorial de Android

Estuve pasando mucho tiempo sobre este tema, así que decidí crear una cuenta y compartir mis resultados contigo.

El tutorial oficial de Android “Taking Photos Simply” resultó no ser lo que prometía. El código provisto allí no funcionaba en mi dispositivo: un Samsung Galaxy S4 Mini GT-I9195 con Android 4.4.2 / KitKat / API Level 19.

Descubrí que el problema principal era la siguiente línea en el método invocado al capturar la foto ( dispatchTakePictureIntent en el tutorial):

 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI); 

Resultó en el bash subsecuentemente atrapado por onActivityResult siendo nulo.

Para resolver este problema, saqué mucha inspiración de las respuestas anteriores aquí y algunos mensajes útiles sobre github (sobre todo este de deepwinter , gracias a él, tal vez desee consultar su respuesta en una publicación estrechamente relacionada también).

Siguiendo estos agradables consejos, elegí la estrategia de eliminar la mencionada línea putExtra y hacer lo que correspondía para recuperar la imagen tomada de la cámara dentro del método onActivityResult (). Las líneas de código decisivas para recuperar el bitmap asociado con la imagen son:

  Uri uri = intent.getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); } catch (IOException e) { e.printStackTrace(); } 

Creé una aplicación ejemplar que solo tiene la capacidad de tomar una foto, guardarla en la tarjeta SD y mostrarla. Creo que esto podría ser útil para personas en la misma situación que yo cuando tropecé con este tema, ya que las sugerencias de ayuda actuales se refieren principalmente a publicaciones github bastante extensas que hacen lo que se pregunta pero no son demasiado fáciles de supervisar para novatos como yo. Con respecto al sistema de archivos que Android Studio crea por defecto al crear un nuevo proyecto, solo tuve que cambiar tres archivos para mi propósito:

activity_main.xml:

      

MainActivity.java:

 package com.example.android.simpleworkingcameraapp; import android.content.Intent; import android.graphics.Bitmap; import android.media.Image; import android.net.Uri; import android.os.Environment; import android.provider.MediaStore; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.ImageView; import android.widget.Toast; import java.io.File; import java.io.IOException; import java.text.SimpleDateFormat; import java.util.Date; public class MainActivity extends AppCompatActivity { private ImageView image; static final int REQUEST_TAKE_PHOTO = 1; String mCurrentPhotoPath; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); image = (ImageView) findViewById(R.id.image1); } // copied from the android development pages; just added a Toast to show the storage location private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES); File image = File.createTempFile( imageFileName, /* prefix */ ".jpg", /* suffix */ storageDir /* directory */ ); // Save a file: path for use with ACTION_VIEW intents mCurrentPhotoPath = image.getAbsolutePath(); Toast.makeText(this, mCurrentPhotoPath, Toast.LENGTH_LONG).show(); return image; } public void takePicAndDisplayIt(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager()) != null) { File file = null; try { file = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File } startActivityForResult(intent, REQUEST_TAKE_PHOTO); } } @Override protected void onActivityResult(int requestCode, int resultcode, Intent intent) { if (requestCode == REQUEST_TAKE_PHOTO && resultcode == RESULT_OK) { Uri uri = intent.getData(); Bitmap bitmap = null; try { bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), uri); } catch (IOException e) { e.printStackTrace(); } image.setImageBitmap(bitmap); } } } 

AndroidManifest.xml:

                 

Tenga en cuenta que la solución que encontré para el problema también condujo a una simplificación del archivo de manifiesto de Android: los cambios sugeridos por el tutorial de Android en términos de agregar un proveedor ya no son necesarios ya que no estoy utilizando ninguno en mi código de Java. Por lo tanto, solo unas pocas líneas estándar -sobre todo con respecto a los permisos- tuvieron que agregarse al archivo de manifiesto.

También podría ser valioso señalar que la autoimportación de Android Studio puede no ser capaz de manejar java.text.SimpleDateFormat y java.util.Date . Tuve que importarlos a ambos manualmente.

Probablemente porque tuviste algo como esto?

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); Uri fileUri = CommonUtilities.getTBCameraOutputMediaFileUri(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); startActivityForResult(takePictureIntent, 2); 

Sin embargo, no debe incluir el resultado adicional en la intención, ya que los datos entran en el URI en lugar de en la variable de datos. Por esa razón, debes tomar las dos líneas en el medio, para que tengas

 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePictureIntent, 2); 

Eso es lo que me causó el problema, espero que haya sido de ayuda.

El siguiente código funciona para mí:

 Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(cameraIntent, 2); 

Y aqui esta el resultado:

 protected void onActivityResult(int requestCode, int resultCode, Intent imageReturnedIntent) { super.onActivityResult(requestCode, resultCode, imageReturnedIntent); if(resultCode == RESULT_OK) { Uri selectedImage = imageReturnedIntent.getData(); ImageView photo = (ImageView) findViewById(R.id.add_contact_label_photo); Bitmap mBitmap = null; try { mBitmap = Media.getBitmap(this.getContentResolver(), selectedImage); } catch (IOException e) { e.printStackTrace(); } } } 

Para acceder a la cámara y tomar fotos y configurar ImageView en Android

Tienes que usar Uri file = Uri.fromFile(getOutputMediaFile()); para malvavisco.

Use el siguiente enlace para obtener la ruta

https://androidkennel.org/android-camera-access-tutorial/

He tenido este problema, la intent no es nula, pero la información enviada a través de este intent no se recibe en onActionActivit()

enter image description here

Esta es una mejor solución que usa getContentResolver () :

  private Uri imageUri; private ImageView myImageView; private Bitmap thumbnail; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ... ... ... myImageview = (ImageView) findViewById(R.id.pic); values = new ContentValues(); values.put(MediaStore.Images.Media.TITLE, "MyPicture"); values.put(MediaStore.Images.Media.DESCRIPTION, "Photo taken on " + System.currentTimeMillis()); imageUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); startActivityForResult(intent, PICTURE_RESULT); } 

onActivityResult() obtiene un bitmap almacenado por getContentResolver () :

  @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (requestCode == REQUEST_CODE_TAKE_PHOTO && resultCode == RESULT_OK) { Bitmap bitmap; try { bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), imageUri); myImageView.setImageBitmap(bitmap); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } } 

introducir la descripción de la imagen aquí introducir la descripción de la imagen aquí

Mira mi ejemplo en github:

https://github.com/Jorgesys/TakePicture

Cuando data.getdata() la imagen de la cámara en Android, Uri o data.getdata() vuelven nulos. Tenemos dos soluciones para resolver este problema.

  1. Recuperar la ruta de Uri desde la imagen de bitmap
  2. Recupere la ruta URI del cursor.

Esta es la forma de recuperar el Uri de la imagen de bitmap. La primera imagen de captura a través del Intento será la misma para ambos métodos:

 // Capture Image captureImg.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, reqcode); } } }); 

Ahora implementa OnActivityResult , que será el mismo para ambos métodos:

 @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==reqcode && resultCode==RESULT_OK) { Bitmap photo = (Bitmap) data.getExtras().get("data"); ImageView.setImageBitmap(photo); // CALL THIS METHOD TO GET THE URI FROM THE BITMAP Uri tempUri = getImageUri(getApplicationContext(), photo); // Show Uri path based on Image Toast.makeText(LiveImage.this,"Here "+ tempUri, Toast.LENGTH_LONG).show(); // Show Uri path based on Cursor Content Resolver Toast.makeText(this, "Real path for URI : "+getRealPathFromURI(tempUri), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(this, "Failed To Capture Image", Toast.LENGTH_SHORT).show(); } } 

Ahora crea todos los métodos anteriores para crear el Uri a partir de los métodos de Imagen y Cursor:

Ruta URI desde la imagen de bitmap:

 private Uri getImageUri(Context applicationContext, Bitmap photo) { ByteArrayOutputStream bytes = new ByteArrayOutputStream(); photo.compress(Bitmap.CompressFormat.JPEG, 100, bytes); String path = MediaStore.Images.Media.insertImage(LiveImage.this.getContentResolver(), photo, "Title", null); return Uri.parse(path); } 

Uri de la ruta real de la imagen guardada:

 public String getRealPathFromURI(Uri uri) { Cursor cursor = getContentResolver().query(uri, null, null, null, null); cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); return cursor.getString(idx); }