公司项目嵌套了一个H5链接,链接中有上传图片跟上传文件的功能, 开始以为直接用webView加载就直接可以了,因为调的是系统的,而且同样一个链接IOS可以,什么都不用兼容,微信打开浏览器也可以,但是如果你单纯的以为webView加载就能完成此功能,那你就真的错了,大坑等着你一点一点填呢 首先先上图公司的需求
开始我也以为就是简单的给权限就行,既然是H5自己上传,还需要我们改什么啊,但是后来怎么也都不能实现,后来一查是因为webView不支持上传图片需要监听他的事件,一顿猛操作以后渐入佳境,虽然满足了公司的需求,但是有几点疑惑我也不知道为什么呢
啥也不说直接贴代码
webView.setWebChromeClient(new WebChromeClient() {//监听网页加载
@Override
public void onProgressChanged(WebView view, int newProgress) {
super.onProgressChanged(view, newProgress);
}
@Override
public void onReceivedTitle(WebView view, String title) {
super.onReceivedTitle(view, title);
}
public void openFileChooser(ValueCallback<Uri> uploadMsg) {
L.e("点击1");
L.e("监听点击按钮");
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType) {
L.e("点击3---acceptType==" + acceptType);
openFileChooser(uploadMsg);
L.e("点击3");
}
public void openFileChooser(ValueCallback<Uri> uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg);
L.e("点击4", "4");
}
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
public boolean onShowFileChooser(WebView mWebView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
L.e("onShowFileChooser");
String acceptType = fileChooserParams.getAcceptTypes()[0];
L.e("onShowFileChooser---acceptType=" + acceptType);
if (acceptType.contains("image/*")) {
if (uploadMessage != null) {
uploadMessage.onReceiveValue(null);
uploadMessage = null;
}
uploadMessage = filePathCallback;
ImgUtil.choicePhoto(WebViewH5PublicActivity.this);
} else {
uploadMessageAboveL = filePathCallback;
// openImageChooserActivity(fileChooserParams.getAcceptTypes());
// Uri uri = Uri.parse("content://com.android.externalstorage.documents/document/primary:Download%2fWeiXin");
// L.e("uri.getPath===" + uri.getPath());
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
// intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI);
intent.addCategory(Intent.CATEGORY_OPENABLE);
startActivityForResult(intent, FILE_CHOOSER_RESULT_CODE);
}
return true;
}
});
```
疑惑一 我有个疑惑不知道为什么第三方的H5链接再点击相册照片的时候跟选择文件的时候事件是一样的,同时调用onShowFileChooser,而且acceptType 在文件上传的时候他返回的参数居然是空,选择照片的时候没有问题
acceptType返回image/* 所以我这样区分了一下然后跳转不同的操作
回调代码
@RequiresApi(api = Build.VERSION_CODES.LOLLIPOP) @Override protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
if (resultCode == RESULT_OK) {//正确返回
switch (requestCode) {
case ImgUtil.FILE_CHOOSER_RESULT_CODE://选择文件
if (intent != null) {
if (null == uploadMessage1 && null == uploadMessageAboveL) return;
Uri resultDoc = intent == null || resultCode != RESULT_OK ? null : intent.getData();
if (uploadMessageAboveL != null) {
onActivityResultAboveL(requestCode, resultCode, intent);
} else if (uploadMessage != null) {
uploadMessage1.onReceiveValue(resultDoc);
uploadMessage1 = null;
}
} else {
clearUploadMessage();
}
break;
case ImgUtil.TAKE_PHOTO://相机返回
L.e("返回相机" + ImgUtil.imageUri.toString());
//相机返回rui
//Uri uriTake = ImgUtil.imageUri;
Uri uriTake = null;
try {
uriTake = ImgUtil.getCompressUri(WebViewH5PublicActivity.this, ImgUtil.imageUri);
} catch (IOException e) {
e.printStackTrace();
}
//显示在页面
if (uploadMessage == null) return;
Uri[] imgTaskUris = {uriTake};
uploadMessage.onReceiveValue(imgTaskUris);
uploadMessage = null;
if (null == mUploadMessage) return;
Uri result = intent == null || resultCode != MainActivity.RESULT_OK ? null : uriTake;
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
break;
case ImgUtil.CHOOSE_PHOTO://相册返回
try {
if (intent != null) {
//相册返回
Log.e("返回", "intent2:" + intent.getData().toString() + "..." + uploadMessage);
//相册返回uri
//Uri uriChoose = intent.getData();
Uri uriChoose = ImgUtil.getCompressUri(WebViewH5PublicActivity.this, intent.getData());
//显示在页面
if (uploadMessage == null) return;
Uri[] imgChooseUris = {uriChoose};
uploadMessage.onReceiveValue(imgChooseUris);
//uploadMessage.onReceiveValue(WebChromeClient.FileChooserParams.parseResult(resultCode, intent));
uploadMessage = null;
Log.e("返回", "intent3:" + WebChromeClient.FileChooserParams.parseResult(resultCode, intent).toString());
}
break;
} catch (Exception e) {
e.printStackTrace();
// ToastUtils.getToastEmail().ToastShowFail(this, "图片选择失败"); clearUploadMessage(); } break; } } else { clearUploadMessage(); // ToastUtils.getToastEmail().ToastShowFail(this, "图片选择失败"); } }
/*
android 5.0
多文件的结果返回处理
*/
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private void onActivityResultAboveL(int requestCode, int resultCode, Intent intent) {
Log.d("test1234", "onActivityResultAboveL");
if (requestCode != FILE_CHOOSER_RESULT_CODE || uploadMessageAboveL == null)
return;
Uri[] results = null;
if (resultCode == Activity.RESULT_OK) {
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)};
}
}
uploadMessageAboveL.onReceiveValue(results);
uploadMessageAboveL = null;
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
switch (requestCode) {
case ImgUtil.REQUEST_CODE_ALBUM://相册存储权限
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
ImgUtil.openAlbum(this);
} else {
ToastUtils.getToastEmail().ToastShowFail(this, "选择图库需要同意权限");
}
break;
case ImgUtil.REQUEST_CODE_CAMERA://相机拍照权限
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {//允许
ImgUtil.openCamera(WebViewH5PublicActivity.this);
} else {//拒绝
ToastUtils.getToastEmail().ToastShowFail(this, "只有同意相机权限,才能使用扫码功能");
}
break;
default:
}
}
clearUploadMessage(); 这个方法是必须的以防止不选择文件或是图片的时候再次点击H5没反应
为了兼容一些上传文件在H5链接里边不显示故而在shouldOverrideUrlLoading适配一下,让其跳转到
```系统浏览器去下载再查看
public WebViewClient getWebViewClient() {
return new WebViewClient() {
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String strUrl) {
L.d("shouldOverrideUrlLoading---url:" + strUrl);
// if (StrUrl.contains("city/list")) {
// L.d("city/list");
// }
if (strUrl.startsWith("tel:")) {
Intent intent = new Intent(Intent.ACTION_VIEW,
Uri.parse(strUrl));
startActivity(intent);
return true;
}
if (strUrl.contains(".doc") || strUrl.contains(".pdf") || strUrl.contains(".mp4")
|| strUrl.contains(".xlsx") || strUrl.contains(".xls") || strUrl.contains(".docx")) {
CloseLockTipDialog closeLockTipDialog = new CloseLockTipDialog(WebViewH5PublicActivity.this, "");
closeLockTipDialog.show();
TextView cancle_info = closeLockTipDialog.findViewById(R.id.cancle_info);
TextView submit_info = closeLockTipDialog.findViewById(R.id.submit_info);
TextView text_two = closeLockTipDialog.findViewById(R.id.text_two);
text_two.setText("即将离开app,在浏览器中打开");
cancle_info.setText("取消");
cancle_info.setTextColor(Color.parseColor("#333333"));
submit_info.setText("允许");
cancle_info.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
closeLockTipDialog.dismiss();
}
});
submit_info.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Uri uri = Uri.parse(strUrl);
Intent intent = new Intent(Intent.ACTION_VIEW, uri);
startActivity(intent);
closeLockTipDialog.dismiss();
}
});
}
webView.loadUrl(strUrl);
return false;
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
@Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
super.onReceivedError(view, errorCode, description, failingUrl);
L.d("errorCode:" + errorCode + "|failingUrl:" + failingUrl);
}
@Override
public void onReceivedSslError(WebView view, SslErrorHandler handler, SslError error) {
super.onReceivedSslError(view, handler, error);
handler.cancel();
handler.proceed();
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
MDialog.hideLoading();
}
};
}
此代码不是原创,有网上的其他博主的代码 有自己修改的添加的东西,写此文章只是为了记录一下,填坑的日子