picture - plugins cordova android
No se puede cargar la imagen cuando se selecciona desde la galerĂa en Android 4.4(KitKat) usando PhoneGap Camera Plugin (6)
Intento establecer el origen de una etiqueta img en mi aplicación en función de la imagen elegida en la galería de imágenes del dispositivo mediante el complemento de cámara PhoneGap / Cordova.
Ha funcionado previamente según lo previsto en las versiones anteriores de Android (3.3) y funciona bien en iOS, pero ahora no puede resolver la ruta de la imagen en 4.4 (KitKat).
La ruta devuelta para la url de la imagen devuelta tiene el siguiente aspecto:
content://com.android.providers.media.documents/document/image%3A352
Cuando uso esta ruta para configurar como src de imagen a través de JavaScript, la URL no se puede resolver y, por lo tanto, produce un error de carga. No hay ningún problema al tomar una foto con la cámara, solo parece ocurrir al elegir una imagen existente de la galería.
He intentado codificar a base64 y también probé el método mencionado en los documentos resolveLocalFileSystemURI();
pero no he tenido suerte con esto. También intenté eliminar el complemento de la cámara y reconstruir la aplicación, pero no me gustó.
Supongo que algo ha cambiado con la forma en que KitKat maneja la galería y el plugin PhoneGap / Camera no se ha actualizado para acomodar esto todavía.
Adobe me asegura que este problema se solucionará en 3.5.0. No está arreglado en 3.4. Como el lanzamiento del 3.5.0 está programado para mediados de mayo, esperaré hasta entonces.
Adobe afirma que esto no fue un cambio que podría hacerse en el nivel de complemento. Fue un cambio básico en el código cordova. Es una lástima que hayan tardado tanto en llegar a esta solución.
ACTUALIZACIÓN: Cordova 3.5.0 fue lanzado el 9 de mayo. Puede descargarlo bia node y ver si los problemas están resueltos.
Algo se rompió en Android 4.4 con la codificación de imágenes URI.
Se ha presentado un error contra Cordova aquí: https://issues.apache.org/jira/browse/CB-5398
En los documentos de getPicture , en la sección Android Quicks, analiza este problema y apunta a una pregunta de con una solución alternativa (edite el código java del complemento de la cámara para forzarlo a abrir la aplicación Galería en lugar de la aplicación Storage Access Framework).
Parece que otra cosa que podría hacer es establecer el tipo de destino en DATA_URL.
Aquí hay una solución simple a este problema:
reemplazar esto:
content://com.android.providers.media.documents/document/image%3A352
por esto:
content://com.android.providers.media.documents/document/image%253A352
Si está usando JavaScript, puede usar este código:
var path = content://com.android.providers.media.documents/document/image%3A352;
path = path.replace("%", "%25");
esta técnica fuerza al uri a dejar pasar "% 3A" tal como es, sin cambiarlo a ":", ¡espero que funcione para usted!
Cada vez que se pasa un uri
a <img src="uri" />
se decodifica implícitamente desde
content: //com.android.providers.media.documents/document/image%3A9888 (1)
dentro
content: //com.android.providers.media.documents/document/image: 9888 (2)
Sin embargo, después de regresar de Intent.ACTION_OPEN_DOCUMENT
o Intent.ACTION_GET_CONTENT
Android le proporciona el permiso de lectura para (1) , no (2) . En este caso, WebView
registrará un error de forma expectante:
java.lang.SecurityException: denegación de permiso: lectura de com.android.providers.media.MediaDocumentsProvider uri content: //com.android.providers.media.documents/document/image: 9888 de pid = 13163, uid = 10165 requiere android. permission.MANAGE_DOCUMENTS, o grantUriPermission ()
o
No se puede abrir la URL de contenido
Fragmento de código
Todo lo que necesita para resolver el problema es
String uriToUseInWebView = transformForWebView(uri.toString());
private String transformForWebView(String uri) {
for (int i = 0; i < timesDecodingWebView(); i++)
uri = uri.replace("%", Uri.encode("%"));
return uri;
}
private int timesDecodingWebView() {
if (Build.VERSION.RELEASE.equals("4.4.2")) {
return 2;
} else {
return 1;
}
}
en su código Java antes de pasar uri
a HTML / JS para asegurarse de que (1) se cargue realmente.
Lo he probado en 4.4.2, 4.4.4 y 5.0. La parte divertida es que Android 4.4.2 decodifica el uri
internamente dos veces.
No mucho más robusto solo unos pocos controles más para condiciones especiales como "contenido:" sin extensiones y así sucesivamente. Además, dado que necesito subirlo, estoy detectando la extensión, o creo una extensión .jpg si el archivo no tiene una:
// Android 4.4 cordova workarounds ... returns new kind or URL for content from chooser
//if (imageUrl.substring(0,21)=="content://com.android") {
if(imageUrl.indexOf(''content://'') != -1 && imageUrl.indexOf("%3A") != -1){
//"PlainFileUrl = content://com.android.providers.media.documents/document/image%3A14",
photo_split=imageUrl.split("%3A");
imageUrl="content://media/external/images/media/"+photo_split[1];
}
// workaround end
var fileName = imageUrl.substr(imageUrl.lastIndexOf(''/'') + 1);
var extension;
// check for content: protocol to make sure is not
// a file with no extension
if (imageUrl.indexOf(''content://'') != -1) {
if(imageUrl.lastIndexOf(''.'') > imageUrl.lastIndexOf(''/'')){
extension = imageUrl.substr(imageUrl.lastIndexOf(''.'') + 1);
}else{
extension = "jpg";
fileName = fileName + ".jpg";
LogService.log("Created File Extension jpg");
}
} else {
if (imageUrl.lastIndexOf(''.'') == -1 || (imageUrl.lastIndexOf(''.'') < imageUrl.lastIndexOf(''/'')) ) {
extension = "invalid";
} else {
extension = imageUrl.substr(imageUrl.lastIndexOf(''.'') + 1);
}
}
Un tipo de solución realmente muy sucia me funciona mientras que este error está solucionado. Uso en caso de extrema necesidad :)
if (imageURI.substring(0,21)=="content://com.android") {
photo_split=imageURI.split("%3A");
imageURI="content://media/external/images/media/"+photo_split[1];
}