No se puede configurar la fuente de la imagen al acceder a la imagen desde la galería-Android
-
21-12-2019 - |
Pregunta
Estoy usando Cordova 3.4.Cuando capturo una imagen y la configuro, funciona bien, pero cuando intento acceder a la imagen desde la galería obtengo la URL.
content://com.android.providers.media.documents/document/image%4A463
y aparece un error de carga de imagen en mi etiqueta de imagen. Sé que se trata de un error conocido y he remitido preguntas de pila como No se puede cargar la imagen cuando se selecciona de la galería en Android 4.4 (KitKat) usando el complemento de cámara PhoneGap
No puedo utilizar el trabajo preliminar mencionado donde el URI se configura manualmente como content://media/external/images/media/ porque nos enfocamos en dispositivos con almacenamiento interno integrado, como Moto.
También puede confirmar que este problema se ha solucionado en Cordova 3.5. Porque necesito permiso de mis funcionarios para descargar y debo asegurarme de que sea posible. ¿Alguien puede ayudarme?
ACTUALIZAR:
app.directive('upload', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elm, attrs, ctrl) {
elm.on('click', function() {
navigator.camera.getPicture(
function(imageURI) {
scope.$apply(function() {
alert(imageURI);
ctrl.$setViewValue(imageURI);
});
window.resolveLocalFileSystemURI(imageURI, function(fileEntry) {
// ctrl.$setViewValue(imageURI);
alert("inside local file" + imageURI);
alert("Inside local file system");
fileEntry.file(function(fileObj) {
alert("hai");
var options = new FileUploadOptions();
options.fileKey = "file";
options.fileName = fileObj.name;
options.mimeType = fileObj.type;
var ft = new FileTransfer();
// var url = fileUploadUrl;
// ft.upload(imageUri, encodeURI(url), success, failure, options);
});
});
},
function(err) {
ctrl.$setValidity('error', false);
}, {quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.PHOTOLIBRARY
}
);
});
}
};
});
Mi HTML:
<img
ng-src="{{onepic}}"
width="250"
height="390"
alt="error"/>
Establecí el valor para onepic en mi controlador dentro de la función de vigilancia. Entonces, cuando la directiva devuelve un URI, se establecerá automáticamente en onepic. Especifique cualquier solución alternativa o, si estoy haciendo algo mal, soy nuevo en angularjs.
Solución
Prueba esto ..
En el complemento de la cámara, hay un archivo FileHelper.java
, reemplace el complemento getRealPath
con mi este mi método.
Para obtener más detalles, puede seguir esto -> https://issues.apache.org/ JIRA / BREOWSE / CB-5398
filehelper.java
@SuppressWarnings("deprecation")
public static String getRealPath(String uriString, CordovaInterface cordova) {
String realPath = null;
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
// DocumentProvider
if (isKitKat) {
Cursor cursor = cordova.getActivity().getContentResolver().query(Uri.parse(uriString), null, null, null, null);
cursor.moveToFirst();
String document_id = cursor.getString(0);
document_id = document_id.substring(document_id.lastIndexOf(":")+1);
cursor.close();
cursor = cordova.getActivity().getContentResolver().query(
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
null, MediaStore.Images.Media._ID + " = ? ", new String[]{document_id}, null);
cursor.moveToFirst();
String path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
realPath = path;
cursor.close();
}else{
if (uriString.startsWith("content://")) {
String[] proj = { _DATA };
Cursor cursor = cordova.getActivity().managedQuery(Uri.parse(uriString), proj, null, null, null);
int column_index = cursor.getColumnIndexOrThrow(_DATA);
cursor.moveToFirst();
realPath = cursor.getString(column_index);
if (realPath == null) {
LOG.e(LOG_TAG, "Could get real path for URI string %s", uriString);
}
} else if (uriString.startsWith("file://")) {
realPath = uriString.substring(7);
if (realPath.startsWith("/android_asset/")) {
LOG.e(LOG_TAG, "Cannot get real path for URI string %s because it is a file:///android_asset/ URI.", uriString);
realPath = null;
}
} else {
realPath = uriString;
}
}
return realPath;
}
en CameraLauncher.java
Class THERER es un método processResultFromGallery
private void processResultFromGallery
Encuentra este código:
if (this.targetHeight == -1 && this.targetWidth == -1 &&
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation){
this.callbackContext.success(uri.toString());
}
y reemplazar con esto:
if (this.targetHeight == -1 && this.targetWidth == -1 &&
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation) {
String s =FileHelper.getRealPath(uri.toString(), cordova);
Log.i("test","<<<<ifURI::::::"+s +"URI::::" + uri.toString());
this.callbackContext.success(s);
}
Otros consejos
ver Esta respuesta :
if (imageUri.toString().substring(0,21).equals("content://com.android")) {
String [] photo_split= imageUri.toString().split("%3A");
String imageUriBasePath = "content://media/external/images/media/"+photo_split[1];
imageUri= Uri.parse(imageUriBasePath );
}
Siempre que algunos uri
se pasa a <img src="uri" />
está implícitamente decodificado de
contenido://com.android.providers.media.documents/document/image%3A9888 (1)
en
contenido://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 permiso de lectura para (1), no (2).En este caso WebView
expectantemente registrará un error:
java.lang.SecurityException:Denegación de permiso:Lectura 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 Grantipermission () ()
o
No se puede abrir la URL del contenido
Fragmento de código
Todo lo que necesitas 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
en HTML/JS para garantizar que (1) será realmente cargado.
Lo probé en 4.4.2, 4.4.4 y 5.0.Lo curioso es que Android 4.4.2 decodifica el uri
internamente dos veces.