您的位置:首页 > 移动开发

android4.4webview支持openFileChooser文件/照片上传

2015-09-11 16:50 741 查看
H5拍照应用在mobile(android和ios)上的实现思路有以下三种:

第一种,H5直接使用新的video标签通过获取navigator的getUserMedia来获取视频流stream中截取一张图的方式来实现,不过这种方式在mobile上的支持比较晚。其中,android是从Android5.0才开始支持,ios未知。所以这种实现思路不做考虑。

第二种,H5直接用以前Html旧有的input标签来实现。其中这种方式在ios支持上还不错,在android上的支持则不怎么令人满意。因为它直接涉及到了webkit在android各个平台不同的实现方式,有很大的风险性。但是,出于方便让ios能直接调用的原因这个方式的可行性还是很大的。当然,问题并非不能解决,这个下面再讲。

第三种,H5直接利用js和本地进行交互来实现。这种方式的采用很成功的例子就是微信公众账号的实现,它通过实现一套js库来支持网页的各种调用。

------------------------------------------------------------------分割线----------------------------------------------------

以下是讲述android4.4webview支持openFileChooser文件/照片上传的一些思路:

大家都知道,android webkit在各个版本上的变化很大。其中,大家会发现android4.4对openFileChooser文件上传的支持是一片空白。我在这里只提供一些思路供大家参考。

第一种思路,自定义webkit使之支持openFileChooser,即将framework的webkit相关代码抽离出来,在源码的基础上修改后再打包。但是这种方式有很大的缺陷,第一你要完全的把webkit相关代码剥离出来打包,这对一般的应用开发者来说还是有一定难度的。第二,最大的问题是你这样做的话势必会增大apk包的体积,有点得不偿失了。我在网上查到的资料是会使apk包增加30-50MB的空间。。。
http://stackoverflow.com/questions/19882331/html-file-input-in-android-webview-android-4-4-kitkat https://crosswalk-project.org/documentation/downloads.html
第二种思路,使用input标签。但是html中增加js对input标签进行拦截。如果android版本是4.4或者4.4.1或者4.4.2的话,将input标签隐藏,增加一个button和span标签,并添加事件支持,通过js和native交互的方式来实现。部分代码如下:

function fixAndroidFileUpload() {
var version = agate.device.os.version();

if (version != "4.4" && version != "4.4.1" && version != "4.4.2")
return;
if (agate.device.os.platform() != "Android")
return;

if (typeof(window.fixAFU_inputInfos) == "undefined")
window.fixAFU_inputInfos = new Array();

var inputTags = document.getElementsByTagName("input");

var i;
for (i = 0; i < inputTags.length; ++i) {
var inputTag = inputTags[i];
if (inputTag.type == "file" && inputTag.style.display != "none") {
if (inputTag.hasAttribute("inputInfoIndex"))
continue;

var infoIndex = window.fixAFU_inputInfos.length;
inputTag.setAttribute("inputInfoIndex", infoIndex);

inputTag.style.display = "none";

var patchedButton = document.createElement("button");
patchedButton.setAttribute("inputInfoIndex", infoIndex);
patchedButton.type = "button";
patchedButton.innerHTML = fixAFU_buttonInnerHTML;
inputTag.parentNode.insertBefore(patchedButton, inputTag);
patchedButton.form = inputTag.form;

var patchedTitle = document.createElement("span");
patchedTitle.setAttribute("inputInfoIndex", infoIndex);
patchedTitle.innerHTML = fixAFU_fileNameInnerHTML;
inputTag.parentNode.insertBefore(patchedTitle, inputTag);

patchedButton.onclick = function (e) {
window.fixAFU_lastInputInfo = e.target.getAttribute("inputInfoIndex");
agate.appLauncher.setSaveForImageCapture(true);
agate.appLauncher.setSaveDirForImageCapture('storage:Photo/');
agate.appLauncher.addEventListener("onComplete", "fixAFU_onFileChoose");
agate.runScript("device.systemPopup('', '" + fixAFU_chooseFileForUploadMessage + "','Camera:appLauncher.exec(\\'imageCapture\\')','Gallery:appLauncher.exec(\\'albums\\')','Cancel')");
};

var inputInfo = new Object();
window.fixAFU_inputInfos.push(inputInfo);
inputInfo.inputTag = inputTag;
inputInfo.patchedTitle = patchedTitle;
inputInfo.patchedButton = patchedButton;

}
}

}


但是,这种思路有一定的局限性,那就是各个机型的适配。有些深度定制的厂家很可能会改动这一块。

第三种思路,就是采取上面第三种的方式,即直接通过js和本地native通信来实现。

------------------------------------------------------------------分割线----------------------------------------------------

附:Android各个版本对文件上传支持的方法:

// android 3.0以下:

void openFileChooser(ValueCallback<Uri> uploadMsg)


// android 3.0以上,android4.0以下:

void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType)


// android 4.0 - android 4.3

void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)


// android4.4 无方法。。。

// android4.4.4

void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture)

// android5.0以上

boolean onShowFileChooser (WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams)


附件:

input标签上传文件的例子点击打开链接

联系方式:

陈俊

QQ:838704711
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: