갤러리-Android에서 이미지에 액세스할 때 이미지 소스를 설정할 수 없습니다.
-
21-12-2019 - |
문제
저는 코르도바 3.4를 사용하고 있습니다.이미지를 캡처하고 설정하면 제대로 작동하지만 갤러리에서 이미지에 액세스하려고 하면 URL을 얻습니다.
content://com.android.providers.media.documents/document/image%4A463
내 이미지 태그에 이미지 로드 오류가 발생합니다. 이것이 알려진 버그라는 것을 알고 있으며 다음과 같은 스택 질문을 참조했습니다. PhoneGap 카메라 플러그인을 사용하여 Android 4.4(KitKat)의 갤러리에서 선택한 경우 이미지를 로드할 수 없습니다.
Moto와 같은 내부 내장 저장소가 있는 장치에 초점을 맞추기 때문에 content://media/external/images/media/와 같이 URI가 수동으로 설정되는 언급된 대략적인 작업을 사용할 수 없습니다.
또한 이 문제가 코르도바 3.5에서 해결되었는지 확인해 주시겠습니까? 다운로드하려면 관계자의 허가가 필요하고 다운로드가 가능한지 확인해야 하기 때문입니다. 누군가 도와주세요.
업데이트:
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
}
);
});
}
};
});
내 HTML:
<img
ng-src="{{onepic}}"
width="250"
height="390"
alt="error"/>
watch 함수 내부의 컨트롤러에서 onepic에 대한 값을 설정했습니다. 따라서 지시문이 URI를 반환하면 자동으로 onepic에 설정됩니다. 대체 솔루션을 지정하거나 잘못된 작업을 수행하는 경우에는 anglejs를 처음 사용합니다.
해결책
이 시도..
카메라 플러그인에는 하나가 있습니다 FileHelper.java
파일, 플러그인 교체 getRealPath
내 방법으로.
자세한 내용은 다음을 참조하세요 -> 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;
}
~ 안에 CameraLauncher.java
거기에 클래스는 하나의 방법입니다 processResultFromGallery
private void processResultFromGallery
다음 코드를 찾으세요:
if (this.targetHeight == -1 && this.targetWidth == -1 &&
(destType == FILE_URI || destType == NATIVE_URI) && !this.correctOrientation){
this.callbackContext.success(uri.toString());
}
그리고 다음으로 바꾸세요:
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);
}
다른 팁
이 답변 :
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 );
}
. 언제든지 uri
으로 전달됩니다 <img src="uri" />
암시적으로 디코딩되었습니다.
콘텐츠://com.android.providers.media.documents/document/image%3A9888 (1)
~ 안으로
콘텐츠://com.android.providers.media.documents/document/image:9888 (2)
그러나 귀국 후 Intent.ACTION_OPEN_DOCUMENT
또는 Intent.ACTION_GET_CONTENT
Android는 다음에 대한 읽기 권한을 제공합니다. (1), 아니다 (2).이 경우 WebView
예상대로 오류가 기록됩니다.
java.lang.SecurityException:권한 거부:com.android.providers.media.mediadocumentsprovider uri content : //com.android.providers.media.documents/document/image : 9888 From PID = 13163, uid = 10165는 android.permission.manage_documents 또는 grantuRipermission ()이 필요합니다.
또는
콘텐츠 URL을 열 수 없습니다.
코드 조각
문제를 해결하는 데 필요한 것은
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;
}
}
통과하기 전에 Java 코드에서 uri
HTML/JS로 변환하여 (1) 실제로 로드됩니다.
4.4.2, 4.4.4 및 5.0에서 테스트했습니다.재미있는 부분은 Android 4.4.2가 uri
내부적으로 두 번.