android 多webview,Android webView多图片选择(两种方法实现)

解决的问题

当webview与h5交互时,遇到选择图片的情况,如果使用了系统相册,默认是选一张的,可是h5的代码是类似这样附带multiple多选属性:

IOS和Android系统浏览器都可以识别并默认能多选,偏偏Android webview不争气

解决的方案1:手动让系统相册自带多选(需要android5.0+)

系统相册既然默认是单选的,那肯定可以多选。直接上代码:

/**

* android 5.0(含) 系统自带的图片选择

*

*/

private void openFileChooseProcess5(ValueCallback filePathCallback,WebChromeClient.FileChooserParams fileChooserParams) {

mValueCallback = filePathCallback;

Intent intent = new Intent(Intent.ACTION_PICK);

intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");

if (fileChooserParams != null && fileChooserParams.getMode() == WebChromeClient.FileChooserParams.MODE_OPEN_MULTIPLE) {

//关键在这

intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);

}

startActivityForResult(intent, 0);

}

/**

* 5.0以下

*/

private void openFileChooseProcess(ValueCallback uploadMsg) {

mUploadMsg = uploadMsg;

Intent i = new Intent(Intent.ACTION_GET_CONTENT);

i.addCategory(Intent.CATEGORY_OPENABLE);

i.setType("image/*");

startActivityForResult(Intent.createChooser(i, "Image Chooser"), 0);

}

注意这句intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);必须加,否则还是单选。

方法openFileChooseProcess5须在WebChromeClient的覆盖方法onShowFileChooser中调用,

具体代码如下

// For Android 3.0+

public void openFileChooser(ValueCallback uploadMsg, String acceptType) {

openFileChooseProcess(uploadMsg);

}

// For Android < 3.0

public void openFileChooser(ValueCallback uploadMsgs) {

openFileChooseProcess(uploadMsg);

}

// For Android > 4.1.1

// @Override

public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) {

openFileChooseProcess(uploadMsg);

}

// For Android >= 5.0

@Override

public boolean onShowFileChooser(WebView webView,

ValueCallback filePathCallback,

WebChromeClient.FileChooserParams fileChooserParams) {

openFileChooseProcess5(filePathCallback,fileChooserParams);

return true;

}

实现当前Activity的onActivityResult方法,获得选中的图片并传给h5,代码如下:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode == RESULT_CANCELED) {

if (mUploadMsg != null) {

mUploadMsg.onReceiveValue(null);

mUploadMsg = null;

}

if (mValueCallback != null) {

mValueCallback.onReceiveValue(null);

mValueCallback = null;

}

}

if (resultCode == Activity.RESULT_OK) {

switch (requestCode) {

case 0:

if (null == mUploadMsg && null == mValueCallback) {

return;

}

Uri result = data == null || resultCode != RESULT_OK ? null : data.getData();

if (mValueCallback != null) {

//处理相关数据

onActivityResultAboveL(data);

} else if (mUploadMsg != null) {

mUploadMsg.onReceiveValue(result);

}

break;

default:

break;

}

}

}

//选中图片并传给js

@TargetApi(Build.VERSION_CODES.LOLLIPOP)

private void onActivityResultAboveL(Intent intent) {

Uri[] results = null;

if (intent != null) {

String dataString = intent.getDataString();

ClipData clipData = intent.getClipData();

if (clipData != null) {

results = new Uri[clipData.getItemCount()];

for (int i = 0; i < clipData.getItemCount(); i++) {

ClipData.Item item = clipData.getItemAt(i);

results[i] = item.getUri();

}

}

if (dataString != null) {

results = new Uri[]{Uri.parse(dataString)};

}

}

mValueCallback.onReceiveValue(results);

mValueCallback = null;

}

注意onActivityResultAboveL方法的作用,多选的情况需要用到intent.getClipData()获取选中数据,在intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);这行代码的第一个参数源码里可以看到注释上倒数第二行有标记说明{@link #getClipData()}

/**

* Extra used to indicate that an intent can allow the user to select and

* return multiple items. This is a boolean extra; the default is false. If

* true, an implementation is allowed to present the user with a UI where

* they can pick multiple items that are all returned to the caller. When

* this happens, they should be returned as the {@link #getClipData()} part

* of the result Intent.

*

* @see #ACTION_GET_CONTENT

* @see #ACTION_OPEN_DOCUMENT

*/

public static final String EXTRA_ALLOW_MULTIPLE =

"android.intent.extra.ALLOW_MULTIPLE";

解决的方案2:自己写一个图片选择器或者调用第三方图片选择器库,并处理选择回调

public void showOptions() {

//调用自己实现的图片选择器

ImageUtils.pictureMultiSelected(getActivity(), PictureConfig.CHOOSE_REQUEST, 9);

}

在上面的openFileChooser和onShowFileChooser中调用此方法。方法内部的实现这里不贴了,回调如下:

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

if (resultCode == RESULT_CANCELED) {

if (mUploadMsg != null) {

mUploadMsg.onReceiveValue(null);

mUploadMsg = null;

}

if (mValueCallback != null) {

mValueCallback.onReceiveValue(null);

mValueCallback = null;

}

}

if (resultCode == Activity.RESULT_OK) {

switch (requestCode) {

case PictureConfig.CHOOSE_REQUEST:

List selectList = PictureSelector.obtainMultipleResult(data);

try {

if (mUploadMsg != null) {

String path;

if (selectList.get(0).isCompressed()) {

LogUtils.e("getCompressPath) =" + selectList.get(0).getCompressPath());

path = selectList.get(0).getCompressPath();

} else {

path = selectList.get(0).getPath();

}

if (!CheckUtils.isAvailable(path) || !new File(path).exists()) {

LogUtils.e("sourcePath empty or not exists.");

break;

}

File file = new File(path);

Uri uri = Uri.fromFile(file);

mUploadMsg.onReceiveValue(uri);

mUploadMsg = null;

} else if (mValueCallback != null) {

Uri[] uris = new Uri[selectList.size()];

for (int i = 0; i < selectList.size(); i++) {

String path;

if (selectList.get(i).isCompressed()) {

LogUtils.e("getCompressPath) =" + selectList.get(i).getCompressPath());

path = selectList.get(i).getCompressPath();

} else {

path = selectList.get(i).getPath();

}

File file = new File(path);

uris[i] = Uri.fromFile(file);

}

if (uris.length > 0) {

mValueCallback.onReceiveValue(uris);

} else {

LogUtils.e("sourcePath empty or not exists.");

}

break;

}

} catch (Exception e) {

e.printStackTrace();

}

break;

default:

break;

}

}

}

总结和发散

两种方法个人觉得第一种更省事,代码量更小。

脱离webview,其实很多地方我们也会用到多图上传的操作,这时候如果不需要自定义UI、选择数量限制等可以直接使用第一种方法比较省事

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值