webview与h5的交互——上传文件& 吊起本地支付&
拦截js alert 转成原生dialog
&back键层级返回
一.上传文件
套页是我们经常方便的时候套用的东西,现在x5可轻松实现图文浏览,word,表格等一些数据的编写和查看,关注鸿洋的公众号,看了他那篇文章,对x5才慢慢了解,但是今天主要说的还不是x5,而是我前段时间套页,页面涉及到一些认证和身份证图片需要上传,所以难了我一段时间,因为我看到ios直接把地址甩到他们的原生框架中,就直接拉起来了而且上传图片没有一点问题,但是到我们安卓了,我就蒙了,怎么点击也都是没有反应,打开支持js开关也没用,后来发现原来我们需要再处理的,代码如下:
WebView webview = (WebView) findViewById(R.id.
web);
imgBack = (ImageView) findViewById(R.id.
imgBack);
imgBack.setOnClickListener(
this);
webview.getSettings().setJavaScriptCanOpenWindowsAutomatically(
true);
//设置js可以直接打开窗口,如window.open(),默认为false
webview.getSettings().setJavaScriptEnabled(
true);
//是否允许执行js,默认为false。设置true时,会提醒可能造成XSS漏洞
webview.getSettings().setSupportZoom(
true);
//是否可以缩放,默认true
webview.getSettings().setBuiltInZoomControls(
true);
//是否显示缩放按钮,默认false
webview.getSettings().setUseWideViewPort(
true);
//设置此属性,可任意比例缩放。大视图模式
webview.getSettings().setLoadWithOverviewMode(
true);
//和setUseWideViewPort(true)一起解决网页自适应问题
webview.getSettings().setAppCacheEnabled(
true);
//是否使用缓存
webview.getSettings().setDomStorageEnabled(
true);
//DOM Storage
webview.getSettings().setJavaScriptEnabled(
true);;
//DOM Storage
LoginBean.DataBean userInfo = Preferences.
getUserInfo();
webview.loadUrl(
"http://xxxxxxxxxxxxxxxxxxxxxxx");
webview.setWebChromeClient(
new MyChromeClient());
WebSettings webSettings = webview.getSettings();
webSettings.setJavaScriptEnabled(
true);
webview.setWebViewClient(
new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
/**
* 在此处监听网页事件 并打开相册
*/
class MyChromeClient
extends WebChromeClient {
public boolean onShowFileChooser(android.webkit.WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
isHighV =
true;
mUploadMessage1 = filePathCallback;
GalleryActivity.
openActivity(Web.
this,
true,
100);
return true;
}
// For Android 3.0+
public void openFileChooser(ValueCallback uploadMsg) {
mUploadMessage = uploadMsg;
isHighV =
false;
//打开图库 用的compile 'com.library.tangxiaolv:telegramgallery:1.0.1'框架
GalleryActivity.
openActivity(Web.
this,
true,
100);
}
//3.0--版本
public void openFileChooser(ValueCallback uploadMsg, String acceptType) {
openFileChooser(uploadMsg);
}
// For Android 4.1
public void openFileChooser(ValueCallback uploadMsg, String acceptType, String capture) {
openFileChooser(uploadMsg);
}
}
/**
* onActivityResult里通过onReceiveValue方法将uri给js
* @param requestCode
* @param resultCode
* @param data
*/
@Override
protected void onActivityResult(
int requestCode,
int resultCode, Intent data) {
if(data==
null){
return;
}
if (
isHighV) {
//高版本
List<String> photos = (List<String>) data.getSerializableExtra(GalleryActivity.
PHOTOS);
String result = photos.get(
0);
if (
null ==
mUploadMessage1)
return;
Uri[] c =
new Uri[
1];
Uri uri = getUri(result);
c[
0] = uri;
mUploadMessage1.onReceiveValue(c);
mUploadMessage1 =
null;
return;
}
else {
//低版本
List<String> photos = (List<String>) data.getSerializableExtra(GalleryActivity.
PHOTOS);
String result = photos.get(
0);
if (
null ==
mUploadMessage)
return;
Uri uri = getUri(result);
mUploadMessage.onReceiveValue(uri);
mUploadMessage =
null;
return;
}
}
/**
* path转uri
*/
private Uri getUri(String path) {
Uri uri =
null;
if (path !=
null) {
path = Uri.
decode(path);
ContentResolver cr =
this.getContentResolver();
StringBuffer buff =
new StringBuffer();
buff.append(
"(")
.append(MediaStore.Images.ImageColumns.
DATA)
.append(
"=")
.append(
"'" + path +
"'")
.append(
")");
Cursor cur = cr.query(
MediaStore.Images.Media.
EXTERNAL_CONTENT_URI,
new String[]{MediaStore.Images.ImageColumns.
_ID},
buff.toString(),
null,
null);
int index =
0;
for (cur.moveToFirst(); !cur.isAfterLast(); cur
.moveToNext()) {
index = cur.getColumnIndex(MediaStore.Images.ImageColumns.
_ID);
index = cur.getInt(index);
}
if (index ==
0) {
}
else {
Uri uri_temp = Uri.
parse(
"content://media/external/images/media/" + index);
if (uri_temp !=
null) {
uri = uri_temp;
}
}
}
return uri;
}
二.吊起本地支付
实际上是通过js和安卓的交互实现的,首先封装一个hiWebview,里面添加上js方法:
@JavascriptInterface
public void webPayOrder(
final String orderInfoString,
final String callbackFun) {
webHandler.post(
new Runnable() {
@Override
public void run() {
Log.
e(
"支付宝",
"参数1======"+
orderInfoString);
Log.
e(
"支付宝",
"参数2======"+
callbackFun);
if (
onWebViewEvent !=
null)
onWebViewEvent.payOrder(
orderInfoString,
callbackFun);
}
});
当被调用时,webview走
hiWebview的实现,当被调用时重写该方法:
/**
* 支付宝支付
*/
@Override
public void payOrder(
final String orderInfoString,
final String callbackFun) {
try {
new Thread() {
public void run() {
// 构造PayTask 对象
PayTask alipay =
new PayTask(WebViewActivity.
this);
// 调用支付接口,获取支付结果
String result = alipay.pay(
orderInfoString);
Message msg =
new Message();
msg.
what =
SDK_PAY_FLAG;
msg.
obj = result;
Bundle data =
new Bundle();
data.putString(
"callback",
callbackFun);
data.putString(
"result", result);
msg.setData(data);
mHandler.sendMessage(msg);
}
}.start();
}
catch (Exception ex) {
ex.printStackTrace();
Toast.
makeText(WebViewActivity.
this, R.string.
alipay_pay_error,
Toast.
LENGTH_SHORT).show();
}
}
/**
* 微信支付
*/
@Override
public void wxPayOrder(String orderInfoString, String callbackFun) {
wxPayCallBack = callbackFun;
String partnerId=
"",prepayId=
"",nonceStr=
"",timeStamp=
"",sign=
"";
int ret =
0;
try {
String jsonContent = URLDecoder.
decode(orderInfoString,
"UTF-8");
JSONTokener parser =
new JSONTokener(jsonContent);
JSONObject json = (JSONObject) parser.nextValue();
partnerId = json.optString(
"partnerId");
prepayId = json.optString(
"prepayId");
nonceStr = json.optString(
"nonceStr");
timeStamp = json.optString(
"timeStamp");
sign = json.optString(
"sign");
if (partnerId.isEmpty() || prepayId.isEmpty() || nonceStr.isEmpty() || timeStamp.isEmpty() || sign.isEmpty())
{
showToast(
"参数不全");
webView.loadUrl(
"javascript:" +
wxPayCallBack +
"(0)");
return;
}
PayReq req;
if (!
msgApi.isWXAppInstalled())
{
showToast(
"没有安装微信");
webView.loadUrl(
"javascript:" +
wxPayCallBack +
"(0)");
return;
}
if (!
msgApi.isWXAppSupportAPI())
{
showToast(
"当前微信版本不支持支付功能");
webView.loadUrl(
"javascript:"+
wxPayCallBack+
"(0)");
return;
}
req =
new PayReq();
req.
appId = Contants.
WEIXIN_APP_ID;
req.
partnerId = partnerId;
req.
prepayId = prepayId;
req.
nonceStr = nonceStr;
req.
timeStamp = timeStamp;
req.
packageValue =
"Sign=WXPay";
req.
sign = sign;
// req.extData = "app data"; // optionall
Toast.
makeText(WebViewActivity.
this,
"正常调起支付", Toast.
LENGTH_SHORT).show();
// 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信
boolean bz =
msgApi.sendReq(req);
if (bz)
Log.
v(
"t",
"OK");
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (JSONException e) {
e.printStackTrace();
}
catch (Exception e) {
e.printStackTrace();
}
}
三.拦截js alert 转成原生dialog
@Override
public boolean onJsAlert(WebView view, String url, String message,
final JsResult result) {
final NoticeDialog dialog =
new NoticeDialog(EnjoyWingActivity.
this,
"",message,
"确认");
dialog.show();
dialog.setNoticeListener(
new NoticeDialog.NoticeListener() {
@Override
public void doConfirm() {
dialog.dismiss();
result.cancel();
}
@Override
public void doCancel() {
dialog.dismiss();
}
});
return true;
}
四.back键层级返回
/**
* 处理webview的返回
*/
@Override
public void onBackPressed() {
if(
"确认订单".equals(
topTitle)){
finish();
return;
}
if (
webView.canGoBack()){
if(
webView.getUrl().equals(
strNavUrl)){
super.onBackPressed();
}
else{
webView.goBack();
}
}
else{
super.onBackPressed();
}
}