Impossible de définir la source de l'image lors de l'accès à l'image depuis la galerie-Android
-
21-12-2019 - |
Question
J'utilise Cordova 3.4.Lorsque je capture une image et la configure, cela fonctionne bien, mais lorsque j'essaie d'accéder à l'image de la galerie, j'obtiens l'URL.
content://com.android.providers.media.documents/document/image%4A463
et j'obtiens une erreur de chargement d'image dans ma balise d'image. Je sais qu'il s'agit d'un bug connu et j'ai référé à des questions de pile telles que Impossible de charger l'image lorsqu'elle est sélectionnée dans la galerie sur Android 4.4 (KitKat) à l'aide du plug-in PhoneGap Camera
Je ne peux pas utiliser le travail approximatif mentionné où l'URI est défini manuellement comme content://media/external/images/media/ parce que nous concentrons les appareils avec un stockage interne intégré tel que Moto.
Pouvez-vous également confirmer que ce problème a été résolu dans Cordova 3.5. Parce que j'ai besoin de l'autorisation de mes responsables pour le téléchargement et je dois m'assurer que cela est réalisable. Quelqu'un peut-il m'aider, s'il vous plaît
MISE À JOUR:
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
}
);
});
}
};
});
Mon HTML :
<img
ng-src="{{onepic}}"
width="250"
height="390"
alt="error"/>
J'ai défini la valeur pour Onepic dans mon contrôleur dans la fonction Watch. Ainsi, lorsque la directive renvoie un URI, elle sera automatiquement définie dans Onepic. Veuillez spécifier une solution alternative ou si je fais quelque chose de mal, je suis nouveau sur AngularJS.
La solution
Essaye ça..
Dans Camera Plugin, il y en a un FileHelper.java
Fichier, Remplacer le plugin getRealPath
avec ma ceci ma méthode.
Pour plus de détails, vous pouvez suivre ceci -> https://issues.apache.org/jira/browse/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;
}
Dans CameraLauncher.java
La classe est une méthode processResultFromGallery
private void processResultFromGallery
Trouvez ce code :
if (this.targetHeight == -1 && this.targetWidth == -1 &&
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation){
this.callbackContext.success(uri.toString());
}
Et remplacez par ceci :
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);
}
Autres conseils
voir Ceci Réponse:
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 );
}
Chaque fois que certains uri
est passé dans <img src="uri" />
c'est implicitement décodé à partir de
contenu://com.android.providers.media.documents/document/image%3A9888 (1)
dans
contenu://com.android.providers.media.documents/document/image:9888 (2)
Cependant, après son retour de Intent.ACTION_OPEN_DOCUMENT
ou Intent.ACTION_GET_CONTENT
Android vous fournit l'autorisation de lecture pour (1), pas (2).Dans ce cas WebView
en espérant enregistrer une erreur :
java.lang.SecurityException :Refus d'autorisation :Lecture com.android.providers.media.mediaDocumentsProvider Uri Content: //com.android.providers.media.documents/document/image: 9888 de PID = 13163, uid = 10165 nécessite Android.permission.manage_documents, ou GRANUPERMISSION ()
ou
Impossible d'ouvrir l'URL du contenu
Extrait de code
Tout ce dont vous avez besoin pour résoudre le problème est
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;
}
}
dans votre code Java avant de passer uri
en HTML/JS pour garantir que (1) sera effectivement chargé.
J'ai testé cela sur 4.4.2, 4.4.4 et 5.0.Le plus drôle, c'est qu'Android 4.4.2 décode le uri
en interne deux fois.