android webview调起微信h5支付以后发生了什么
webview调起微信h5支付
先把webview调起微信h5支付的代码贴一下,网上都有
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_webview_privacy);
ButterKnife.bind(this);
setToolBar(R.id.toolbar, true);
toolbar.setNavigationOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View view)
{
if (webView.canGoBack())
{
webView.goBack();// 返回前一个页面
}
else
{
finish();
}
}
});
Intent intent = getIntent();
action = (WebviewForAppointActivity.WebAction) intent.getSerializableExtra(WEBVIEW_ACTION);
actionPatten = intent.getStringExtra(WEBVIEW_ACTION_PATTEN);
isFromHospital = intent.getBooleanExtra(Extras.EXTRA_DATA, false);
if (action == null || actionPatten == null)
{
action = null;
actionPatten = null;
}
initWebView();
String url = getIntent().getStringExtra(WEBVIEW_URL);
if (TextUtils.isEmpty(url))
{
ToastUtil.showLongToast("地址错误,地址不能为空");
return;
}
else
{
referer = getIntent().getStringExtra(Extras.EXTRA_DATA2);
if (referer != null && !StringUtil.isEmpty(referer))
{
HashMap<String, String> stringStringHashMap = new HashMap<>();
stringStringHashMap.put("Referer", referer);
webView.loadUrl(url, stringStringHashMap);
}
else
{
webView.loadUrl(url);
}
}
}
public class MyWebViewClient extends WebViewClient
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
{
String url = request.getUrl().toString();
if (!TextUtils.isEmpty(url))
{
if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
{
finish();
return false;
}
if (url.startsWith("weixin://") || url.startsWith("alipays://") || url.startsWith("tel:"))
{
try
{
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
return true;
//防止没有app匹配到action时抛出异常闪返
}
catch (Exception ignored)
{
ignored.printStackTrace();
final NoticeDialog noticeDialog = new NoticeDialog(WebviewForAppointActivity.this);
noticeDialog.setLinearLayoutInputVisible(false);
noticeDialog.setTitle("提示");
noticeDialog.setNoticeContent("您尚未安装微信,不能支付?");
noticeDialog.setSubmitButtonText("确定");
noticeDialog.setCancelButtonText("取消");
noticeDialog.setSubmitListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
finish();
}
});
noticeDialog.setCancelListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
finish();
}
});
noticeDialog.showAtLocation(WebviewForAppointActivity.this.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
}
return super.shouldOverrideUrlLoading(webView, request);
}
else
{
try
{
Map<String, String> extraHeaders = new HashMap<String, String>();
extraHeaders.put("Referer", referer);
view.loadUrl(url, extraHeaders);
referer = url;
return true;//不调用系统的浏览器打开网页
}
catch (Exception e)
{
e.printStackTrace();
}
return true;
}
}
return super.shouldOverrideUrlLoading(view, request);
}
......
}
先解释一下代码:
webview只能识别http://或https://开头的url,微信支付的url以weixin://开头,因此需要用intent调起能处理此scheme开头的url的App
if (url.startsWith("weixin://") || url.startsWith("alipays://") || url.startsWith("tel:"))
如果没有设置,会报错
net::ERR_UNKNOWN_URL_SCHEME
然后要设置Referer,这个是商户申请H5时提交的授权域名,要不然会报错商家参数格式有错
Map<String, String> extraHeaders = new HashMap<String, String>();
extraHeaders.put("Referer", referer);
view.loadUrl(url, extraHeaders);
referer = url;
Webview获取回调
这个回调我试了一下,基本上都在5秒就会调用。webview获取回调以及处理自己逻辑的代码可以这样写
首先在shouldOverrideUrlLoading拦截回调url,这个是redirect_url拼接的,可以由后台返回,然后在webview里写一个接口,再定义一个类来继承,里边操作自己的逻辑,伪代码是这样
//Webview里定义
public interface WebAction extends Serializable
{
void doAction(WebviewForAppointActivity webViewActivity);
}
继承这个接口的类
/**
* Created by hanzj on 2021/10/22
* 查询微信h5支付结果
*/
public class WeiXinH5PayAction implements WebviewForAppointActivity.WebAction
{
private PayQueryParam payQueryParam;
/**
* 查询支付订单
*/
private void payQuery(PayQueryParam payQueryParam, WebviewForAppointActivity webViewActivity)
{
RequestEntity<PayQueryParam> entity = new RequestEntity<>();
entity.setReqData(payQueryParam);
OkHttpUtils.postString().url(Contants.APIURL.POST_APPOINTPayQUERY.getUrl()).headers(entity.getHeader())
.content(entity.getBody()).build().execute(new JsonCallBack<ResponseEntity<PayQueryResults>>()
{
@Override
public void onError(Call call, Exception e, RequestCall requestCall)
{
ToastUtil.showLongToast("服务器繁忙,请您稍后尝试。");
}
@Override
public void onResponse(ResponseEntity<PayQueryResults> data, RequestCall requestCall)
{
if (data.isOK())
{
OnLinePayResultActivity.startActivity(webViewActivity,data.getRstData());
webViewActivity.finish();
}
else
{
OnLinePayResultActivity.startActivity(webViewActivity,null);
webViewActivity.finish();
}
}
});
}
@Override
public void doAction(WebviewForAppointActivity webViewActivity)
{
payQuery(payQueryParam,webViewActivity);
}
public void setPayQueryParam(PayQueryParam payQueryParam){
this.payQueryParam=payQueryParam;
}
}
在webview中拦截调用
action = (WebviewForAppointActivity.WebAction) intent.getSerializableExtra(WEBVIEW_ACTION);
actionPatten = intent.getStringExtra(WEBVIEW_ACTION_PATTEN);
public class MyWebViewClient extends WebViewClient
{
@Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
{
WebView.HitTestResult hitTestResult = view.getHitTestResult();
Log.e("shouldOverrideUrlLoading", TimeUtil.getBeijingNowTime("HHmmss"));
String url = request.getUrl().toString();
if (!TextUtils.isEmpty(url))
{
if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
{
action.doAction(WebviewForAppointActivity.this);
return true;
}
}
....
当然,要是嫌麻烦的话,可以直接在
if (actionPatten != null && url.lastIndexOf(actionPatten) != -1)
{
}
处理逻辑
我的逻辑
我这边的逻辑是,支付的时候,直接打开支付页面,然后5秒以后就会调回调接口,我捕捉到这个url,因为回调地址是域名,webview会显示404,用户体验不好,我就加载成空白页,然后弹出对话框,提示用户支付完成或者未完成,然后关闭webview
public class MyWebViewClient extends WebViewClient{
if (actionPatten != null && url.lastIndexOf(actionPatten) != -1&&
!isFromHospital)
{
webView.loadUrl("about:blank ");
final NoticeDialog noticeDialog = new NoticeDialog(WebviewForAppointActivity.this);
noticeDialog.setLinearLayoutInputVisible(false);
noticeDialog.setTitle("提示");
noticeDialog.setNoticeContent("是否完成支付?");
noticeDialog.setSubmitButtonText("已完成");
noticeDialog.setCancelButtonText("未完成");
noticeDialog.setSubmitListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
finish();
}
});
noticeDialog.setCancelListener(new View.OnClickListener()
{
@Override
public void onClick(View v)
{
noticeDialog.dismiss();
finish();
}
});
noticeDialog.showAtLocation(WebviewForAppointActivity.this.getWindow().getDecorView(), Gravity.CENTER, 0, 0);
return false;
}
}
调起支付以后,发生了什么
支付页面弹出以后,会发生什么?原理我还没深究,我先说一下我这边的研究情况
是否调起微信app
我把支付url放到手机浏览器中,会调起微信app,但是在webview中发起支付,我看了一下打开的支付页面,并没有在微信中打开,所以并没有唤起微信app
是否在网页中支付
没唤起微信app,那是不是就在当前webview加载的网页中支付了呢,为了测试这个情况,我果断删除了微信app,结果支付报错,那就是没有在当前网页支付,还是需要依赖微信app
支付页面是否加载在webview中
难道支付页面,是在自己app的webview中加载的吗?为了测试这个问题,我在回调url加载以后,finish掉webview的页面,发现支付页面不受影响,关闭支付以后,回到webview前一个页面,说明支付页面并没有加载在webview中
支付页面是依赖本app吗
那不在webview中加载,是否依赖于调起支付的app呢。为了测试这个问题,我直接在回调url加载以后,杀掉了整个进程,然后发现支付页面依然存在,结论就是支付页面不依赖调起他的app
结论
通过以上观察,调起支付页面以后,就会超出我们的控制,自己app不能控制这个支付过程和结果,所以要主动查询,一般5秒会调用回调url,在这里我们可以弹出提示框,在其他页面可以进行主动查询支付情况
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgfahhh
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01