2011-11-22 11 views
5

Io chiamo telecamera per scattare una foto. Ma non posso tornare alla mia attività originale dopo aver scattato la foto. Qual è il problema? Grazie.Come tornare dall'intento chiamante

public void addEntry(View view) 
{ 
       String EntryName=RegisterName.toString(); 
       Toast.makeText(this, EntryName, Toast.LENGTH_LONG); 
       Intent addEntryintent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
       File file = new File(getFilesDir(),EntryName); 
       registeryFileUri = Uri.fromFile(file); 
       addEntryintent.putExtra(MediaStore.EXTRA_OUTPUT, registeryFileUri); 
       startActivityForResult(addEntryintent,TAKE_PICTURE);   

} 


@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
     if (requestCode == TAKE_PICTURE) 
     { 
      if (data != null) 
      { 
     Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG); 
     ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture); 
     Registerimage.setImageURI(registeryFileUri); 
     } 

    } 
    } 
+0

Hai dimenticato di chiamare 'Toast.show();' dentro 'onActivityResult()'. Deve essere 'Toast.makeText (questo," Registrato con successo! ", Toast.LENGTH_LONG) .show();' –

risposta

4

risposta

Usa appContext.getExternalCacheDir() e non dimenticare di menzionare permissons.

@Override 
     protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
       if (requestCode == TAKE_PICTURE) 
       { 
         if(resultCode==Activity.RESULT_OK) 
        { //if (data != null) 
        //{ 
        Toast.makeText(this, "Successfully Registered!", Toast.LENGTH_LONG); 
        ImageView Registerimage= (ImageView)findViewById(R.id.RegisterPicture); 
        Registerimage.setImageURI(registeryFileUri); 
        //} 
         } 
         else 
         Toast.makeText(this, "Not Registered!", Toast.LENGTH_LONG); 
      } 
**"android.permission.CAMERA"**  

Check whether the above permission is specified in your manifest or not 

Note: It's better to use getExternalCacheDir() than getFilesDir() if you still dont get the 
     image then use that. Dont forgot to specify the permission "android.permission.WRITE_EXTERNAL_STORAGE" if you use the getExternalCacheDir(). 
+0

Hai dimenticato di chiamare 'Toast.show();' dentro 'onActivityResult();' –

+0

ya, tu sono giusti. Ma il problema è con l'intento quindi non ho verificato il codice rimanente. –

+0

Né funziona. Sto usando 4.0, non riesco ancora a tornare dall'attività della fotocamera. – James

1

Su alcuni dispositivi data sarà purtroppo essere nullo in onActivityResult dopo aver chiamato l'attività della fotocamera. Potrebbe quindi essere necessario salvare il proprio stato nelle variabili dell'attività e leggerle in onActivityResult. Assicurati di salvare queste variabili in onSaveInstanceState e ripristinali in onCreate.

+1

Anche se "data! = Null" non viene aggiunto, sono ancora intrappolato nell'attività della telecamera ... – James

7

Mi ci è voluto un po 'per farlo funzionare e ho fatto diverse cose e finalmente funziona. Non posso dire con certezza quale delle cose che ho fatto sia la soluzione al problema, ma tutte insieme costituiscono la soluzione operativa.

Ci sono diversi motivi per cui l'attività della telecamera non ritorna. Due quelli principali sono:

  1. percorso per la nuova immagine non è valido o non esistente, o non possono essere creati

  2. applicazione percorso stato sospeso e salvato perdersi.

Quindi ecco il mio codice per risolvere tutti questi problemi, tutti insieme funzionanti.

Per prima cosa ho creato classe helper ImageServices:

class ImageServices { 

    private static String getTempDirectoryPath(Context ctx) { 
    File cache; 

    // SD Card Mounted 
    if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { 
     cache = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + 
       "/Android/data/" + ctx.getPackageName() + "/cache/"); 
    } 
    // Use internal storage 
    else { 
     cache = ctx.getCacheDir(); 
    } 

    // Create the cache directory if it doesn't exist 
    if (!cache.exists()) { 
     cache.mkdirs(); 
    } 

    return cache.getAbsolutePath(); 
    } 

    public static Uri getOutputImageFileUri(Context ctx) { 
    // TODO: check the presence of SDCard 

    String tstamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); 
    File file = new File(getTempDirectoryPath(ctx), "IMG_" + tstamp + ".jpg"); 

    return Uri.fromFile(file); 

    } 
} 

Il codice è in parte ispirato da developer.android.com e in parte da CameraLauncher class del progetto Apache Cordova.

Nella mia attività di gestore di eventi per il pulsante per scattare una foto assomiglia a questo:

private Uri imageFileUri; 

private static final int MAKE_PHOTO_RESULT_CODE = 100; 
private static final int PICK_PHOTO_RESULT_CODE = 101; 

public void onMakePhoto(View v) { 
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 
    imageFileUri = ImageServices.getOutputImageFileUri(this); 
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageFileUri); 
    Log.i("babies", "Taking picture: requested " + imageFileUri); 
    startActivityForResult(intent, MAKE_PHOTO_RESULT_CODE); 
} 

Metodo onActivityResult in realtà non contiene molto, come imageFileUri punta già al file esistente e necessaria il rendering è fatto in onResume metodo, che viene chiamato quando l'attività si rimette in primo piano:

@Override 
protected void onActivityResult(int requestCode, int resultCode, Intent data) { 
    if (resultCode == RESULT_OK) { 
    switch(requestCode) { 
     case MAKE_PHOTO_RESULT_CODE: 
     assert imageFileUri != null; 
     break; 
     case ... 
     ...other cases... 
     break; 
    } 
    } 
} 

Ma questo non è ancora sufficiente, come imageFileUri si perde come la vostra applicazione viene sospeso. E su dispositivi regolari le probabilità sono vicine al 100%.Così la prossima è necessario memorizzare il valore di imageFileUri di Stato esempio:

@Override 
protected void onSaveInstanceState(Bundle outState) { 
    super.onSaveInstanceState(outState); 
    if (imageFileUri == null) { 
    outState.putString("file-uri", ""); 
    } 
    else { 
    outState.putString("file-uri", imageFileUri.toString()); 
    } 
}; 

e caricarlo di nuovo in - più semplice è direttamente in onCreate:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    if (savedInstanceState != null) { 
    String fileUri = savedInstanceState.getString("file-uri"); 
    if (!fileUri.equals("")) imageFileUri = Uri.parse(fileUri); 
    } 
} 

Così, ancora una volta, in cima a molte altre soluzioni presentato su questo sito, così come altrove, ci sono due differenze importanti:

  1. più intelligente getTempDirectoryPath ispirato da Apache Cordova
  2. permettendo imageFileUri per sopravvivere applicazione sospesa

E ora - almeno per me - tutto funziona bene.

+0

Mi sto strappando i capelli tutto il giorno. Finalmente trovato questa soluzione. Non è probabile che vedrai questo commento, ma se lo fai, hai trovato dei dispositivi su cui questo non funziona? Great Stuff @Tom Burger –

+0

L'app non è ancora in produzione, quindi non ho molti dispositivi per testarlo. Ma se incontri il dispositivo, dove la cosa sopra potrebbe essere un problema, fammi sapere :-) –