Este es un error bien documentado en algunas versiones de Android. es decir, en las versiones de Android de la experiencia de Google, la captura de imágenes no funciona como se documenta. lo que generalmente he usado es algo como esto en una clase de utilidades.
public boolean hasImageCaptureBug() {
// list of known devices that have the bug
ArrayList<String> devices = new ArrayList<String>();
devices.add("android-devphone1/dream_devphone/dream");
devices.add("generic/sdk/generic");
devices.add("vodafone/vfpioneer/sapphire");
devices.add("tmobile/kila/dream");
devices.add("verizon/voles/sholes");
devices.add("google_ion/google_ion/sapphire");
return devices.contains(android.os.Build.BRAND + "/" + android.os.Build.PRODUCT + "/"
+ android.os.Build.DEVICE);
}
luego, cuando inicio la captura de imágenes, creo una intención que comprueba el error.
Intent i = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
if (hasImageCaptureBug()) {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File("/sdcard/tmp")));
} else {
i.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
}
startActivityForResult(i, mRequestCode);
luego, en la actividad a la que regreso, hago diferentes cosas según el dispositivo.
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
switch (requestCode) {
case GlobalConstants.IMAGE_CAPTURE:
Uri u;
if (hasImageCaptureBug()) {
File fi = new File("/sdcard/tmp");
try {
u = Uri.parse(android.provider.MediaStore.Images.Media.insertImage(getContentResolver(), fi.getAbsolutePath(), null, null));
if (!fi.delete()) {
Log.i("logMarker", "Failed to delete " + fi);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
}
} else {
u = intent.getData();
}
}
esto le ahorra tener que escribir una nueva aplicación de cámara, pero este código tampoco es excelente. los grandes problemas son
nunca obtienes imágenes de tamaño completo de los dispositivos con el error. obtienes imágenes de 512 píxeles de ancho que se insertan en el proveedor de contenido de imágenes. en dispositivos sin el error, todo funciona como documento, obtienes una gran imagen normal.
Tienes que mantener la lista. tal como está escrito, es posible que los dispositivos se actualicen con una versión de Android (digamos las compilaciones de cyanogenmod ) que tiene el error corregido. Si eso sucede, su código se bloqueará. la solución es usar toda la huella digital del dispositivo.
Sé que esto ha sido respondido antes, pero sé que mucha gente se ha tropezado con esto, así que voy a agregar un comentario.
Tuve exactamente el mismo problema en mi Nexus One. Esto era del archivo que no existía en el disco antes de que comenzara la aplicación de la cámara. Por lo tanto, me aseguré de que el archivo existente antes de iniciar la aplicación de la cámara. Aquí hay un código de muestra que usé:
Primero creo un nombre de archivo único (algo) usando un hash MD5 y lo pongo en la carpeta apropiada. Luego verifico para ver si existe (no debería, pero es una buena práctica verificar de todos modos). Si no existe, obtengo el directorio principal (una carpeta) y creo la jerarquía de carpetas (por lo tanto, si las carpetas que conducen a la ubicación del archivo no existen, aparecerán después de esta línea. Luego, después de eso Creo el archivo. Una vez que se crea el archivo, obtengo el Uri y lo paso a la intención y luego el botón OK funciona como se esperaba y todo está dorado.
Ahora, cuando se presiona el botón Ok en la aplicación de la cámara, el archivo estará presente en la ubicación dada. En este ejemplo, sería /sdcard/Android/data/com.example.myapp/files/234asdioue23498ad.jpg
No es necesario copiar el archivo en "onActivityResult" como se publicó anteriormente.
fuente
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
en su manifiesto si está utilizando una versión más nueva que Android 1.5: pasé unas horas depurando las cosas de la cámara y esto no estaba incluido, por lo que mis guardados siempre fallarían.He pasado por una serie de estrategias de captura de fotos, y siempre parece haber un caso, una plataforma o ciertos dispositivos, donde algunas o todas las estrategias anteriores fallarán de manera inesperada. Pude encontrar una estrategia que usa el código de generación de URI a continuación que parece funcionar en la mayoría, si no en todos los casos.
Para contribuir más a la discusión y ayudar a los recién llegados, he creado una aplicación de muestra / prueba que muestra varias estrategias diferentes para la implementación de captura de fotos. Las contribuciones de otras implementaciones son definitivamente alentadas a agregar a la discusión.
https://github.com/deepwinter/AndroidCameraTester
fuente
onActivityResult
o realmente tengo que recordarlo yo mismo? Tendría que guardarlo de forma persistente para que mi aplicación incluso lo recuerde si se destruye mientras se toma una foto ...Tuve el mismo problema donde el botón OK en la aplicación de la cámara no hizo nada, tanto en el emulador como en el nexus one.
El problema desapareció después de especificar un nombre de archivo seguro que no tiene espacios en blanco, sin caracteres especiales, en
MediaStore.EXTRA_OUTPUT
Además, si está especificando un archivo que reside en un directorio que aún no se ha creado, primero debe crearlo. La aplicación de la cámara no hace mkdir por ti.fuente
mkdirs()
lugar demkdir()
si su ruta tiene más de un nivel de directorio y desea que se creen todos (mkdir
solo crea el último, el directorio 'hoja'). Tuve algunos problemas con eso, y esta respuesta me ayudó.El flujo de trabajo que describe debe funcionar como lo describió. Puede ser útil que nos muestre el código en torno a la creación de la intención. En general, el siguiente patrón debería permitirle hacer lo que está intentando.
Tenga en cuenta que es la Actividad de la cámara la que creará y guardará el archivo, y en realidad no forma parte de su aplicación, por lo que no tendrá permiso de escritura en la carpeta de la aplicación. Para guardar un archivo en la carpeta de la aplicación, cree un archivo temporal en la tarjeta SD y muévalo a la carpeta de la aplicación en el
onActivityResult
controlador.fuente
Para seguir el comentario de Yenchi anterior, el botón Aceptar tampoco hará nada si la aplicación de la cámara no puede escribir en el directorio en cuestión.
Eso significa que no puede crear el archivo en un lugar que solo su aplicación pueda escribir (por ejemplo, algo debajo de
getCacheDir())
Algo debajogetExternalFilesDir()
debería funcionar, sin embargo.Sería bueno si la aplicación de la cámara imprimiera un mensaje de error en los registros si no pudiera escribir en la
EXTRA_OUTPUT
ruta especificada , pero no encontré ninguno.fuente
para que la cámara escriba en la tarjeta SD pero mantenga un nuevo álbum en la aplicación de la galería, uso esto:
Tenga en cuenta que deberá generar un nombre de archivo único cada vez y reemplazar el 1111.jpg que escribí. Esto fue probado con nexus one. la uri se declara en la clase privada, por lo que en el resultado de la actividad puedo cargar la imagen desde la uri a imageView para obtener una vista previa si es necesario.
fuente
Tuve el mismo problema y lo solucioné con lo siguiente:
El problema es que cuando especifica un archivo al que solo su aplicación tiene acceso (por ejemplo, llamando
getFileStreamPath("file");
)Es por eso que me aseguré de que el archivo dado realmente exista y que TODOS tengan acceso de escritura.
De esta manera, la aplicación de la cámara tiene acceso de escritura a la Uri dada y el botón Aceptar funciona bien :)
fuente
Te recomiendo que sigas la publicación de entrenamiento de Android para capturar una foto. Muestran en un ejemplo cómo tomar fotografías pequeñas y grandes. También puedes descargar el código fuente desde aquí
fuente
Creé una biblioteca simple que administrará la elección de imágenes de diferentes fuentes (Galería, Cámara), tal vez la guarde en algún lugar (tarjeta SD o memoria interna) y devuelva la imagen, así que puede usarla y mejorarla libremente - Android-ImageChooser .
fuente
El archivo debe ser editable por la cámara, como señaló Praveen .
En mi uso, quería almacenar el archivo en almacenamiento interno. Hice esto con:
Aquí
cacheFile
hay un archivo global utilizado para referirse al archivo que está escrito. Luego, en el método de resultado, la intención devuelta es nula. Entonces el método para procesar la intención se ve así:Aquí
getImageFile()
hay un método de utilidad para nombrar y crear el archivo en el que se debe almacenar la imagen, ycopyFile()
es un método para copiar un archivo.fuente
Puedes usar este código
fuente
Es muy sencillo resolver este problema con el Código de resultado de actividad. Pruebe este método
fuente
fuente