Android集成支付宝支付、微信支付、微信分享

Tags

1、支付宝支付

1、在AndroidManifest.xml文件里面添加声明

<activity
            android:name="com.alipay.sdk.app.H5PayActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
</activity>
<activity
            android:name="com.alipay.sdk.auth.AuthActivity"
            android:configChanges="orientation|keyboardHidden|navigation"
            android:exported="false"
            android:screenOrientation="behind" >
 </activity>

2、权限声明

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

3、封装的支付宝辅助类

因为这里我们的payInfo由自己的服务器端生成了,所以,直接封装了下面的一个辅助类:
public class AliHelper {

    //阿里支付
    public static Observable<String> pay(Activity activity, String payInfo) {
        return Observable.create(subscriber -> {
            if (subscriber.isUnsubscribed()) return;
            try {
                PayTask task = new PayTask(activity);
                String result = task.pay(payInfo, true);
                PayResult payResult = new PayResult(result);
                String resultStatus = payResult.getResultStatus();
                subscriber.onNext(resultStatus);
                subscriber.onCompleted();
            } catch (Exception e) {
                subscriber.onError(e);
            }
        });
    }
}
这里的PayResult是支付宝的demo中的:
public class PayResult {
	private String resultStatus;
	private String result;
	private String memo;

	public PayResult(String rawResult) {

		if (TextUtils.isEmpty(rawResult))
			return;

		String[] resultParams = rawResult.split(";");
		for (String resultParam : resultParams) {
			if (resultParam.startsWith("resultStatus")) {
				resultStatus = gatValue(resultParam, "resultStatus");
			}
			if (resultParam.startsWith("result")) {
				result = gatValue(resultParam, "result");
			}
			if (resultParam.startsWith("memo")) {
				memo = gatValue(resultParam, "memo");
			}
		}
	}

	@Override
	public String toString() {
		return "resultStatus={" + resultStatus + "};memo={" + memo
				+ "};result={" + result + "}";
	}

	private String gatValue(String content, String key) {
		String prefix = key + "={";
		return content.substring(content.indexOf(prefix) + prefix.length(),
				content.lastIndexOf("}"));
	}

	/**
	 * @return the resultStatus
	 */
	public String getResultStatus() {
		return resultStatus;
	}

	/**
	 * @return the memo
	 */
	public String getMemo() {
		return memo;
	}

	/**
	 * @return the result
	 */
	public String getResult() {
		return result;
	}
}

4、在项目中调用支付宝支付:

这里的aliPay()的我调用的一个网络接口,返回服务端的payInfo信息,然而根据该payInfo信息,去调用AliHelper.pay()
BaseApplication.getWebInterface()
        .aliPay(new AliPayRequest(1, moneyNum))
        .flatMap(response -> AliHelper.pay(getActivity(), response.getPayInfo()))
        .compose(new WebTransformer<>())
        .subscribe(new WebSubscriber<String>() {
            @Override
            public void onSuccess(String status) {
                LogUtil.print("status:" + status);
                SkipHelper.gotoPayResult(getActivity(), status);
            }
        });
这里的SkipHelper.gotoPayResult()只是我封装的一个应用跳转管理类而已:
    public static void gotoPayResult(Context context, String status) {
        Intent intent = new Intent();
        intent.setAction(IntentAction.ACTIVITY_PAYRESULT);
        intent.setPackage(context.getPackageName());
        intent.putExtra(IntentKey.TOPUP_STATUS, status);
        context.startActivity(intent);
    }
支付结果页就没什么可以说的了:
public class PayResultActivity extends BaseActivity {

    public final static String TAG = IntentAction.ACTIVITY_PAYRESULT;

    @BindView(R.id.view_success)
    LinearLayout viewSuccess;
    @BindView(R.id.view_failure)
    LinearLayout viewFailure;

    private String status = "";

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_topupresult);
        ButterKnife.bind(this);
        status = getIntent().getStringExtra(IntentKey.TOPUP_STATUS);
        LogUtil.print("status=" + status);
        switch (status) {
            case PayStatus.ALI_SUCCESS:
                viewSuccess.setVisibility(View.VISIBLE);
                viewFailure.setVisibility(View.GONE);
                break;
            case PayStatus.ALI_CONFIRMING:
                AppHelper.show("支付结果确认中");
                viewSuccess.setVisibility(View.VISIBLE);
                viewFailure.setVisibility(View.GONE);
                break;
            default:
                viewSuccess.setVisibility(View.GONE);
                viewFailure.setVisibility(View.VISIBLE);
                break;
        }
    }

    @OnClick({R.id.iv_back, R.id.tv_confirm, R.id.tv_cancel, R.id.tv_repeat})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_back:
                finish();
                break;
            case R.id.tv_confirm:
                SkipHelper.gotoMain(getActivity());
                finish();
                break;
            case R.id.tv_cancel:
                SkipHelper.gotoMain(getActivity());
                finish();
                break;
            case R.id.tv_repeat:
                finish();
                break;
        }
    }
}

2、微信支付

添加jar包

1、后台设置

Android端必须要设置应用的签名和应用包名,签名工具下载地址:https://open.weixin.qq.com/zh_CN/htmledition/res/dev/download/sdk/Gen_Signature_Android.apk

2、添加权限

<uses-permission android:name="android.permission.INTERNET"/> 
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> 
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> 
<uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

3、封装的微信辅助类

支持支付、分享到微信好友、分享到微信朋友圈
public class WXHelper {

    public static IWXAPI wxApi;

    public static void initApi(Context context, String wxAppId) {
        wxApi = WXAPIFactory.createWXAPI(context, wxAppId, false);
        wxApi.registerApp(wxAppId);
    }

    /**
     * 微信支付
     */
    public static void pay(Map<String, String> map) {
        PayReq wxPayReq = new PayReq();
        wxPayReq.appId = map.get("appid");
        wxPayReq.partnerId = map.get("partnerid");
        wxPayReq.prepayId = map.get("prepayid");
        wxPayReq.packageValue = map.get("package");
        wxPayReq.nonceStr = map.get("noncestr");
        wxPayReq.timeStamp = map.get("timestamp");
        wxPayReq.sign = map.get("sign");
        WXHelper.wxApi.sendReq(wxPayReq);
    }

    /**
     * 分享到微信
     *
     * @param cover  封面图片
     * @param target 链接地址
     * @param title  标题
     * @param desc   内容
     */
    public static void shareToWeixin(String cover, String target, String title, String desc) {
        if (checkWeixinApp()) return;
        if (checkShareFiled(cover, target, title, desc)) return;
        requestShare(cover, target, title, desc, true);
    }

    /**
     * 分享到朋友圈
     */
    public static void shareToPengyouQuan(String cover, String target, String title, String desc) {
        if (checkWeixinApp()) return;
        if (checkShareFiled(cover, target, title, desc)) return;
        requestShare(cover, target, title, desc, false);
    }

    //发送分享的请求
    private static void requestShare(String cover, String target, String title, String desc, boolean isWeixin) {
        Observable<SendMessageToWX.Req> observable = Observable.create(subscriber -> {
            if (subscriber.isUnsubscribed()) return;
            try {
                WXWebpageObject webObj = new WXWebpageObject();
                webObj.webpageUrl = target;

                WXMediaMessage msg = new WXMediaMessage(webObj);
                msg.title = title;
                msg.description = desc;
                Bitmap bmp = lo

4、在项目中调用微信支付

在Application创建时中初始化微信API:
WXHelper.initApi(this, "yourWXAppId");
调用微信支付: 这里的tenPay()的一个网络接口,返回服务端的支付信息map
BaseApplication.getWebInterface()
        .tenPay(new TenPayRequest(1, moneyNum))
        .compose(new WebTransformer<>())
        .subscribe(new WebSubscriber<TenPayResponse>() {
            @Override
            public void onSuccess(TenPayResponse response) {
                WXHelper.pay(response.getParams());
            }
        });
然后在包名下新建一个包:wxapi,在wxapi包下新建WXPayEntryActivity。 这里为了和支付宝的支付结果统一,我在WXPayEntryActivity中没有setContentView,而是直接处理支付的返回值,然后跳转到和支付宝支付结果一样的Activity
public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ButterKnife.bind(this);
        WXHelper.wxApi.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        WXHelper.wxApi.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq baseReq) {
    }

    @Override
    public void onResp(BaseResp baseResp) {
        if (baseResp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            switch (baseResp.errCode) {
                case BaseResp.ErrCode.ERR_OK:
                    SkipHelper.gotoPayResult(getActivity(), PayStatus.ALI_SUCCESS);
                    finish();
                    break;
                default:
                    SkipHelper.gotoPayResult(getActivity(), PayStatus.ALI_FAILURE);
                    finish();
                    break;
            }
        }
    }
}
别忘记了,在AndroidManifest.xml文件里面添加声明: 尤其是android:exported="true"属性,千万别忘记!否则无法收到微信的返回结果。
<activity
    android:name="com.che.lovecar.wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"/>
##5、在项目中调用微信分享: 在Application创建时中初始化微信API,已经初始化过就不用了:
WXHelper.initApi(this, "yourWXAppId");
调用微信分享: 弹出微信分享弹窗:
    private void share() {
        ShareDialog dialog = new ShareDialog(this);
        dialog.show();
        String cover = H5Urls.logo;//预览图
        String target = url;//链接地址
        String title = getTitle(url);//标题
        String desc = getDesc(url);//描述
        dialog.setData(cover, target, title, desc);
    }
弹窗样式如下: 这是一个自定义的底部显示的宽度占据全屏的Dialog:
./_image/34F5C60D84E9C4D9E030739694841CBB.jpg
public class ShareDialog extends Dialog {

    private String cover = "";//预览图
    private String target = "";//链接地址
    private String title = "";//标题
    private String desc = "";//描述

    public ShareDialog(Context context) {
        super(context, R.style.DarkDialog);
        Window window = getWindow();
        window.setGravity(Gravity.BOTTOM);
        window.setWindowAnimations(R.style.dialogAnim);
        //默认的Dialog只有5/6左右的宽度
        window.getDecorView().setPadding(0, 0, 0, 0);
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.width = WindowManager.LayoutParams.MATCH_PARENT;
        lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
        window.setAttributes(lp);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.dialog_share);
        ButterKnife.bind(this);
    }

    public void setData(String cover, String target, String title, String desc) {
        this.cover = cover;
        this.target = target;
        this.title = title;
        this.desc = desc;
    }

    @OnClick({R.id.tv_weixin, R.id.tv_pengyouquan, R.id.tv_cancel})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.tv_weixin:
                dismiss();
                WXHelper.shareToWeixin(cover, target, title, desc);
                break;
            case R.id.tv_pengyouquan:
                dismiss();
                WXHelper.shareToPengyouQuan(cover, target, title, desc);
                break;
            case R.id.tv_cancel:
                dismiss();
                break;
        }
    }
}
样式如下:
    <!-- 标准的dialog的样式 -->
    <style name="BaseDialog" parent="@android:style/Theme.Dialog">
        <item name="android:windowFrame">@null</item><!-- 窗框 -->
        <item name="android:windowIsFloating">true</item><!-- 窗口浮动 -->
        <item name="android:windowIsTranslucent">@null</item><!-- 窗口半透明 -->
        <item name="android:windowNoTitle">true</item><!-- 窗口没有标题 -->
        <item name="android:windowBackground">@android:color/transparent</item><!-- 背景的颜色 -->
        <item name="android:backgroundDimEnabled">true</item><!--activity变暗-->
        <item name="android:windowContentOverlay">@null</item><!-- 窗口内容覆盖 -->
    </style>

    <style name="LightDialog" parent="BaseDialog">
        <item name="android:backgroundDimEnabled">false</item><!--activity不变暗-->
    </style>

    <style name="DarkDialog" parent="BaseDialog">
        <item name="android:backgroundDimEnabled">true</item><!--activity变暗-->
    </style>
底部弹出动画如下:
    <!-- 用于弹出底部弹窗的样式 -->
    <style name="dialogAnim" parent="android:Animation">
        <item name="android:windowEnterAnimation">@anim/bottom_in</item>
        <item name="android:windowExitAnimation">@anim/bottom_out</item>
    </style>
底部进入动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">

    <translate
        android:fromYDelta="100%"
        android:toYDelta="0%"
        android:duration="300"
        android:fillAfter="true"
        />
</set>
底部退出动画:
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:duration="300"
        android:fillAfter="true"
        android:fromYDelta="0"
        android:toYDelta="100%"
    />
</set>
在上面Dialog的点击事件中,分享调用了WXHelper.shareToWeixin()和WXHelper.shareToPengyouQuan() 然后在包名下新建一个包:wxapi,在wxapi包下新建WXEntryActivity。
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        WXHelper.wxApi.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        WXHelper.wxApi.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {

    }


    @Override
    public void onResp(BaseResp resp) {
        if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
            finish();
            AppHelper.show("分享成功");
        } else if (resp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {
            finish();
            AppHelper.show("取消成功");
        } else {
            finish();
            AppHelper.show("分享失败");
        }
        EventBus.getDefault().post(new HideShareEvent());
    }
}
别忘记了,在AndroidManifest.xml文件里面添加声明: 尤其是android:exported="true"属性,千万别忘记!否则无法收到微信的返回结果。
<activity
    android:name="com.che.lovecar.wxapi.WXEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"
    android:screenOrientation="portrait"/>

© fishyer 2022