2012-10-21 21 views
8

Ho un programma che apre la fotocamera tramite Intento per scattare una foto. Quella parte funziona già bene. Tuttavia, voglio che salvi in ​​una certa cartella con un determinato nome di file (il nome del file è opzionale ma sarebbe davvero di grande aiuto).Android - Scattare foto e salvarle con un nome personalizzato in una destinazione personalizzata tramite Intent

Quindi ecco quello che ho finora.

Ecco la riga di codice che apre la fotocamera:

//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); 

gestore Risultato va qui:

//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 
    } 
} 

Prima ho implementato i due metodi indicati, il codice stava funzionando benissimo. Tuttavia è stato salvato nella cartella predefinita con il nome del file predefinito (la versione con timestamp). Il brindisi mostra "Imaged saved to: null" poiché non ho ancora impostato quella parte.

Così qui sono i metodi che avrebbero dovuto gestire il nome del file personalizzato e la destinazione

/** 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; 
} 

* Questi codici sono tratti dalla guida della telecamera da developer.android.com.

Il codice sopra consente di aprire la fotocamera e scattare foto e salvarle. Tuttavia, il problema si verifica quando l'utente decide di interrompere l'acquisizione di foto e premere il tasto Indietro. Quello che succede è che la forza di applicazione si chiude dando questo errore:

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 linea a cui punta sarebbe questa linea (linea 379): data.getData(), Toast.LENGTH_LONG

Tuttavia, i file vengono salvati nella cartella /Pictures/MyCameraApp insieme le foto di Instagram che sono state scattate.

Quindi le domande sono: 1. C'è un modo per rendere onActivityResult funziona correttamente? So che posso semplicemente ricorrere a startActivity per non uccidere l'app. 2. C'è un modo per fare solo uno scatto con la fotocamera? Quindi, dopo che l'utente ha salvato la foto, l'app torna all'attività principale. 3. Inoltre, posso salvarlo in una cartella personale? Non sono sicuro del motivo per cui salva le foto in /Pictures/MyCameraApp, voglio che salvi solo su /MyCameraApp.

Penso che mi stia perdendo qualcosa di semplice qui.

risposta

19

Ecco il codice che ha reso il lavoro:.

//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); 

si apre la fotocamera e prende esattamente un solo colpo (risale all'attività principale dopo che l'utente salva l'immagine che è stata presa Si salva l'immagine nella cartella specificata.

+1

la linea filepath non ha alcuno scopo, vero? Meglio rimuoverlo. – Laurent

+0

In che modo il permesso di utilizzo aggiunge una risposta? –

+0

Creerà uno stesso file nella directory specificata. Come creare una nuova immagine con lo stesso nome. – taranjeetsapra

7

È possibile ottenere la vostra foto nella cartella, ma per questo si dovrà passare il nome del file con l'intento utilizzando sottostante Codice

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

Il file fuori contiene il percorso completo e il nome del file.

Ora gestire il metodo onActivityResult() e controllare lo stato del risultato se il risultato è RESULT_OK quindi utilizzare il nome del file fornito con l'intento di accedere alla foto.

È possibile fare riferimento a How to get camera result as a uri in data folder? per ulteriori opzioni.

Modifica

Hai trovato data.getData() a nulla perché sarà nullo se si passa il file URL con l'intento. In effetti hai già percorso il file che stai passando con l'Intent, quindi perché stai cercando di recuperarlo dal pacchetto in onActivityResult()?

+0

Siamo spiacenti, ho aggiornato la mia domanda. :) – Razgriz

+0

@Razgriz Controllare la mia risposta aggiornata. – Dharmendra

+0

Oh hmm. Ho commentato e ha funzionato bene, ma ci sono stati alcuni risultati indesiderati. Ho seguito il link che hai inviato e l'ho ritoccato un po 'e alla risposta che volevo. Pubblicare la risposta in pochi istanti. – Razgriz

0

questo può aiutare u

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); 
} 
Problemi correlati