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"/>