建议大家看第二版本(最新版):http://blog.csdn.net/lowprofile_coding/article/details/78004224
转载请注明出处:http://blog.csdn.net/lowprofile_coding/article/details/48086381
前言:用了微信的sdk各种痛苦,感觉比QQ sdk调用麻烦多了,回调过于麻烦,还必须要在指定包名下的actvity进行回调,所以我在这里写一篇博客,有这个需求的朋友可以借鉴一下,以后自己别的项目有用到也有个找资料的地方.
一微信登陆分三个步骤:
1)微信授权登陆
2)。根据授权登陆代码获取该用户令牌
3)。根据令牌获取用户资料
4)接收微信的请求及返回值如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面3步操作:
一个。在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个WXEntryActivity类,该类继承自Activity(例如应用程序的包名为net.sourceforge.simcpux,
则新添加的类如下图所示)
并在清单文件里面加上出口属性,设置为真,例如:
湾实现IWXAPIEventHandler接口,微信发送的请求将回调到onReq方法,发送到微信请求的响应结果将回调到onResp方法
c.在WXEntryActivity中将接收到的intent及实现了IWXAPIEventHandler接口的对象传递给IWXAPI接口的handleIntent方法,示例如下图:
微信官网登陆教程:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419317851&token=&lang=zh_CN
微信官网接入指南:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417751808&token=&lang=zh_CN
二.微信分享直接调用sdk就行,回调跟登陆回调的类是一样的,根据BaseResp的类型来区分是登陆还是分享。
三,微信支付
1)。发送一个支付请求
2).接收微信支付的返回值(跟接收微信登陆.分享的返回值类似,我就不写详细操作步骤了)
官网参考地址如下:https://pay.weixin.qq.com/wiki/doc/api/app.php章= 8_5
四,贴上代码进行讲解
我把微信登陆,分享,支付都封装到了一个类里面了,你们可以参考这个类.封装了6个方法,我对几个需要的方法介绍一下
1)构造方法:初始化对象的时候,顺便初始化微信对象,把APP_ID注册到微信
2)的.login()发起一个登陆的请求在微信登陆监听Actviity中获取代码
3).getAccessToken(字符串代码)当你从监听活动中获取了密码之后就可以通过这个方法获取微信访问令牌了
4).getWeiXinUserInfo(最终WeiXinToken OBJ)获取微信用户信息传入一个WeiXinToken对象,这个对象是第三步的返回值
5).share(最终布尔friendsCircle,最终VideoB videoB)分享给朋友或者朋友圈如果你有分享图片,图片过大的时候一定要经过压缩,微信官网说明图片不能大
于32KB
6).isWXAppInstalled()检查微信是否安装
7).wxPay(最终BaseActivity活动,字符串ORDER_ID,字符串payType)微信支付我们项目微信支付的一些参数保存在服务器上,所以我这边还请求了自己的
服务器,如果你们是放在本地,直接copy回调函数里面的代码即可.在微信支付监听Actviity中获取支付的状态码
PayReq类属性对应含义请参考微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_12
public class WeiXinPresenter extends Presenter{
private static final int THUMB_SIZE = 150;
public static final int IMAGE_SIZE=32768;//微信分享图片大小限制
public static final String APP_ID = "";
public static final String SECRET="";
private IWXAPI wxAPI;
private IView iView;
private IUserController userController;
@Override
public IView getIView() {
return iView;
}
public WeiXinPresenter(Context context){
if(context!=null && context instanceof IView)
iView =(IView) context;
if(wxAPI==null){
wxAPI = WXAPIFactory.createWXAPI(context,APP_ID,true);
wxAPI.registerApp(APP_ID);
}
if(null==userController)
userController=ControllerFactory.getUserController();
}
/**
* 微信登陆(三个步骤)
* 1.微信授权登陆
* 2.根据授权登陆code 获取该用户token
* 3.根据token获取用户资料
* @param activity
*/
public void login(){
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = String.valueOf(System.currentTimeMillis());
wxAPI.sendReq(req);
}
/**
* 获取微信访问token
*/
public void getAccessToken(String code){
if(!userController.isLogin()){//没有登陆的情况用第三方登陆
userController.getWeiXinAccessToken(APP_ID,SECRET,code,new RequestDataCallback<WeiXinToken>(){
@Override
public void dataCallback(WeiXinToken obj){
if(obj!=null){
if(obj.getErrcode()==0){
// if(MLog.debug){
// iView.showToast("授权用户唯一标识:"+obj.getOpenid());
// }
getWeiXinUserInfo(obj);
}else{
iView.showToast(obj.getErrmsg());
}
}else{
}
}
});
}else{//用户已登陆
}
}
/**
* 获取微信用户信息
*/
private void getWeiXinUserInfo(final WeiXinToken obj){
userController.getWeiXinUserInfo(obj.getAccess_token(), obj.getOpenid(), new RequestDataCallback<RegisterB>() {
@Override
public void dataCallback(RegisterB registerB){
if(registerB!=null&&obj!=null){
registerB.setAccess_token(obj.getAccess_token());
registerB.setToken_expire_at(obj.getExpires_in());
if(registerB.getErrcode()==0){
registerB.setThird_type_name(Constants.WEI_XIN);
thirdLogin(registerB);
}else{
iView.showToast(registerB.getErrmsg());
}
}
}
});
}
/**
* 调用我们自己的服务器进行登录
* @param registerB
*/
private void thirdLogin(RegisterB registerB){
userController.thirdAuth(registerB,new RequestDataCallback<UserP>(){
@Override
public void dataCallback(UserP user){
if(checkCallbackData(user, true)){
if(user.getError()==user.ErrorNone){
iView.showToast(R.string.login_success);
getAppController().sendLoginChangeIntent();
userController.saveLoginUser(user,FileUtil.getFilePath());
((ILoginView)iView).toMain();
}else{
iView.showToast(user.getError_reason());
}
}
}
});
}
/**
* 微信分享
* @param friendsCircle 是否分享到朋友圈
*/
public void share(final boolean friendsCircle,final VideoB videoB){
new LoadPicThread(videoB.getCover_url(),new Handler(){
@Override
public void handleMessage(Message msg) {
byte[] bytes=(byte[]) msg.obj;
if(bytes.length>IMAGE_SIZE){
iView.showToast(R.string.image_no_big);
return;
}
WXVideoObject videoObject = new WXVideoObject();// 视频类型
videoObject.videoUrl = videoB.getShare_url() + Constants.WEI_XIN + "&share_from="+com.kaka.utils.Constants.ANDROID;// 视频播放url
WXMediaMessage wxMessage = new WXMediaMessage(videoObject);
wxMessage.title = videoB.getContent();
wxMessage.thumbData = bytes;
SendMessageToWX.Req req = new SendMessageToWX.Req();
//transaction字段用于唯一标识一个请求
req.transaction = String.valueOf(videoB.getId() + System.currentTimeMillis());
req.message = wxMessage;
req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
wxAPI.sendReq(req);
}
}).start();
}
/**
* 分享邀请有奖
* @param userP 用户信息
*/
public void shareInvitationPrize(UserP userP,Context context,boolean friendsCircle){
WXWebpageObject webpage = new WXWebpageObject();
webpage.webpageUrl = userP.getInvite_url();
WXMediaMessage msg = new WXMediaMessage(webpage);
if(friendsCircle){
msg.title = context.getResources().getString(R.string.share_invitation_prize_content);
}else{
msg.description = context.getResources().getString(R.string.share_invitation_prize_content);
}
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2;
Bitmap thumb = BitmapFactory.decodeResource(context.getResources(), R.drawable.send_cash_register,options);
msg.thumbData = bmpToByteArray(thumb);
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = String.valueOf(userP.getId() + System.currentTimeMillis()); // transaction字段用于唯一标识一个请求
req.message = msg;
req.scene = friendsCircle ? SendMessageToWX.Req.WXSceneTimeline : SendMessageToWX.Req.WXSceneSession;
// 调用api接口发送数据到微信
wxAPI.sendReq(req);
}
private class LoadPicThread extends Thread{
private String url;
private Handler handler;
public LoadPicThread(String url,Handler handler){
this.url=url;
this.handler=handler;
}
@Override
public void run(){
try {
URL picurl = new URL(url);
HttpURLConnection conn = (HttpURLConnection)picurl.openConnection(); // 获得连接
conn.setConnectTimeout(6000);//设置超时
conn.setDoInput(true);
conn.setUseCaches(false);//不缓存
conn.connect();
Message message=handler.obtainMessage();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inSampleSize=2;
message.obj=bmpToByteArray(BitmapFactory.decodeStream(conn.getInputStream(),null,options));
message.sendToTarget();
} catch (Exception e) {
e.printStackTrace();
}
}
}
//检查微信是否安装
public boolean isWXAppInstalled(){
return wxAPI.isWXAppInstalled();
}
public void wxPay(final BaseActivity activity,String order_id,String payType){
activity.showProgress("");
ControllerFactory.getWalletsController().getPayments(order_id, payType, new RequestDataCallback<PaymentsP>() {
@Override
public void dataCallback(PaymentsP obj) {
if(checkCallbackData(obj, true)){
if(obj.getError()==obj.ErrorNone){
PayReq req = new PayReq();//待修改
req.appId = obj.getAppid();
// init(obj.getAppid());
req.nonceStr=obj.getNoncestr();
req.packageValue=obj.getPackage_value();
req.sign=obj.getSign();
req.partnerId=obj.getPartnerid();
req.prepayId=obj.getPrepayid();
req.timeStamp=obj.getTimestamp();
wxAPI.registerApp(obj.getAppid());
wxAPI.sendReq(req);
MLog.i("ansen", "开始进行微信支付..");
// iView.showToast("开始进行微信支付..");
}
}else{
iView.showToast(obj.getError_reason());
}
activity.hideProgress();
}
});
}
强调一点,一定要注意接收微信的请求及返回值的包名跟类名,包名是应用程序的包名+“。wxapi”类名必须是微信指定的类名并且这两个Activity一定要在AndroidManifest.xml中注册,上传一张是我做的app中包名跟类名的截图
如何在活动中调用微信登陆
1)登陆广播监听内部类如果接收到了广播就去获取微信令牌
private class WXEntryReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent){
if(intent.getAction().equals(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN)){
MLog.i("WXEntryReceiver","接收微信登陆广播");
int errCode = intent.getExtras().getInt("errCode");
if(errCode==BaseResp.ErrCode.ERR_USER_CANCEL||errCode==BaseResp.ErrCode.ERR_AUTH_DENIED){
requestDataFinish();
}else{
String code = intent.getExtras().getString("code");
xinTestPresenter.getAccessToken(code);
}
}
}
}
private WXEntryReceiver wxEntryReceiver = NULL;
3)。在OnCreate中中注册广播
//微信登陆广播
wxEntryReceiver= new WXEntryReceiver();
LocalBroadcastManager lbm = LocalBroadcastManager.getInstance(this);
IntentFilter filter = new IntentFilter(APIDefineConst.BROADCAST_ACTION_WEIXIN_TOKEN);
lbm.registerReceiver(wxEntryReceiver,filter);
4)调用微信登陆
WeiXinPresenter xinTestPresenter =new WeiXinPresenter(this);
xinTestPresenter.login();
在Activity中调用微信分享跟调用微信支付的代码我就不贴出来了,我这篇博客只是给大家一个参考的地方,遇到问题还是建议第一时间看官方文档.
说说我在做微信登陆碰到的问题
1.微信登陆,分享,支付回调的活动包名跟类名一定要严格按照要求去写
2.接收回调的是活动一定要在AndroidManifest.xml中中注册
3.WeiXinPresenter中有两个常量APP_ID跟SECRET要去微信申请的时候才有的。你们复制代码的时候要给这两个常量赋值
4.可能访问网络神马的还需要一些权限记得在AndroidManifest.xml中添加权限
5.调用微信的登陆,分享,支付你的安装包一定要有签名,签名信息一定要跟你在微信官网上申请时签名信息一致
6.微信没有客服支持.....如果出了问题看官方的演示或者官方API
7.微信SDK经常升级,如果你开发的时候有最新的就用最新的吧.....
说了那么多,感觉说了一大堆废话......希望能帮到大家....有神马问题可以给我留言....
我在csdn上上传了一个微信sdk的jar包,有需要的可以去下载
推荐一个Android开发者公众号,每周都有原创干货