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

android使用webview上传文件(适配4.4以上系统)

2016-11-10 13:10 746 查看
在版本迭代中需要上传图片做统计,把链接发QQ上,里面的网页可以正常上传图片,但是我们自己app里不能上传。查了一些相关资料

默认情况下,Android的webview是不支持<input type=file>的,点击没有任何反应,如果希望点击上传,弹出选择文件、图片的窗口,我们可以重写webview的webchromeClient中的openFileChooser方法,由于android系统有多个版本,因此需要重写多个openFileChooser进行兼容,而android5.0以后,需要重写onShowFileChooser方法,其上传的参数Uri变成了Uri[]类型,说明5.0以后支持多传图片。查了很多文章,要么实现不了,要么对一些手机系统版本5.0及以上系统不适配或者手机型号不适配,总结前人经验及遇到的坑查找stackoverflow
外国大佬提供的经验,把实现方法分享一下,帮助小伙伴较少弯路。

可以用下面这个链接进行测试:
https://www.wenjuan.com/s/j67NJrg/
public class MyChromeClient extends WebChromeClient {
public static ValueCallback<Uri> uriValueCallback;
public static ValueCallback<Uri[]> valueCallbacks;
private Activity activity;

public static final int FILECHOOSER_RESULTCODE = 5173;

public static String mCameraFilePath = "";

@SuppressWarnings("deprecation")
public MyChromeClient(Activity cordova) {
this.activity = cordova;
}

@Override
public void onProgressChanged(WebView view, int newProgress) {

super.onProgressChanged(view, newProgress);

}

@Override
public boolean onShowFileChooser(WebView webView,
ValueCallback<Uri[]> filePathCallback,
FileChooserParams fileChooserParams) {
// TODO 自动生成的方法存根
valueCallbacks = filePathCallback;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
return true;
}

public void openFileChooser(ValueCallback<Uri> uploadMsg,
String acceptType, String capture) {
uriValueCallback = uploadMsg;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);

}

// 3.0 +

@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {

uriValueCallback = uploadMsg;

this.activity.startActivityForResult(createDefaultOpenableIntent(),

this.FILECHOOSER_RESULTCODE);

}

// Android < 3.0

@SuppressWarnings("static-access")
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
uriValueCallback = uploadMsg;
this.activity.startActivityForResult(createDefaultOpenableIntent(),
this.FILECHOOSER_RESULTCODE);
}

private Intent createDefaultOpenableIntent() {
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
"image/*");
// Intent chooser = createChooserIntent(createCameraIntent());
// chooser.putExtra(Intent.EXTRA_INTENT, i);
return i;

}

private Intent createChooserIntent(Intent... intents) {
Intent chooser = new Intent(Intent.ACTION_CHOOSER);
chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, intents);
chooser.putExtra(Intent.EXTRA_TITLE, "选择图片");
return chooser;
}

@SuppressWarnings("static-access")
private Intent createCameraIntent() {
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File externalDataDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
File cameraDataDir = new File(externalDataDir.getAbsolutePath()
+ File.separator + "515aaa");
cameraDataDir.mkdirs();
String mCameraFilePath = cameraDataDir.getAbsolutePath()
+ File.separator + System.currentTimeMillis() + ".jpg";
this.mCameraFilePath = mCameraFilePath;
cameraIntent.putExtra(MediaStore.Images.Media.ORIENTATION, 0);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT,
Uri.fromFile(new File(mCameraFilePath)));
return cameraIntent;
}

public static void update(Uri[] uris) {

if ( valueCallbacks != null
&& uris[0] != null) {
valueCallbacks.onReceiveValue(uris);
valueCallbacks = null;
}

if(uriValueCallback != null
&& uris[0] != null){
uriValueCallback.onReceiveValue(uris[0]);
uriValueCallback = null;
}

}

}

在 对应的Activity中事件处理:

/**
* 返回文件选择
*/
@Override
protected void onActivityResult(int requestCode, int resultCode,
Intent intent) {
if (requestCode == MyChromeClient.FILECHOOSER_RESULTCODE&&
intent!=null&&resultCode == RESULT_OK) {
Uri[] uris = new Uri[1];
uris[0] = intent.getData();
MyChromeClient.update(uris);
}
}

测试手机有限,不知道还存在部分机型适配问题不,华为,小米,三星,以及4.x,5.x,6.x系统测试暂时没问题。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: