android 微信授权、分享、支付之坑——纪念那踩不完的坑

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weimingjue/article/details/80047273

    微信分享的demo更新了,貌似没有以前坑了,最好先把demo改一下再打开。

1.无用的文件删掉否则会报错:Error:Unknown host 'android.oa.com'. You may need to adjust the proxy settings in Gradle,只保留4个:整个app目录、build.gradle、debug.keystore、settings.gradle

2.sdk版本,build tools版本适配版本等

微信支付生成签名什么的最好后台计算,不然别人破解包就gg了。

上面的坑有踩过的请分享至下方谢谢,本人用的友盟所以就没去踩了。

坑一:分享或支付必须创建指定Activity的坑,这个坑微信是不会告诉你的。

分享或支付时必须在项目目录下创建wxapi>WXEntryActivity或者WXPayEntryActivity并且该Activity必须实现IWXAPIEventHandler接口。这样还会引发耦合性较高的问题,其他界面的分享或支付逻辑不一样的情况下会出现如下代码:

    public static int AAA = 0;
    @Override
    public void onResp(BaseResp resp) {
        switch (AAA){
            case 1:
                //a界面
                break;
            case 2:
                //b界面
                break;
            case 3:
                //c界面
                break;
            //...n界面
            default:
                break;
        }
    }

然后动态改AAA的值,这样Activity不仅杂乱难堪,还难以维护,如果注释不够清晰,这里的代码等同于天书。建议这样修改

    private static OnWXListener mListener = null;
    private static WeakReference<Activity> mActivity = null;
    public static final int DEFAULT_WXTIME = 300;
    private static int mTime = DEFAULT_WXTIME;
    private static OnCancelClickListener<Void> mTimeListener = null;

    @Override
    public void onReq(BaseReq req) {
        if (mListener != null) {
            mListener.onReq(req);
            mListener = null;
        }
        finish();
    }

    @Override
    public void onResp(BaseResp resp) {
        if (mListener != null) {
            mListener.onResp(resp);
            mListener = null;
        }
        finish();
    }

    public static void setResultListener(Activity activity, OnWXListener listener) {
        if (mListener != null) {
            mListener.onError(OnWXListener.TYPE_REPLACE);
        }
        mActivity = new WeakReference<>(activity);
        mListener = listener;
        if (mTimeListener == null) {
            mTimeListener = new OnCancelClickListener<Void>() {
                @Override
                public void clickCancel(Void aVoid) {
                    mTime--;
                    Activity ac = mActivity.get();
                    if (ac == null || ac.isFinishing()) {
                        clear();
                    }
                    if (mTime < 0) {
                        if (mListener != null) {
                            mListener.onError(OnWXListener.TYPE_TIMEOUT);
                        }
                        clear();
                    }
                }

                void clear() {
                    TimeUtil.removeTimeListener(this);//取消回调
                    mActivity = null;
                    mListener = null;
                    mTime = WXEntryActivity.DEFAULT_WXTIME;
                }
            };
        }
        mTime = DEFAULT_WXTIME;
        TimeUtil.addTimeListener(mTimeListener);//这个只是1秒回调一次的handler
    }

    /**
     * 把微信支付解耦,只需要调这个方法即可
     */
    public static void WXPay(Activity activity, WXCode wc/*后台返回的支付数据*/, OnWXListener listener) {
        setResultListener(activity, listener);
        IWXAPI api = WXAPIFactory.createWXAPI(MyApplication.mApp/*此处一定要传application的Context,不然就是内存泄漏*/, wc.appid);
        api.registerApp(wc.appid);
        if (!api.isWXAppInstalled()) {
            Utils.toast("您可能没有安装微信!");
        }
        PayReq request = new PayReq();
        request.appId = wc.appid;
        request.partnerId = wc.mch_id;
        request.prepayId = wc.prepay_id;
        request.packageValue = "Sign=WXPay";//随机码,如果想要安全,可以生成一个
        request.nonceStr = wc.nonce_str;
        request.timeStamp = String.valueOf(wc.timestamp);
        request.sign = wc.paySign;
        api.sendReq(request);
    }

    public static abstract class OnWXListener {
        //错误类型:请求超时,没有回调并被新的分享或支付替换
        public static final int TYPE_TIMEOUT = 0, TYPE_REPLACE = 1;

        @IntDef({TYPE_TIMEOUT, TYPE_REPLACE})
        @Retention(RetentionPolicy.SOURCE)
        public @interface type {
        }//该变量只能传入上面几种,否则会报错

        //微信主动调app
        public void onReq(BaseReq req) {
        }

        //app调授权支付等
        public abstract void onResp(BaseResp resp);

        /**
         * @param errType {@link #TYPE_TIMEOUT}{@link #TYPE_REPLACE}
         */
        public abstract void onError(@OnWXListener.type int errType);
    }

这是WXPayEntryActivity的例子,只要调用WXPayEntryActivity.WXPay方法,传入指定参数和回调即可,分享也可以参考参考

坑二:开放平台的签名问题,微信也不会告诉你的。

签名是个深坑,请多次确认你的签名格式正确,正确格式:MD5并且没有冒号(没有冒号!没有冒号!),不区分大小写。

如果签名写的是SHA1,那么恭喜你重填;

如果直接copy签名算出来的MD5值,那么恭喜你,算出来的基本都带冒号;

如果已经确认内容正确,那么请看《坑三》。

坑三:微信缓存之巨坑,微信更不可能告诉你了。

如果你的签名或包名写错了,并且修改完全正确后仍然不能授权或者支付一次之后总是提示通信失败,那么恭喜入坑。

原因:你改的数据确实立即保存到微信服务器端了,但是微信app端会在第一次授权时会把签名缓存到本地,这个手机第一次授权得到了错误的签名,后面再授权都是一样。

解决方式大致3种:1.退出登录再重新登录;2.清除微信缓存(不是清除数据);3.如果以上两种都不行,只能清除数据或者卸载重装(用户操作后不知道会不会想念妖妖灵睡觉

目前先把这三个坑记录下来,之前的小坑可能已经忘了

猜你喜欢

转载自blog.csdn.net/weimingjue/article/details/80047273