最近由于公司想弄一个新手推荐活动,因为是推荐活动,必须借用现在流行的社交软件进行各种分享,只要形式有微信分享到好友或者朋友圈、QQ分享给好友或者空间、微博分享和短信分享等。下面我就跟大家一起聊下在分享的过程中所遇到的各种坑。本文来自于自己的经验,不足的地方还请指正。首先说下我是怎么实现的,然后给大家说下实现过程中应该注意的。
微信支付
微信支付注册
1
api = WXAPIFactory.createWXAPI(this, AppConfig.WEIXIN_PAY_ID, false);
第二个参数是我们在微信开放平台申请的Pay_ID
第三个参数代表是否进行校验.微信推荐我们从后台生成订单,然后再通过app调起微信进行支付,其实也可以App里面就生成订单,然后Appc里面进行支付。两种都是可行的,但是大多数App并不是简简单单的支付,可能还要数据库入库,或者进行一些其他的操作,通过后台生成订单就比较好,大家可以根据自己的需求,选择适合自己的。
当订单生成之后,我们需要拼接调起微信支付的请求PayReq:
1
2
3
4
5
6
7
8
9PayReq request = new PayReq();
request.appId = object.getString("appId");
request.partnerId = object.getString("partnerId");
request.prepayId = object.getString("prepayId");
request.packageValue = object.getString("package");
request.nonceStr = object.getString("nonceStr");
request.timeStamp = object.getString("timeStamp");
request.sign = object.getString("sign");
api.sendReq(request);通过api.sendReq(),我们就能调起微信进行支付啦。一般情况下还是比较容易调起 的,如果没反应,请检查自己的APP_ID,然后在检查一下自己的PayReq,然后在检查一下,是否添加了必须的权限。
微信成功调起,输入密码成功支付之后,如果我们想要知道微信支付的结果,就必须在应用包名下,新建一个wxapi的包,然后新建一个WXPayEntryActivity,重点注意包名和activity的名字不要写错,微信是通过包名加activity的名称通过反射跳转到该页面。这样还不够,需要实现微信定义的IWXAPIEventHandler,重写onResp和onReq,在onReq里面我们可以对app发送到微信的请求做些处理,在onResp我们可以接收到微信返回的结果。返回结果bean里面的errCode比较简单,0代表成功,-1代表失败,-2代表取消。这样还不够,还要调用iwxapi.handleIntent(getIntent(), this)在能正真的接收到微信返回的消息。如果没能成功的接收到微信返回的消息,依次检查包名activity名是否与规定的不符,检查是否在AndroidMianfest里面注册了activity,然后是否调用了iwxapi.handleIntent(getIntent(), this)。
以上就是微信支付的总结,主要注意
- 权限是否添加
- wxapi和WXPayEntryActivity的包名是否正确
- 在 WXPayEntryActivity里面是否调用了iwxapi.handleIntent(getIntent(), this)
微信分享
首先检测手机是否安装了微信,通过微信自定义的方法
1
2
3
4IWXAPI api = WXAPIFactory.createWXAPI(context, AppConfig.WEIXIN_PAY_ID, false);
if (api.isWXAppInstalled() && api.isWXAppSupportAPI()) {
flag = true;
}api.isWXAppInstalled()返回微信是否安装
api.isWXAppSupportAPI()返回微信是否支持支付在初始化了api之后,我们需要把应用注册到微信
api.registerApp(AppConfig.WEIXIN_PAY_ID);
- 下面就是创建WXobject和wxMessage,说明文档上有具体的代码,分享文字,图片,音频等详细代码,我就不一一重述了,大家自己去微信开放平台查看代码。通过api.sendReq(req)我们就能调起微信分享的界面。
- 跟微信支付一样,我们 需要在wxapi包下面新建一个WXEntryActivity,并且实现IWXAPIEventHandler才能接收到是否分享成功。
如果没有分享成功,依次检查:
分享之前时候注册了应用到微信
1
api.registerApp(AppConfig.WEIXIN_PAY_ID);
WXEntryActivity是否注册了
- 是否添加了必要的权限
QQ分享
- 首先导入必须的mta_sdk.jar和open_sdk.jar
- AndroidManifest里面添加
Tencent是QQ的入口,需要实例化Tencent:
Tencent:mTencent = Tencent.createInstance(APP_ID, this.getApplicationContext());
实现回调:IUiListener,QQ的所有操作都是通过这个回调的,如果要想接收到QQ的回调,还需要重写onActivityRes
如果没有分享成功,依次检查:
- 是否添加必要的权限
- 是否在Manifest里面注册了必要的activity,重点注意的是 ,这里以Tencent 开头,后面的数字是自己申请的appkey,当初就是这里没有处理,导致QQ一直无法调起
- 如果分享成功,但是不能接收到回调,检查是否重写了onActivityResult()
微博分享
微博里面文档比较全,他涉及到的东西也非常多,我们移动app比较关注的是他的分享和登陆。
- 导入jar包和so库
在Manifest里面添加:
1
2
3
4<activity android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser" android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:windowSoftInputMode="adjustResize">
</activity>
>这是微博自带的有个webview,当你手机没有安装微博的时候,可以通过H5实现分享和登陆。如果没有注册的话,当没安装微博客户端的时候,无法调起微博H5页面;
- 实现IWeiboHandler.Response接口,用于接收微博分享的结果
实例化IWeiboShareAPI、注册,处理微博分享 的结果:
1
2
3mWeiboShareAPI=WeiboShareSDK.createWeiboAPI(context.getApplicationContext(), AppConfig.WEIBO_APPID);
mWeiboShareAPI.registerApp();
mWeiboShareAPI.handleWeiboResponse(getIntent(), this);//处理微博分享的结果;
###如果没有分享成功,一次检查:
- 因为微博审核比较严格,只有当审核通过之后才能分享成功,有可能并不是你的代码问题,而是审核没有通过,导致分享失败
- 在没有安装微博的情况下,不能跳到微博分享的H5,检查Manifest里面是否注册了微博的H5 webview;
添加必须的权限**
下面分享我自己写的一个ShareUtils,里面实现了QQ,微信,微博分享,大家可以自行下载对照。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.widget.Toast;
import com.sina.weibo.sdk.api.TextObject;
import com.sina.weibo.sdk.api.WebpageObject;
import com.sina.weibo.sdk.api.WeiboMessage;
import com.sina.weibo.sdk.api.WeiboMultiMessage;
import com.sina.weibo.sdk.api.share.IWeiboShareAPI;
import com.sina.weibo.sdk.api.share.SendMessageToWeiboRequest;
import com.sina.weibo.sdk.api.share.SendMultiMessageToWeiboRequest;
import com.sina.weibo.sdk.api.share.WeiboShareSDK;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WeiboAuthListener;
import com.sina.weibo.sdk.exception.WeiboException;
import com.sina.weibo.sdk.utils.Utility;
import com.tencent.connect.common.Constants;
import com.tencent.connect.share.QQShare;
import com.tencent.connect.share.QzoneShare;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import java.io.ByteArrayOutputStream;
import java.util.ArrayList;
public class ShareUtils {
private static final String PREFERENCES_NAME = "com_weibo_sdk_android";
private static final String KEY_UID = "uid";
private static final String KEY_ACCESS_TOKEN = "access_token";
private static final String KEY_EXPIRES_IN = "expires_in";
private static final String KEY_REFRESH_TOKEN = "refresh_token";
public static boolean isWeiXinInstallAndSupport(Context context) {
boolean flag = false;
IWXAPI api = WXAPIFactory.createWXAPI(context, AppConfig.WEIXIN_PAY_ID, false);
if (api.isWXAppInstalled() && api.isWXAppSupportAPI()) {
flag = true;
}
return flag;
}
/**
* @param context
* @param type 1:分享到朋友圈 2:分享到微信好友
* @param title 标题
* @param url 跳转url
* @param imageId 图片id
*/
public static void shareToWeChat(Context context, int type, String title, String url, int imageId) {
IWXAPI api = WXAPIFactory.createWXAPI(context, AppConfig.WEIXIN_PAY_ID);
api.registerApp(AppConfig.WEIXIN_PAY_ID);
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), imageId);
Bitmap thumbBmp = Bitmap.createScaledBitmap(bitmap, 150, 150, true);
bitmap.recycle();
WXWebpageObject webpageObject = new WXWebpageObject();
webpageObject.webpageUrl = url;
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = webpageObject;
msg.title = title;
msg.thumbData = bmpToByteArray(thumbBmp, true);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.message = msg;
req.transaction = System.currentTimeMillis() + "";
req.scene = type == 1 ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
api.sendReq(req);
}
/**
* @param context
* @param title 标题
* @param description 描述
* @param url 跳转URL
* @param imageUrl 图片链接
* @param callBack
*/
public static void shareToQQ(Tencent mTencent, Context context, String title, String description, String url, String imageUrl, IUiListener callBack) {
Bundle params = new Bundle();
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, description);
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, url);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUrl);
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, App名字);
mTencent.shareToQQ((Activity) context, params, callBack);
}
/**
* @param context
* @param picLists 图片arraylist,可以分享多张图片
* @param title 标题
* @param description 描述
* @param url 跳转url
* @param callBack
*/
public static void shareToZone(Context context, ArrayList<String> picLists, String title, String description, String url, IUiListener callBack) {
Tencent mTencent = Tencent.createInstance(AppConfig.QQ_APPID, context.getApplicationContext());
final Bundle params = new Bundle();
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);//必填
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, description);//选填
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, url);//必填
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, picLists);
mTencent.shareToQzone((Activity) context, params, callBack);
}
/**
* @param context
* @param phoneNum 短信接受者电话号码
* @param content 短信内容
*/
public static void shareToSms(Context context, String phoneNum, String content) {
Uri smsToUri = Uri.parse("smsto:" + phoneNum);
Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri);
intent.putExtra("sms_body", content);
context.startActivity(intent);
}
/**
* @param context
* @param resId 显示图片
* @param title 标题
* @param description 描述
* @param url 跳转url
*/
public static void shareToWeibo(IWeiboShareAPI api, final Context context, int resId, String title, String description, String url) {
WebpageObject mediaObject = new WebpageObject();
mediaObject.identify = Utility.generateGUID();
mediaObject.title = title;
mediaObject.description = title;
TextObject textObject = new TextObject();
textObject.text = title;
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), resId);
// 设置 Bitmap 类型的图片到视频对象里 设置缩略图。 注意:最终压缩过的缩略图大小不得超过 32kb。
mediaObject.setThumbImage(bitmap);
mediaObject.actionUrl = url;
mediaObject.defaultText = title;
WeiboMultiMessage weiboMessage = new WeiboMultiMessage();
weiboMessage.mediaObject = mediaObject;
weiboMessage.textObject=textObject;
SendMultiMessageToWeiboRequest request = new SendMultiMessageToWeiboRequest();
// 用transaction唯一标识一个请求
request.transaction = String.valueOf(System.currentTimeMillis());
request.multiMessage = weiboMessage;
// 3. 发送请求消息到微博,唤起微博分享界面
AuthInfo authInfo = new AuthInfo(context, AppConfig.WEIBO_APPID, "", AppConfig.SCOPE);
Oauth2AccessToken accessToken = readAccessToken(context.getApplicationContext());
String token = "";
if (accessToken != null) {
token = accessToken.getToken();
}
api.sendRequest((Activity) context, request, authInfo, token, new WeiboAuthListener() {
public void onWeiboException(WeiboException arg0) {
}
public void onComplete(Bundle bundle) {
// TODO Auto-generated method stub
Oauth2AccessToken newToken = Oauth2AccessToken.parseAccessToken(bundle);
writeAccessToken(context.getApplicationContext(), newToken);
}
public void onCancel() {
}
});
}
public static void writeAccessToken(Context context, Oauth2AccessToken token) {
if (null == context || null == token) {
return;
}
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
SharedPreferences.Editor editor = pref.edit();
editor.putString(KEY_UID, token.getUid());
editor.putString(KEY_ACCESS_TOKEN, token.getToken());
editor.putString(KEY_REFRESH_TOKEN, token.getRefreshToken());
editor.putLong(KEY_EXPIRES_IN, token.getExpiresTime());
editor.commit();
}
public static Oauth2AccessToken readAccessToken(Context context) {
if (null == context) {
return null;
}
Oauth2AccessToken token = new Oauth2AccessToken();
SharedPreferences pref = context.getSharedPreferences(PREFERENCES_NAME, Context.MODE_APPEND);
token.setUid(pref.getString(KEY_UID, ""));
token.setToken(pref.getString(KEY_ACCESS_TOKEN, ""));
token.setRefreshToken(pref.getString(KEY_REFRESH_TOKEN, ""));
token.setExpiresTime(pref.getLong(KEY_EXPIRES_IN, 0));
return token;
}
public static byte[] bmpToByteArray(final Bitmap bmp, final boolean needRecycle) {
ByteArrayOutputStream output = new ByteArrayOutputStream();
bmp.compress(Bitmap.CompressFormat.PNG, 100, output);
if (needRecycle) {
bmp.recycle();
}
byte[] result = output.toByteArray();
try {
output.close();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}
文章写得不好,欢迎大家吐槽