前言
最近公司的项目中有又又又又微信分享和支付的功能,每次我都会重新集成,为了方便以后的开发,以及方便各位同仁的开发,整合了这次开发的一些点滴,方便亲们快速集成微信分享和支付。
参考文档
–1.微信官方分享API
–2.微信支付API
一.微信分享
- 环境:AS2.1.2
- jar包支持,选用官方提供的最新jar报,libammsdk.jar
- 最好有一个官方提供的demo project,用于后面直接考入支持类
以上的准备工作就做好了,下面我们就进行快速集成
1.引用支持
1)微信官方jar支持
jar包考入libs支持后,build.gradle中加入引用
compile files('libs/libammsdk.jar')
导入成功之后,最好做一个测试,防止环境问题
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
随便导入上面一行代码,如果没有报错,则导入成功,如果报错,请检查代码
2)权限支持
在AndroidManifest.xml 文件中添加必要的权限支持:
<!--访问网络连接,可能产生GPRS流量-->
<uses-permission android:name="android.permission.INTERNET" />
<!--获取网络信息状态,如当前的网络连接是否有效-->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!--获取当前WiFi接入的状态以及WLAN热点的信息-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!--访问电话状态-->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<!--允许程序写入外部存储,如SD卡上写文件-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
在sdk版本>=6.0文件读写和手机状态读取都需要授权,亲们一定要注意哈,权限相关问题可以参考本人博客这个地址
3)微信分享必备类考入
在实际开发中微信要求我们微信功能需要在特定的包下面提供特定的class类支持,类实际如下
package packageName.wxapi;//[这里包名称不可修改]
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import android.app.AlertDialog;
import android.os.Bundle;
import android.app.Activity;
import android.util.DebugUtils;
import android.util.Log;
import android.view.Menu;
import android.widget.Toast;
/** 微信客户端回调activity示例 */
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
// private int TAG=0;
// IWXAPI 是第三方app和微信通信的openapi接口
private IWXAPI api;
//wxd08be7529caa7577乐惠生活wxe91510de0e3d09e6测试wxfafb57b10b42cea1
public static final String WX_APP_ID = "正式环境对应的微信APPID";
public static final String WX_APP_TESTID="测试环境对应的微信APPID";
//public static final String WX_PACKAGE_NAME = "packageName";
@Override
protected void onCreate(Bundle savedInstanceState) {
String APP_ID=WXEntryActivity.WX_APP_ID;
String packageNmae=getPackageName();
//因为本人的项目包含区分测试和正式的需求顾有如下代码
if(!StringUtlis.isEmpty(packageNmae) && packageNmae.indexOf("debug")>0){
APP_ID=WXEntryActivity.WX_APP_TESTID;
}
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
api.handleIntent(getIntent(), this);
super.onCreate(savedInstanceState);
}
@Override
public void onReq(BaseReq arg0) {
}
@Override
public void onResp(BaseResp resp) {
if(resp.getType()== ConstantsAPI.COMMAND_PAY_BY_WX){//排除微信支付
this.finish(); //此功能为点击返回某程序,非停在微信的时候调用
}else {
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
Toast.makeText(getApplicationContext(), "分享成功", Toast.LENGTH_SHORT).show();
//分享成功
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
Toast.makeText(getApplicationContext(), "分享取消", Toast.LENGTH_SHORT).show();
//分享取消
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
Toast.makeText(getApplicationContext(), "分享拒绝", Toast.LENGTH_SHORT).show();
//分享拒绝
break;
}
this.finish(); //此功能为点击返回某程序,非停在微信的时候调用
}
}
}
这样整体的微信支付支持相关已经完成,有人问是否一定需要在AndroidManifest.XML中注册微信分享支持类Activity,经过本人测试,不需要的欧,不需要也可以完成相关分享。
2.具体分享功能实现
现在要进行的工作,就是我们在我们需要的分享功能的activity类中,代码实现相关功能
本人的项目是NATIVE+HTML,下面是本人项目中微信分享的基本实现
1)提供给HTMl调用的分享方法
/**
* 微信分享
*
* @param json
*/
@JavascriptInterface
public void share(final String json) {
Logs.d(TAG, "----------->share:" + json);
if (!StringUtlis.isEmpty(json)) {
ShareFamilyBeanVo shareVo = new ShareFamilyBeanVo();
try {
JSONObject json_dd = new JSONObject(json);
if (json_dd != null && !StringUtlis.isEmpty(json_dd.getString("data"))) {
JSONObject json_de = new JSONObject(json_dd.getString("data"));
if (json_de != null && !StringUtlis.isEmpty(json_de.getString("shareConfig"))) {
shareVo = new Gson().fromJson(json_de.getString("shareConfig"), ShareFamilyBeanVo.class);
}
}
} catch (Exception e) {
shareVo = null;
}
if (shareVo != null) {
//标题,链接地址,备注,图片缩略图地址
String title = "", linkUrl = "", desc = "", imgUrl = "";
if (!StringUtlis.isEmpty(shareVo.getTitle())) {
title = shareVo.getTitle();
}
if (!StringUtlis.isEmpty(shareVo.getLink())) {
linkUrl = shareVo.getLink();
}
if (!StringUtlis.isEmpty(shareVo.getDesc())) {
desc = shareVo.getDesc();
}
if (!StringUtlis.isEmpty(shareVo.getImgUrl())) {
imgUrl = shareVo.getImgUrl();
}
final ShareWeatchDialog shareDialog = new ShareWeatchDialog(activity, title, linkUrl, imgUrl, desc);
shareDialog.show();
}
}
}
2)ShareWeatchDialog的具体实现
package packageName;
import android.app.Dialog;
import android.content.Context;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import packageName.R;
import packageName.StringUtlis;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
/**
* @author fuqinming
* <p>
* 分享弹框页面
*/
public class ShareWeatchDialog extends Dialog implements View.OnClickListener {
private String TAG = "ShareWeatchDialog";
//其他的部分用于点击关闭[模拟关闭]
//取消按钮
private TextView comm_three_btn;
//分享_微信好友
private LinearLayout watchet_session_lin;
//分享_微信盆友圈
private LinearLayout watchet_timeline_lin;
//分享标识判断
public static int sence = -1;
//标题
private String title = "", linkUrl = "", desc = "",imgUrl="";
// activity类
private Context mContext;
public ShareWeatchDialog(Context context) {
super(context, R.style.loadingDialog);
this.mContext = context;
init();
}
public ShareWeatchDialog(Context context, String title1, String linkUrl1,String imgUrl1,String desc1) {
super(context, R.style.loadingDialog);
this.mContext = context;
if (!StringUtlis.isEmpty(title1)) {
title = title1;
}
if (!StringUtlis.isEmpty(linkUrl1)) {
linkUrl = linkUrl1;
}
if (!StringUtlis.isEmpty(desc1)) {
desc = desc1;
}
if(!StringUtlis.isEmpty(imgUrl1)){
imgUrl=imgUrl1;
}
init();
}
public ShareWeatchDialog(Context context, int theme) {
super(context, theme);
mContext = context;
init();
}
public ShareWeatchDialog(Context context, int theme, String title1, String linkUrl1, String desc1) {
super(context, theme);
this.mContext = context;
if (!StringUtlis.isEmpty(title1)) {
title = title1;
}
if (!StringUtlis.isEmpty(linkUrl1)) {
linkUrl = linkUrl1;
}
if (!StringUtlis.isEmpty(desc1)) {
desc = desc1;
}
init();
}
private void init() {
try {
// 初始化view
LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(-1, -2);
setContentView(R.layout.share_dialog_layout);
android.view.WindowManager.LayoutParams layoutParams = getWindow()
.getAttributes();
layoutParams.gravity = Gravity.BOTTOM;
layoutParams.width = LinearLayout.LayoutParams.MATCH_PARENT;
layoutParams.height = LinearLayout.LayoutParams.WRAP_CONTENT;
getWindow().getDecorView().setPadding(0, 0, 0, 0);
getWindow().setAttributes(layoutParams);
//关闭
comm_three_btn = (TextView) findViewById(R.id.comm_three_btn);
//微信好友
watchet_session_lin = (LinearLayout) findViewById(R.id.watchet_session_lin);
//微信盆友圈
watchet_timeline_lin = (LinearLayout) findViewById(R.id.watchet_timeline_lin);
this.setCancelable(true);
this.setCanceledOnTouchOutside(false);
comm_three_btn.setOnClickListener(this);
watchet_session_lin.setOnClickListener(this);
watchet_timeline_lin.setOnClickListener(this);
} catch (Exception e) {
}
}
public void show() {
super.show();
}
@Override
public void onClick(View v) {
switch (v.getId()) {
//取消
case R.id.comm_three_btn:
this.dismiss();
break;
//微信好友
case R.id.watchet_session_lin:
sence = SendMessageToWX.Req.WXSceneSession;
//因为只有子页面需要分享顾只在需要的页面进行分享控制
if (mContext instanceof WebViewActivity || mContext instanceof WeViewBackActivity) {
shareWatch();
}
this.dismiss();
break;
//微信盆友圈
case R.id.watchet_timeline_lin:
sence = SendMessageToWX.Req.WXSceneTimeline;
shareWatch();
this.dismiss();
break;
default:
break;
}
}
private void shareWatch() {
if (mContext instanceof WebViewActivity) {
((WebViewActivity) mContext).shareWatch(sence, title, linkUrl,imgUrl, desc);
}else if(mContext instanceof WeViewBackActivity){
((WeViewBackActivity) mContext).shareWatch(sence, title, linkUrl,imgUrl, desc);
}
}
/*
* 关闭 (non-Javadoc)
*
* @see android.app.Dialog#dismiss()
*/
@Override
public void dismiss() {
super.dismiss();
}
}
3)在相关Activity中的实现
[1]初始化微信
private IWXAPI api;
private void initWXAPI() {
payReq = new PayReq();
String APP_ID = WXEntryActivity.WX_APP_ID;
String packageNmae = getPackageName();
if (!StringUtlis.isEmpty(packageNmae) && packageNmae.indexOf("debug") > 0) {
APP_ID = WXEntryActivity.WX_APP_TESTID;
}
//初始化分享
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
api.handleIntent(getIntent(), this);
api.registerApp(APP_ID);
}
[2]微信分享的具体实现
/**
* 分享微信
*/
public void shareWatch(int sence, String title, String linkUrl, String imgUrl, String desc) {
if (sence < 0) {
ToastTools.showShort(this, "您选择的分享类型错误");
return;
}
if (api.isWXAppInstalled() == false) {
ToastTools.showShort(this, "您暂未装微信,请安装微信");
} else {
if (!api.isWXAppSupportAPI()) {
ToastTools.showShort(this, "不支持此版本微信,请安装新版本微信");
} else {
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = linkUrl;
Bitmap bitmap = null;
try {
if (!StringUtlis.isEmpty(imgUrl)) {
Bitmap thumbBmp = Glide.with(activity).load(imgUrl).asBitmap().centerCrop().into(120, 120).get();
if (thumbBmp != null) {
bitmap = thumbBmp;
} else {
bitmap = BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher);
}
}
} catch (Exception e) {
bitmap = BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher);
}
WXMediaMessage msg = new WXMediaMessage(webpage);
msg.title = title;
msg.description = desc;
msg.setThumbImage(bitmap);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.message = msg;
req.scene = sence;
boolean ab = api.sendReq(req);
int ac = 10;
ac++;
}
}
}
[3]分享成功与否回调
// 微信发送请求到第三方应用时,会回调到该方法
public void onReq(BaseReq req) {
int ab = 10;
ab++;
}
// 第三方应用发送到微信的请求处理后的响应结果,会回调到该方法
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {//支付
} else {
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
ToastTools.showShort(this, "分享成功");
// result = R.string.errcode_success;
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
ToastTools.showShort(this, "分享已取消,分享失败");
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
ToastTools.showShort(this, "分享失败");
break;
default:
ToastTools.showShort(this, "分享失败");
break;
}
}
}
以上就完成了微信分享,如果您不是NATIVE+HTML的项目就更加简单了,只需要在对应的activity类中实现相关功能就好,就不需要上面的很多步骤。
二.快速集成微信支付
在一的基础上完成微信支付,是超级快速并且简单的,因为有一的基础,一的一些支持都还是可以用的哈
1)导入支付支持class类
和微信分享一样,支付也需要固定类的支持,该类实现如下,如果没有该类是可以实现支付吊起的欧,只是没有支付成功与否的返回值[亲自测试得到结果]
很多情况下我们都需要知道成功与否的返回值,顾添加了这项支持
下面是该类代码
package packageName.wxapi;
import packageName.R;
import packageName.base.log.Logs;
import packageName.utils.StringUtlis;
import com.tencent.mm.sdk.constants.ConstantsAPI;
import com.tencent.mm.sdk.modelbase.BaseReq;
import com.tencent.mm.sdk.modelbase.BaseResp;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.Window;
/**
*@author fuqinming
*@add 2017-10-10
*
*支付结果跳转类[用于数据回调]
**/
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler{
private static final String TAG = "WXPayEntryActivity";
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
String APP_ID=WXEntryActivity.WX_APP_ID;
String packageNmae=getPackageName();
if(!StringUtlis.isEmpty(packageNmae) && packageNmae.indexOf("debug")>0){
APP_ID=WXEntryActivity.WX_APP_TESTID;
}
api = WXAPIFactory.createWXAPI(this, APP_ID);
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
}
@Override
public void onReq(BaseReq req) {
}
@Override
public void onResp(BaseResp resp) {
if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
Log.e(TAG,"WXPayEntryActivity onPayFinish,errCode="+resp.errCode);
//setResult(resp.errCode);html端反馈说不用把状态返回给他,顾没有做相关操作
//需要的亲们可以自己添加
this.finish(); //此功能为点击返回某程序,非停在微信的时候调用
}
}
}
想要接收到回调,一定需要在Android中店家activity的支持
<!-- 支付回调页面 -->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="${WEATCH_APPID}"/>
//{WEATCH_APPID}来自build.gradle中声明
//因本人支持正式和测试环境区分,如果没有这个需求的亲们,自行写自己的APPID就好
</intent-filter>
</activity>
这一步操作就是为了让微信支付成功调用成功,并收到返回值。
支付成功一般如下:
名称 | 描述 | 解决方案 |
---|---|---|
0 | 成功 | 展示成功页面 |
-1 | 错误 | 可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。 |
-2 | 用户取消 | 无需处理。发生场景:用户不支付了,点击取消,返回APP。 |
2)支付的具体实现
[1]调起微信支付参数Model创建[这里只是方便传参,大家可以选择适合自己的方式]
package com.reach.doooly.bean;
/**
*@author fuqinming
*
* @add 2017-10-10
* 微信分享bean
*/
public class WeachPayBeanVo extends RHBaseVo{
//微信开放平台审核通过的应用APPID
private String appid;
//随机字符串,不长于32位。推荐随机数生成算法
private String noncestr;
//扩展字段[package]
private String packageValue;
//签名
private String sign;
//商户号
private String partnerid;
//预支付交易会话ID
private String prepayid;
//时间戳
private String timestamp;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getNoncestr() {
return noncestr;
}
public void setNoncestr(String noncestr) {
this.noncestr = noncestr;
}
public String getPackageValue() {
return packageValue;
}
public void setPackageValue(String packageValue) {
this.packageValue = packageValue;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
sign = sign;
}
public String getPartnerid() {
return partnerid;
}
public void setPartnerid(String partnerid) {
this.partnerid = partnerid;
}
public String getPrepayid() {
return prepayid;
}
public void setPrepayid(String prepayid) {
this.prepayid = prepayid;
}
public String getTimestamp() {
return timestamp;
}
public void setTimestamp(String timestamp) {
this.timestamp = timestamp;
}
}
[2]Native提供给html的调用
/**
* 微信支付
*
* @param jsonParams
*/
@JavascriptInterface
public void wechatPay(String jsonParams,String func) {
Logs.d(TAG, "----------------------> wechatPay()"+"func:"+func+",jsonParmas:"+jsonParams);
if (activity instanceof WebViewActivity || activity instanceof WeViewBackActivity) {
if (!StringUtlis.isEmpty(jsonParams) && !StringUtlis.isEmpty(func)) {
jsonParams = jsonParams.replace("\"package\"", "\"packageValue\"");
Logs.d(TAG, "wechatPay() jsonParams is " + jsonParams);
WeachPayBeanVo weachPayVo = new WeachPayBeanVo();
try {
weachPayVo = new Gson().fromJson(jsonParams, WeachPayBeanVo.class);
} catch (Exception e) {
weachPayVo = null;
}
if (weachPayVo != null && !StringUtlis.isEmpty(weachPayVo.getAppid()) &&
!StringUtlis.isEmpty(weachPayVo.getNoncestr()) && !StringUtlis.isEmpty(weachPayVo.getPackageValue())
&& !StringUtlis.isEmpty(weachPayVo.getPartnerid()) && !StringUtlis.isEmpty(weachPayVo.getPrepayid()) &&
!StringUtlis.isEmpty(weachPayVo.getSign()) && !StringUtlis.isEmpty(weachPayVo.getTimestamp())) {
if (activity instanceof WebViewActivity) {
((WebViewActivity) activity).wechatPay(weachPayVo);
} else if (activity instanceof WeViewBackActivity) {
((WeViewBackActivity) activity).wechatPay(weachPayVo);
}
} else {
ToastTools.showShort(activity, "订单异常,不可进行支付");
}
}
}
}
[3]下面是Activity中具体实现
[1]微信支付初始化
//微信支付
private PayReq payReq;
private IWXAPI api;
//这里是分享和支付的融合
private void initWXAPI() {
payReq= new PayReq();
String APP_ID = WXEntryActivity.WX_APP_ID;
String packageNmae = getPackageName();
if (!StringUtlis.isEmpty(packageNmae) && packageNmae.indexOf("debug") > 0) {
APP_ID = WXEntryActivity.WX_APP_TESTID;
}
//初始化分享
api = WXAPIFactory.createWXAPI(this, APP_ID, true);
api.handleIntent(getIntent(), this);
api.registerApp(APP_ID);
}
[2]微信支付具体实现
/***
* 微信支付[NATIVIE TO HTML]
* @add 2017-10-10
* @param weachPayVo
*/
public void wechatPay(WeachPayBeanVo weachPayVo) {
if(payReq!=null && weachPayVo!=null && !StringUtlis.isEmpty(weachPayVo.getAppid()) &&
!StringUtlis.isEmpty(weachPayVo.getNoncestr()) && !StringUtlis.isEmpty(weachPayVo.getPackageValue())
&& !StringUtlis.isEmpty(weachPayVo.getPartnerid()) && !StringUtlis.isEmpty(weachPayVo.getPrepayid()) &&
!StringUtlis.isEmpty(weachPayVo.getSign()) && !StringUtlis.isEmpty(weachPayVo.getTimestamp())){
payReq.appId = weachPayVo.getAppid();
payReq.partnerId = weachPayVo.getPartnerid();//微信支付分配的商户号
payReq.prepayId=weachPayVo.getPrepayid();//微信返回的支付交易会话ID
payReq.packageValue = weachPayVo.getPackageValue();//扩展字段占时填固定
payReq.nonceStr= weachPayVo.getNoncestr();//随机字符串
payReq.timeStamp= weachPayVo.getTimestamp();//时间戳
payReq.sign= weachPayVo.getSign();//签名
api.sendReq(payReq);
}else{
ToastTools.showShort(this,"订单异常,不可进行支付");
}
}
[3]微信成功的返回在WXPayEntryActivity类欧
如上整体就完成了欧,是不是超级简单呢,如果你的项目不是NATIVE+HTML,会更加简单的欧,可以节省很多的代码,希望本博客文章对您的开发有用。
后写了支付宝微信快速集成支付的博客,博客地址:https://blog.csdn.net/onlymetagain/article/details/80774910