2011-11-22 19 views
5

Llamo a la cámara para tomar una foto. Pero no puedo volver a mi actividad original después de tomar la foto. ¿Cuál es el problema? Gracias.Cómo volver desde el intento de llamada

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

Olvidó llamar a 'Toast.show();' inside 'onActivityResult()'. Debe ser 'Toast.makeText (this," ¡Registrado con éxito! ", Toast.LENGTH_LONG) .show();' –

Respuesta

4

respuesta

Uso appContext.getExternalCacheDir() y no se olvide de mencionar permisos en.

@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

Ha olvidado llamar a 'Toast.show();' inside 'onActivityResult();' –

+0

ya, usted tienen razón. Pero el problema es con la intención, así que no verifiqué el código restante. –

+0

Ninguno de los dos funciona. Estoy usando 4.0, todavía no puedo regresar de la actividad de la cámara. – James

1

En algunos dispositivos data desafortunadamente ser nulo en onActivityResult después de llamar a la actividad de la cámara. Por lo tanto, es posible que deba guardar su estado en las variables de su actividad y que las lea en el onActivityResult. Asegúrese de guardar estas variables en onSaveInstanceState y restaurarlas en onCreate.

+1

Incluso si no se agrega "data! = Null", sigo atrapado en la actividad de la cámara ... – James

7

Me tomó un tiempo para que funcione y he hecho varias cosas y finalmente funciona. No puedo decir con certeza cuál de las cosas que hice es la solución al problema, pero todas juntas forman la solución de trabajo.

Existen varias razones por las cuales la actividad de la cámara no regresa. Dos más importantes son:

  1. ruta para la nueva imagen no es válida o no existente, o que no se pueden crear

  2. aplicación trayectoria fue suspendido y se guarda perderse.

Así que aquí está mi código para resolver todos estos problemas, todos juntos trabajando.

Primero creé clase de ayuda 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); 

    } 
} 

El código está inspirado en parte por developer.android.com y en parte por CameraLauncher class del proyecto Apache Cordova.

En mi actividad al controlador de eventos para el botón para tomar una imagen se ve así:

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

Método onActivityResult en realidad no contiene mucho, ya que imageFileUri ya apunta al archivo existente y la representación necesaria se realiza en onResume método, que se llama cuando la actividad se pone de nuevo en primer plano:

@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; 
    } 
    } 
} 

Pero esto todavía no es suficiente, ya que se pierde imageFileUri como su aplicación se suspende. Y en dispositivos regulares, las posibilidades son cercanas al 100%.Así que la próxima que necesita para almacenar el valor de imageFileUri al estado de la instancia:

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

y cargarlo de nuevo en - más fácil es directamente en 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); 
    } 
} 

Así, de nuevo, en la parte superior de muchas otras soluciones presentada en este sitio, así como en otras partes, hay dos diferencias principales:

  1. inteligente getTempDirectoryPath inspirado en Apache Cordova
  2. permitiendo imageFileUri para sobrevivir aplicación suspendida

Y ahora - al menos para mí - todo funciona bien.

+0

He estado tirando de mi cabello todo el día. Finalmente encontré esta solución. No es probable que veas este comentario, pero si lo haces, ¿has encontrado algún dispositivo con el que no funcione? Great Stuff @Tom Burger –

+0

La aplicación aún no está en producción, por lo que no tengo muchos dispositivos para probar esto. Pero si encuentra el dispositivo, donde lo de arriba podría ser un problema, permítame saberlo :-) –

Cuestiones relacionadas