微信
基础
使用前先下载sdk,一个jar包。
在微信开放平台注册应用,应用审核通过后,会拿到一个APP_ID与AppSecret。微信所有功能的使用都是通过IWXAPI的对象进行操作的。拿到这个对象后,调用它的registerApp(APP_ID)将自己的应用注册到微信列表中。其后才可进行别的操作。示例如下:
private IWXAPI api;
Context mContext;
public WXTools(Context mContext){
this.mContext = mContext;
api = WXAPIFactory.createWXAPI(mContext, Constants.APP_ID, false);//拿到IWXAPI对象
api.registerApp(Constants.APP_ID);//向微信中注册自己的应用
}
回调
package sb.wx.wxapi;//修改成自己应用的包名+wxapi
public class WXEntryActivity extends Activity implements IWXAPIEventHandler{}
实现的接口中有两个方法,onResp()表示第三方应用请求微信,微信处理后的回调。是否安装过微信
private boolean isWXAppInstalledAndSupported() {
IWXAPI api = WXAPIFactory.createWXAPI(this, Constants.APP_ID, false);
return api.isWXAppInstalled()
&& api.isWXAppSupportAPI();
}
登陆
public void login(){
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";//这个是必须的,用于确定当初应用可获取微信用户的哪些信息
req.state = "sb_login";//这个最好带上
api.sendReq(req);//发起请求
}
第二步:处理授权登录后的回调,并根据返回的code生成链接。这里就需要用上应用审核通过后拿到的appid与appsecret。第一步时会调起微信授权登录界面,用户授权后会回调到WXEntryActivity#onResp()。首先判断BaseResp.errCode的值,只有当该值为BaseResp.ErrCode.ERR_OK时才可进行下一步操作,其余的都是授权失败。如下:
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
String code = ((SendAuth.Resp) resp).code;
WXOAuthCodeURL += "appid=" + Constants.APP_ID + "&secret=" + Constants.AppSecret + "&code=" + code + "&grant_type=authorization_code";
其中WXOAuthCodeURL是一个固定值: private String WXOAuthCodeURL = "https://api.weixin.qq.com/sns/oauth2/access_token?";
第三步:使用Get请求方式访问第二步拿到的链接,成功后可得access_token与openid。如下:HttpGet httpRequest = new HttpGet(WXOAuthCodeURL);
HttpResponse httpResponse = new DefaultHttpClient().execute(httpRequest);
if (httpResponse.getStatusLine().getStatusCode() == 200) {
String strResult = EntityUtils.toString(httpResponse.getEntity());
JSONObject jsonObject = new JSONObject(strResult);
access_token = jsonObject.getString("access_token");
openid = jsonObject.getString("openid");//这两个是主要的
int expires_in = jsonObject.getInt("expires_in");
String refresh_token = jsonObject.getString("refresh_token");
String scope = jsonObject.getString("scope");
第四步:判断拿到的access_token与openid是否有效。其中的
//这个是固定值,只不过后面拼的参数是第三步获取到的
String WXOAuthTokenURL = "https://api.weixin.qq.com/sns/auth?";//access_token=ACCESS_TOKEN&openid=OPENID
WXOAuthTokenURL += "access_token=" + access_token + "&openid=" + openid;
HttpGet get = new HttpGet(WXOAuthTokenURL);
HttpResponse response = new DefaultHttpClient().execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(response.getEntity());
JSONObject jsonObject = new JSONObject(result);
int errcode = jsonObject.getInt("errcode");
String errmsg = jsonObject.getString("errmsg");
if (errcode == 0 && errmsg.equals("ok")) {//两者都有效,可进行下一步操作}
第五步:如果access_token与openid有效,则使用他们去获取用户的具体信息。如下:String WXOAuthUserInfoURL = "https://api.weixin.qq.com/sns/userinfo?";
WXOAuthUserInfoURL += "access_token=" + access_token + "&openid=" + openid;
HttpGet get = new HttpGet(WXOAuthUserIforURL);
HttpResponse response = new DefaultHttpClient().execute(get);
if (response.getStatusLine().getStatusCode() == 200) {
String result = EntityUtils.toString(response.getEntity(), "UTF-8");
JSONObject jsonObject = new JSONObject(result);
String openid = jsonObject.getString("openid");
String nickname = jsonObject.getString("nickname");
int sex = jsonObject.getInt("sex");
String province = jsonObject.getString("province");
String city = jsonObject.getString("city");
String country = jsonObject.getString("country");
String headimgurl = jsonObject.getString("headimgurl");
String unionid = jsonObject.getString("unionid");
到此时才终于拿到了微信用户的基本信息。
分享
其主要调用的是IWXAPI#sendReq()方法。分享时传入该方法的参数为SendMessageToWX.Req对象。如下:
public void sendReq(Context context,String title, String description,String url,Bitmap bmp,boolean isPeng) {
//创建message时需要的object。此处是分享一个链接到微信
WXWebpageObject localWXWebpageObject = new WXWebpageObject();
localWXWebpageObject.webpageUrl = url;
//创建请求时需要的message
WXMediaMessage localWXMediaMessage = new WXMediaMessage(localWXWebpageObject);
localWXMediaMessage.title = title;// 不能太长,否则微信会提示出错。
localWXMediaMessage.description = description;
localWXMediaMessage.thumbData = getBitmapBytes(bmp, false);//分享时需要对缩略图进行处理,将图片压缩成80*80,并转换成byte[]
//构建一个要发送到微信的请求
SendMessageToWX.Req localReq = new SendMessageToWX.Req();
localReq.transaction = System.currentTimeMillis() + "";
localReq.message = localWXMediaMessage;
//根据是否分享到朋友圈,该请求的scene(场景)不一样
if (isPeng) {// 朋友圈
localReq.scene = SendMessageToWX.Req.WXSceneTimeline;
}else {
localReq.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(localReq);//使用api发送请求到微信
}
上面是分享一个链接,如果想分享一个图片,只需要将localWXMediaMessage的参数换成WXImageObject即可。如下: public void sendImg(String imagePath,boolean isPeng) {
WXImageObject imgObj = new WXImageObject();
imgObj.setImagePath(imagePath);//设置要分享出去的图片的路径,无论该路径是本地的还是网络中的。如果不行,就使用imgObj.imageUrl。
//也可将图片转换成byte[],然后设置到imgObj.imageData属性中
WXMediaMessage msg = new WXMediaMessage();
msg.mediaObject = imgObj;//与上面的代码中通过参数传递是一样的效果
msg.description="图片描述";
Bitmap bmp = BitmapFactory.decodeFile(imagePath);//解释文件生成bitmap
Bitmap thumbBmp = Bitmap.createScaledBitmap(bmp, 80, 80, true);
bmp.recycle();
msg.thumbData = Util.bmpToByteArray(thumbBmp, true);//将上述的80*80的图片转换成byte[]
msg.title="标题";
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = "img"+String.valueOf(System.currentTimeMillis());
req.message = msg;
if (isPeng) {// 朋友圈
req.scene = SendMessageToWX.Req.WXSceneTimeline;
}else {
req.scene = SendMessageToWX.Req.WXSceneSession;
}
api.sendReq(req);
}
对比上述两个代码可以发现,只需要修改WXMediaMessage.mediaObject的值即可。
如果是分享文本,如下:
WXTextObject textObj = new WXTextObject();
textObj.text = text;
另外,还有WXMusicObject(分享一段音频,通过musicUrl属性指定音频的url),WXVideoObject(视频,通过videoUrl指定视频链接),WXEmojiObject(表情,通过emojiPath指定表情路径,emojiData指定表情的二进制数据)。支付
微信支付非常简单,因为大部分数据都是后台处理好的。前端只需要调用一些接口将后台返回的数据发送给微信即可。如下:
public void payReq(String appId,String partnerId,String prepayId,String packageValue,String nonceStr,String timeStamp,String sign) {
req = new PayReq();
req.appId = appId;
req.partnerId = partnerId;
req.prepayId = prepayId;
req.packageValue = packageValue;
req.nonceStr = nonceStr;
req.timeStamp = timeStamp;
req.sign = sign;
api.sendReq(req);}
其回调的接口依旧是WXEntryActivity#onResp()。