Android: tomar fotos y guardarlas con un nombre personalizado en un destino personalizado mediante Intent

Tengo un programa que abre la cámara a través de intención de tomar una foto. Esa parte funciona bien ya. Sin embargo, quiero guardar en una carpeta determinada con un nombre de archivo determinado (el nombre del archivo es opcional, pero realmente lo ayudaría).

Así que esto es lo que tengo hasta ahora.

Esta es la línea de código que abre la cámara:

//TODO camera stuff. Intent openCam = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //The two lines of code below were commented out at first. //They were eventually added when I tried to save it with a custom name and destination fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE); // create a file to save the image openCam.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the image file name startActivityForResult(openCam, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); 

El manejador de resultados va aquí:

 //TODO handle result if (requestCode == CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE) { if (resultCode == RESULT_OK) { // Image captured and saved to fileUri specified in the Intent Toast.makeText(this, "Image saved to:\n" + data.getData(), Toast.LENGTH_LONG).show(); System.out.println("I am here"); } else if (resultCode == RESULT_CANCELED) { // User cancelled the image capture } else { // Image capture failed, advise user } } 

Antes de implementar los dos métodos a continuación, el código funcionaba correctamente. Sin embargo, se guardó en la carpeta predeterminada con el nombre de archivo predeterminado (la versión de marca de tiempo). La tostada mostrada "Imaged saved to: null" ya que no he configurado esa parte todavía.

Así que aquí están los métodos que se suponía que manejar el nombre de archivo personalizado y el destino

 /** Create a file Uri for saving an image or video */ private static Uri getOutputMediaFileUri(int type){ return Uri.fromFile(getOutputMediaFile(type)); } /** Create a File for saving an image or video */ private static File getOutputMediaFile(int type){ // To be safe, you should check that the SDCard is mounted // using Environment.getExternalStorageState() before doing this. Environment.getExternalStorageState(); File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES), "MyCameraApp"); // This location works best if you want the created images to be shared // between applications and persist after your app has been uninstalled. // Create the storage directory if it does not exist if (! mediaStorageDir.exists()){ if (! mediaStorageDir.mkdirs()){ Log.d("MyCameraApp", "failed to create directory"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File mediaFile; if (type == MEDIA_TYPE_IMAGE){ mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_"+ timeStamp + ".jpg"); } else { return null; } return mediaFile; } 

* Estos códigos fueron eliminados de la Guía de cámaras de developer.android.com.

El código anterior logra abrir la cámara y tomar fotos y guardarlas. Sin embargo, el problema se produce cuando el usuario decide dejar de tomar fotos y presione la tecla de retroceso. Lo que ocurre es que la aplicación se cierra cerrando dando este error:

 10-21 12:44:33.699: E/AndroidRuntime(13016): FATAL EXCEPTION: main 10-21 12:44:33.699: E/AndroidRuntime(13016): java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=100, result=-1, data=null} to activity {com.AIC.QRCodeScanner/com.AIC.QRCodeScanner.QRCodeScanner}: java.lang.NullPointerException 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread.deliverResults(ActivityThread.java:2536) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread.handleSendResult(ActivityThread.java:2578) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread.access$2000(ActivityThread.java:117) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:965) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.os.Handler.dispatchMessage(Handler.java:99) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.os.Looper.loop(Looper.java:123) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread.main(ActivityThread.java:3691) 10-21 12:44:33.699: E/AndroidRuntime(13016): at java.lang.reflect.Method.invokeNative(Native Method) 10-21 12:44:33.699: E/AndroidRuntime(13016): at java.lang.reflect.Method.invoke(Method.java:507) 10-21 12:44:33.699: E/AndroidRuntime(13016): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:847) 10-21 12:44:33.699: E/AndroidRuntime(13016): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:605) 10-21 12:44:33.699: E/AndroidRuntime(13016): at dalvik.system.NativeStart.main(Native Method) 10-21 12:44:33.699: E/AndroidRuntime(13016): Caused by: java.lang.NullPointerException 10-21 12:44:33.699: E/AndroidRuntime(13016): at com.AIC.QRCodeScanner.QRCodeScanner.onActivityResult(QRCodeScanner.java:379) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.Activity.dispatchActivityResult(Activity.java:3934) 10-21 12:44:33.699: E/AndroidRuntime(13016): at android.app.ActivityThread.deliverResults(ActivityThread.java:2532) 10-21 12:44:33.699: E/AndroidRuntime(13016): ... 11 more 

La línea a la que apunta sería esta línea (línea 379): data.getData(), Toast.LENGTH_LONG

Sin embargo, los archivos se guardan en la carpeta /Pictures/MyCameraApp junto con las fotos de Instagram que se tomaron.

Así que las preguntas son: 1. ¿Hay una manera de hacer onActivityResult trabajar correctamente? Sé que sólo puedo recurrir a startActivity para no matar la aplicación. 2. ¿Hay alguna manera de tomar solo una foto con la cámara? Así que después de que el usuario guarda la foto, la aplicación vuelve a la actividad principal. 3. También, puedo guardarlo en una carpeta de mi propio? No estoy seguro de por qué guarda las fotos en /Pictures/MyCameraApp , quiero guardar sólo en /MyCameraApp .

Creo que estoy perdiendo algo sencillo aquí.

Aquí está el código que lo hizo funcionar:

 //camera stuff Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); //folder stuff File imagesFolder = new File(Environment.getExternalStorageDirectory(), "MyImages"); imagesFolder.mkdirs(); File image = new File(imagesFolder, "QR_" + timeStamp + ".png"); Uri uriSavedImage = Uri.fromFile(image); imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage); startActivityForResult(imageIntent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE); 

Se abre la cámara y toma exactamente una toma (vuelve a la actividad principal después de que el usuario guarda la imagen que se tomó y guarda la imagen en la carpeta especificada.

Usted puede conseguir su foto en su carpeta pero para eso usted tendrá que pasar el nombre de archivo con la intención usando debajo código

 Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); File out = Environment.getExternalStorageDirectory(); out = new File(out, imagename); i.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(out)); startActivityForResult(i, CAMERA_RESULT); 

El archivo de salida contiene la ruta de acceso completa y el nombre del archivo.

Ahora maneje el método onActivityResult () y compruebe el estado del resultado si el resultado es RESULT_OK y luego use el nombre de archivo que ha proporcionado con la intención de acceder a la foto.

Puede consultar cómo obtener el resultado de la cámara como un uri en la carpeta de datos? Para más opciones.

Editar

Usted está recibiendo data.getData() a null porque será nulo si pasa el url del archivo con la intención. De hecho, usted ya tiene la ruta del archivo que está pasando con la Intención así que por qué está tratando de buscarlo desde el paquete en onActivityResult() ?

Esto puede ayudarte

 File file=new File(Environment.getExternalStorageDirectory(),"file name"); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub opencam(); } }); protected void opencam() { Intent in = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); in.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(file)); startActivityForResult(in,1); } 
  • Samsung Galaxy S: ¿Cómo determinar la presencia de la cámara frontal?
  • Android: la foto tomada es más grande que la vista previa
  • Phonegap cámara Android mata cordova
  • Flash Torch en Google Nexus 5
  • Uso de la API de Camera2 con ImageReader
  • ¿Qué hardware soporta la detección de ojos y la boca?
  • Cámara Android: ¿Hilos? Que debe hacer lo que
  • Android - cámara como detector de movimiento
  • Grabación de superposición de texto / imagen en Android
  • Cómo recortar la imagen en forma ovalada o forma facemask en android?
  • Calidad personalizada de la cámara Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.