Android: tomar fotos y guardarlas con un nombre personalizado en un destino personalizado a través de Intento

Tengo un progtwig que abre la cámara a través de Intento para tomar una foto. Esa parte ya funciona bien. Sin embargo, quiero que se guarde en una determinada carpeta con un cierto nombre de archivo (el nombre del archivo es opcional pero realmente ayudaría).

Así que aquí está lo que tengo hasta ahora.

Aquí está 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); 

Controlador 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 bien. Sin embargo, se guardó en la carpeta predeterminada con el nombre de archivo predeterminado (la versión del sello de tiempo). La tostada mostrada “Imagen guardada en: nulo” ya que aún no he configurado esa parte.

Así que aquí están los métodos que se suponía que manejarían 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 la cámara de developer.android.com.

El código anterior se las arregla para abrir la cámara y tomar fotos y guardarlas. Sin embargo, el problema ocurre cuando el usuario decide dejar de tomar fotos y presiona la tecla Atrás. Lo que sucede es que la fuerza de la aplicación cierra 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.

Entonces las preguntas son: 1. ¿Hay alguna manera de hacer que onActivityResult funcione correctamente? Sé que puedo recurrir al uso de startActivity para no matar la aplicación. 2. ¿Hay alguna forma de tomar solo una fotografía con la cámara? Entonces, después de que el usuario guarda la foto, la aplicación vuelve a la actividad principal. 3. Además, ¿puedo guardarlo en una carpeta propia? No estoy seguro de por qué guarda las fotos en /Pictures/MyCameraApp , quiero que solo se guarden en /MyCameraApp .

Creo que me estoy perdiendo algo simple 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); 

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ó. Guarda la imagen en la carpeta especificada.

Puede obtener su foto en su carpeta, pero para eso tendrá que pasar el nombre del archivo con la intención de usar el código siguiente

 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 completa y el nombre del archivo.

Ahora maneje el método onActivityResult () y verifique el estado del resultado si el resultado es RESULT_OK y luego use el nombre del 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 uri en la carpeta de datos? para más opciones.

Editar

Obtendrá null a data.getData() porque será nulo si pasa la URL del archivo con la intención. De hecho, usted ya tiene una ruta de archivo que está pasando con la intención, entonces, ¿por qué está tratando de recuperarla del 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); }