支付宝扫描支付——app端无法显示二维码等问题的解决方式

ok首先说明一下,下面说的使用 即时到账方式,服务端获取到了一个订单的支付地址,而app端我们做的就是使用WebView来显示二维码的操作,涉及到二维码地址的请求,这一部分有服务端来做。


一、主要涉及的问题

  1. WebView 不能显示二维码,出现网站已迁移的问题
  2. 退出了Activity,但是网页还在不停的请求
  3. https需要证书
  4. 如何判断支付成功

二、问题解决的方式

(1) 第一个问题可能由以下两种原因引起
  1. WebView木有加代理
    解决方式
    加代理

    /**
     * 加这个代理的原因是: 以前是不需要加这个的,现在必须加这个,现在不加这个会出现(无法连接网络)这个错误,加上用户代理
    */
    payWv.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36
  2. 木有接受网站的证书(就是第三个问题)
    解决方式
    创建一个 WebViewClient 的子类MyWebViewClient,重写这个类中的onReceivedSslError方法,接受网站的证书

             /**
             * 处理https请求的时候,需要加上下面这个代码(接受证书),不然有的手机无法请求https(例如:ml)
             */
            @Override
            public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                           SslError error) {
                handler.proceed();// 接受所有网站的证书
                Log.i("MyWebViewClient", "接受证书");
            }

(2)第二个问题的解决方式

重写onKeyDown方法,退出时,把WebView 销毁掉

     /**
      * 按下返回键的时候 退出Activity 并且destroy掉 webView
      * 不destory 掉的话,webview会一直请求网路 除非整个应用关闭,
      * 所以添加上了 webView.destroy操作。
      */
     @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
         if(keyCode==KeyEvent.KEYCODE_BACK){
            payWv.destroy();
            finish();
         }
        return false;
    }

(3)第三个问题的解决方式

这个问题的解决方式和第一个问题中的第二个解决方式一样
创建一个 WebViewClient 的子类,重写这个类中的onReceivedSslError方法,接受网站的证书

         /**
         * 处理https请求的时候,需要加上下面这个代码(接受证书),不然有的手机无法请求https(例如:ml)
         */
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                       SslError error) {
            handler.proceed();// 接受所有网站的证书
            Log.i("MyWebViewClient", "接受证书");
        }

(4)第四个问题的解决方式

支付成功,我们的网页地址会调到一个支付成功的界面(地址是:https://tradeexprod.alipay.com/cashiergw/cashierReturnMiddlePage.htm?,后面带一些参数),这时候,我们可以在MyWebViewClient中的shouldOverrideUrlLoading方法中判断,url是不是的开始部分是不是上面这个网址。

 @Override
 public boolean shouldOverrideUrlLoading(WebView view, String url) {                           
       if(url.startsWith("https://tradeexprod.alipay.com/cashiergw/cashierReturnMiddlePage.htm?")){
                //这里面就是支付成功,以后的操作  ,这里面我们是调到支付成界面
                startActivity(new Intent(MainActivity.this,PayOk.class));
            }  
            view.loadUrl(url);
            return true;
 }

三、代码示例

这里主要说明一哈,我们获取到的二维码,有好几种格式,这里我们选择的是 2
类型(长度范围) 是否可为空 样例

参数参数名称参数说明
qr_pay_mode扫码支付方式扫码支付的方式,支持前置模式和跳转模式。前置模式是将二维码前置到商户的订单确认页的模式。需要商户在自己的页面中以iframe方式请求支付宝页面。具体分为以下3种:1、订单码-简约前置模式,对应iframe宽度不能小于600px,高度不能小于300px;2、订单码-前置模式,对应iframe宽度不能小于300px,高度不能小于600px;3、订单码-迷你前置模式,对应iframe宽度不能小于75px,高度不能小于75px。跳转模式下,用户的扫码界面是由支付宝生成的,不在商户的域名下。4、订单码-跳转模式

具体可以看 支付宝开放平台api–即时到账

根据生成的二位的大小,我们来定义WebView的宽和高,ok也许你也想到了,我们的这个WebView应该不能滑动放大之类的,so easy 我们写一个WebView的子类,屏蔽掉它的触摸事件就ok了。


(1)NoScorWbView
package com.xm.alipayxmdemo1;
import android.content.Context;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.webkit.WebView;
/**
* @author:qiwenming
        * @date:2015/8/28 0028 下午 5:14
        * @instruction
*/
public class NoScorWbView extends WebView {


    public NoScorWbView(Context context) {
        super(context);
    }

    public NoScorWbView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public NoScorWbView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    /**
     *让这个webview 无法响应触摸事件
     */
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        return true;
    }
}
(2)activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"     android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">
    <com.xm.alipayxmdemo1.NoScorWbView
        android:layout_centerInParent="true"
        android:id="@+id/sdwv_apy"
        android:layout_width="290dp"
        android:layout_height="290dp" />
