前言:用了微信sdk各种痛苦,感觉比qq sdk调用麻烦多了,回调过于麻烦,还必须要在指定包名下的actvity进行回调,所以我在这里写一篇博客,有这个需求的朋友可以借鉴一下,以后自己别的项目有用到也有个找资料的地方.
一.微信登陆分三个步骤:
1).微信授权登陆
2).根据授权登陆code 获取该用户token
3).根据token获取用户资料
4).接收微信的请求及返回值 如果你的程序需要接收微信发送的请求,或者接收发送到微信请求的响应结果,需要下面3步操作:
a. 在你的包名相应目录下新建一个wxapi目录,并在该wxapi目录下新增一个wxentryactivity类,该类继承自activity(例如应用程序的包名为net.sourceforge.simcpux,
则新添加的类如下图所示)
并在manifest文件里面加上exported属性,设置为true,例如:
b. 实现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?chapter=8_5
四.贴上代码进行讲解
我把微信登陆,分享,支付都封装到了一个类里面了,你们可以参考这个类.封装了6个方法,我对几个需要的方法介绍一下
1).构造方法:初始化对象的时候,顺便初始化微信对象,把app_id注册到微信
2).login() 发起一个登陆的请求 在微信登陆监听actviity中获取code
3).getaccesstoken(string code) 当你从监听activity中获取了code之后就可以通过这个方法获取微信访问token了
4).getweixinuserinfo(final weixintoken obj) 获取微信用户信息 传入一个weixintoken对象,这个对象是第三步的返回值
5).share(final boolean friendscircle,final videob videob) 分享给朋友或者朋友圈 如果你有分享图片,图片过大的时候一定要经过压缩,微信官网说明图片不能大
于32kb
6).iswxappinstalled() 检查微信是否安装
7).wxpay(final baseactivity activity,string order_id,string paytype) 微信支付 我们项目微信支付的一些参数保存在服务器上,所以我这边还请求了自己的
服务器,如果你们是放在本地,直接copy回调函数里面的代码即可.在微信支付监听actviity中获取支付的状态码
payreq类属性对应含义请参考微信官方文档:https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=9_12
/**
* 微信分享,登陆,支付
* @author ansen
* @create time 2015-08-29
*/
public class weixinpresenter extends presenter{
public static final int image_size=32768;//微信分享图片大小限制
public static final string app_id = "";//应用唯一标识,在微信开放平台提交应用审核通过后获得
public static final string secret="";//应用密钥appsecret,在微信开放平台提交应用审核通过后获得
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){
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>(){
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();
iview.showtoast(user.geterror_reason());
* 微信分享
* @param friendscircle 是否分享到朋友圈
public void share(final boolean friendscircle,final videob videob){
new loadpicthread(videob.getcover_url(),new handler(){
public void handlemessage(message msg) {
byte[] bytes=(byte[]) msg.obj;
if(bytes.length>image_size){
iview.showtoast(r.string.image_no_big);
return;
system.out.println("图片长度:"+bytes.length);
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();
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();
bitmap bmp=bitmapfactory.decodestream(conn.getinputstream());
bytearrayoutputstream output = new bytearrayoutputstream();
bmp.compress(bitmap.compressformat.jpeg, 100, output);
int options = 100;
while (output.tobytearray().length > image_size && options != 10) {
output.reset(); // 清空baos
bmp.compress(bitmap.compressformat.jpeg, options, output);// 这里压缩options%,把压缩后的数据存放到baos中
options -= 10;
bmp.recycle();
byte[] result = output.tobytearray();
output.close();
message message=handler.obtainmessage();
message.obj=result;
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>() {
public void datacallback(paymentsp obj) {
if(checkcallbackdata(obj, true)){
if(obj.geterror()==obj.errornone){
payreq req = new payreq();//待修改
req.appid = 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("开始进行微信支付..");
iview.showtoast(obj.geterror_reason());
activity.hideprogress();
}
微信登陆以及分享 请求跟返回值的接收 我这边登陆.分享的状态都是发送广播出去,然后结束当前的activity.
* 微信登陆分享回调activity
* @author ansen
* @create time 2015-05-25
public class wxentryactivity extends activity implements iwxapieventhandler{
private iwxapi wxapi;
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
if(mlog.debug)
system.out.println("wxentryactivity oncreate");
wxapi = wxapifactory.createwxapi(this,weixinpresenter.app_id,true);
wxapi.registerapp(weixinpresenter.app_id);
wxapi.handleintent(getintent(), this);
protected void onnewintent(intent intent){
super.onnewintent(intent);
wxapi.handleintent(getintent(),this);
system.out.println("wxentryactivity onnewintent");
public void onreq(basereq arg0) {
system.out.println("wxentryactivity onreq:"+arg0);
toast.maketext(this, "onreq 方法运行", 0).show();
public void onresp(baseresp resp){
mlog.d("ansen", "onresp.....");
toast.maketext(this,"onresp 方法运行", 0).show();
if(resp.gettype()==constantsapi.command_sendmessage_to_wx){//分享
switch (resp.errcode){
case baseresp.errcode.err_ok:
if(mlog.debug)
toast.maketext(wxentryactivity.this, "分享成功!", toast.length_short).show();
break;
case baseresp.errcode.err_user_cancel:
// toast.maketext(wxentryactivity.this, "分享取消!", toast.length_short).show();
case baseresp.errcode.err_auth_denied:
intent intent = new intent();
intent.setaction(apidefineconst.broadcast_action_weixin_share);
localbroadcastmanager lbm = localbroadcastmanager.getinstance(this);
lbm.sendbroadcast(intent);
}else if(resp.gettype()==constantsapi.command_sendauth){//登陆发送广播
sendauth.resp authresp = (resp) resp;
string code = authresp.code;
intent.setaction(apidefineconst.broadcast_action_weixin_token);
intent.putextra("errcode", authresp.errcode);
if (authresp.errcode == baseresp.errcode.err_ok){//用户同意
intent.putextra("code", code);
if(mlog.debug)
toast.maketext(this, "wxentryactivity 发送登陆广播!!!!", 0).show();
if (android.os.build.version.sdk_int >= 12) {
intent.setflags(32);//3.1以后的版本需要设置intent.flag_include_stopped_packages
finish();
微信支付 请求跟返回值的接收 微信支付也是发送广播,如果你们还有需求判断支付成功或者失败,可以在广播的intent中进行传参
* 微信支付回调activity
public class wxpayentryactivity extends activity implements iwxapieventhandler{
wxapi = wxapifactory.createwxapi(this, weixinpresenter.app_id);
setintent(intent);
wxapi.handleintent(intent, this);
public void onresp(baseresp resp) {
mlog.i("微信支付回调..", "ansen onresp");
if (resp.gettype() == constantsapi.command_pay_by_wx){//微信支付回调
if(resp.errcode==baseresp.errcode.err_ok){//微信支付成功
intent intent = new intent();
intent.setaction(apidefineconst.broadcast_action_weixin_pay);
localbroadcastmanager lbm = localbroadcastmanager.getinstance(this);
lbm.sendbroadcast(intent);
//成功
// toast.maketext(this,r.string.wxpay_success, 0).show();
}else{
强调一点,一定要注意 接收微信的请求及返回值 的包名跟类名,包名是应用程序的包名+".wxapi" 类名必须是微信指定的类名 并且这两个activity一定要在androidmanifest.xml中注册,上传一张是我做的app中包名跟类名的截图
如何在activity中调用微信登陆
1).登陆广播监听内部类 如果接收到了广播就去获取微信token
private class wxentryreceiver extends broadcastreceiver {
public void onreceive(context context, intent intent){
mlog.i("wxentryreceiver", "接收微信登陆广播");
showtoast("接收微信登陆广播");
if(intent.getaction().equals(apidefineconst.broadcast_action_weixin_token)){
int errcode = intent.getextras().getint("errcode");
if(mlog.debug)
system.out.println("获取错误码:"+errcode);
if(errcode==baseresp.errcode.err_user_cancel||errcode==baseresp.errcode.err_auth_denied){
requestdatafinish();
string code = intent.getextras().getstring("code");
xintestpresenter.getaccesstoken(code);
2).定义成员变量
private wxentryreceiver wxentryreceiver=null;
3).在oncreate中注册广播
//微信登陆广播
wxentryreceiver= new wxentryreceiver();
localbroadcastmanager lbm = localbroadcastmanager.getinstance(this);
intentfilter filter = new intentfilter();
filter.addaction(apidefineconst.broadcast_action_weixin_token);
lbm.registerreceiver(wxentryreceiver,filter);
4).调用微信登陆
weixinpresenter xintestpresenter=new weixinpresenter(this);
xintestpresenter.login();
在activity中调用微信分享跟调用微信支付的代码我就不贴出来了,我这篇博客只是给大家一个参考的地方,遇到问题还是建议第一时间看官方文档.
说说我在做微信登陆碰到的问题
1.微信登陆、分享、支付 回调的activity 包名跟类名一定要严格按照要求去写
2.接收回调的是activity 一定要在androidmanifest.xml中注册
3.weixinpresenter中有两个常量 app_id跟secret 要去微信申请的时候才有的.你们copy代码的时候要给这两个常量赋值
4.可能访问网络神马的还需要一些权限 记得在androidmanifest.xml添加权限
5.调用微信的登陆、分享、支付 你的安装包一定要有签名,签名信息一定要跟你在微信官网上申请时签名信息一致
6.微信没有客服支持。。。。。如果出了问题看官方demo 或者 官方api
7.微信sdk经常升级,如果你开发的时候有最新的就用最新的吧.....
说了那么多,感觉说了一大堆废话......希望能帮到大家....有神马问题可以给我留言....
推荐下自己创建的android qq群:202928390 欢迎大家的加入.