我正在尝试根据使用PhoneGap / Cordova相机插件从设备图库中选择的图像在我的应用中设置img标记的来源。
以前在旧版本的Android(3.3)上按预期工作,在iOS上工作正常,但现在无法解析4.4(KitKat)上的图像路径。
返回的图片网址的返回路径如下所示:
content://com.android.providers.media.documents/document/image%3A352
当我使用此路径通过JavaScript设置为图像src时,无法解析URL,因此会产生加载错误。使用相机拍照时没有问题,只有在从画廊中选择现有照片时才会出现这种情况。
我已经尝试过编码到base64并尝试了文档resolveLocalFileSystemURI();
中提到的方法,但我对这些没有运气。我也试过删除相机插件并重建应用程序,但没有快乐。
我的猜测是KitKat处理图库的方式发生了变化,PhoneGap / Camera插件尚未更新以适应这种情况。
答案 0 :(得分:19)
当修复此错误时,一种非常非常脏的解决方法适用于我。在极端必要的情况下使用:)
if (imageURI.substring(0,21)=="content://com.android") {
photo_split=imageURI.split("%3A");
imageURI="content://media/external/images/media/"+photo_split[1];
}
答案 1 :(得分:16)
Android 4.4中的某些内容与图像的URI编码有关。
此处针对Cordova提出了一个错误:https://issues.apache.org/jira/browse/CB-5398
在getPicture的文档中,在Android Quicks部分下,它讨论了这个问题,并指出了一个带有解决方法的StackOverflow问题(编辑Camera插件java代码以强制它打开Gallery应用程序而不是存储访问框架应用程序。)
您可以做的另一件事是将目的地类型设置为DATA_URL。
答案 2 :(得分:4)
Adobe向我保证,这个问题将在3.5.0中修复。它没有在3.4中修复。由于3.5.0计划于5月中旬发布,我只能等到那时。
Adobe声称这不是可以在插件级别上进行的更改。这是科尔多瓦代码的一个基本变化。他们花了这么长时间来解决这个问题太糟糕了。
更新:Cordova 3.5.0于5月9日发布。您可以下载bia节点,看看问题是否已经解决。
答案 3 :(得分:4)
以下是此问题的简单修复:
替换这个:
content://com.android.providers.media.documents/document/image%3A352
由此:
content://com.android.providers.media.documents/document/image%253A352
如果您使用的是JavaScript,则可以使用以下代码:
var path = content://com.android.providers.media.documents/document/image%3A352;
path = path.replace("%", "%25");
这种技术迫使uri按原样传递“%3A”,而不将其改为“:”,希望它能为你效用!
答案 4 :(得分:2)
对于像“内容:”这样没有扩展等特殊条件的更多检查,并没有那么强大。此外,由于我需要上传它,我正在检测扩展名,或者如果文件没有扩展名,则创建.jpg扩展名:
// 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);
}
}
答案 5 :(得分:0)
每当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:Permission Denial:read com.android.providers.media.MediaDocumentsProvider uri 内容://com.android.providers.media.documents/document/image:9888 从pid = 13163,uid = 10165需要 android.permission.MANAGE_DOCUMENTS或grantUriPermission()
或
无法打开内容网址
代码段
您需要解决的问题是
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;
}
}
在将uri
传递给HTML / JS之前,在您的Java代码中以确保实际加载(1)。
我在4.4.2,4.4.4和5.0上测试了它。有趣的是,Android 4.4.2在内部对uri
进行了两次解码。