</RelativeLayout>

(3)MainActivity
package com.xm.alipayxmdemo1;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.net.http.SslError;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.KeyEvent;
import android.webkit.SslErrorHandler;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class MainActivity extends Activity {

    private WebView payWv;
    private ProgressDialog dialog;
    Runnable runnable;
    Handler handler;
    private String payUrl = "你获取到二维码的支付地址";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        payWv = (WebView)findViewById(R.id.sdwv_apy);
        payWv.getSettings().setJavaScriptEnabled(true);
        payWv.setWebViewClient(new MyWebViewClient());
        /**
         * 加这个代理的原因是: 以前是不需要加这个的,现在必须加这个,现在不加这个会出现(无法连接网络)这个错误,加上用户代理
         */
        payWv.getSettings().setUserAgentString("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36");
        payWv.loadUrl(payUrl);

        //这是用于控制我们的进度框显示的
        runnable = new Runnable() {
            @Override
            public void run() {
                // TODO Auto-generated method stub
//                  webView.loadUrl("javascript:window.local_obj.dimissDialog()");
                if(dialog != null && dialog.isShowing())
                    dialog.dismiss();
            }
        };
        handler = new Handler();
        dialog = ProgressDialog.show(this, null, "正在加载中。。。", true, true);
    }


    class MyWebViewClient extends WebViewClient{
        /**
         * 处理https请求的时候,需要加上下面这个代码(接受证书),不然有的手机无法请求https(例如:ml)
         */
        @Override
        public void onReceivedSslError(WebView view, SslErrorHandler handler,
                                       SslError error) {
            handler.proceed();// 接受所有网站的证书
            Log.i("MyWebViewClient", "接受证书");
        }

        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url) {
            if(url.startsWith("https://tradeexprod.alipay.com/cashiergw/cashierReturnMiddlePage.htm?")){
                //这里面就是支付成功,以后的操作  ,这里面我们是调到支付成界面
                startActivity(new Intent(MainActivity.this,PayOk.class));
            }
            view.loadUrl(url);
            return true;
        }
        @Override
        public void onPageFinished(final WebView view, String url) {
            Log.d("MyWebViewClient","onPageFinished---url="+url);
            //加载完成以后,需要把我么的dialog关了
            handler.removeCallbacks(runnable);
            handler.postDelayed(runnable, 2000);
            super.onPageFinished(view, url);
        }
    }

    /**
     * 按下返回键的时候 退出Activity 并且destroy掉 webView
     * 不destory 掉的话,webview会一直请求网路 除非整个应用关闭,
     * 所以添加上了 webView.destroy操作。
     */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if(keyCode== KeyEvent.KEYCODE_BACK){
            payWv.destroy();
            finish();
        }
        return false;
    }

}

四、演示与源码下载

效果图

源码下载

<script type="text/javascript"> $(function () { $('pre.prettyprint code').each(function () { var lines = $(this).text().split('\n').length; var $numbering = $('<ul/>').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('<li/>').text(i)); }; $numbering.fadeIn(1700); }); }); </script>
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值