当前位置: 移动技术网 > 移动技术>移动开发>Android > Android调用微信登陆、分享、支付

Android调用微信登陆、分享、支付

2019年07月24日  | 移动技术网移动技术  | 我要评论

用了微信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>(){ 
      @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; 
        } 
        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>() { 
      @override 
      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("开始进行微信支付.."); 
          } 
        }else{ 
          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; 
   
  @override 
  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); 
  } 
  @override 
  protected void onnewintent(intent intent){ 
    super.onnewintent(intent); 
    wxapi.handleintent(getintent(),this); 
    if(mlog.debug) 
      system.out.println("wxentryactivity onnewintent"); 
  } 
  @override 
  public void onreq(basereq arg0) { 
    if(mlog.debug) 
      system.out.println("wxentryactivity onreq:"+arg0); 
    if(mlog.debug) 
      toast.maketext(this, "onreq 方法运行", 0).show(); 
  }  
  @override 
  public void onresp(baseresp resp){ 
    mlog.d("ansen", "onresp....."); 
    if(mlog.debug) 
      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(); 
        break; 
      case baseresp.errcode.err_auth_denied: 
         
        break; 
      } 
      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 intent = new intent(); 
      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 
        } 
        localbroadcastmanager lbm = localbroadcastmanager.getinstance(this); 
        lbm.sendbroadcast(intent); 
    } 
    finish(); 
  } 
}

微信支付 请求跟返回值的接收   微信支付也是发送广播,如果你们还有需求判断支付成功或者失败,可以在广播的intent中进行传参

/** 
 * 微信支付回调activity 
 * @author ansen 
 * @create time 2015-08-29 
 */ 
public class wxpayentryactivity extends activity implements iwxapieventhandler{ 
  private iwxapi wxapi; 
   
  @override 
  protected void oncreate(bundle savedinstancestate) { 
    super.oncreate(savedinstancestate); 
    wxapi = wxapifactory.createwxapi(this, weixinpresenter.app_id); 
    wxapi.handleintent(getintent(), this); 
  } 
   
  @override 
  protected void onnewintent(intent intent){ 
    super.onnewintent(intent); 
    setintent(intent); 
    wxapi.handleintent(intent, this); 
  } 
   
  @override 
  public void onreq(basereq arg0) { 
  } 
 
  @override 
  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{ 
//       toast.maketext(this,r.string.wxpay_success, 0).show(); 
      } 
    } 
    finish(); 
  } 
   
} 

强调一点,一定要注意 接收微信的请求及返回值 的包名跟类名,包名是应用程序的包名+".wxapi"  类名必须是微信指定的类名   并且这两个activity一定要在androidmanifest.xml中注册,上传一张是我做的app中包名跟类名的截图

 

如何在activity中调用微信登陆

1).登陆广播监听内部类  如果接收到了广播就去获取微信token

private class wxentryreceiver extends broadcastreceiver { 
  @override 
  public void onreceive(context context, intent intent){ 
    mlog.i("wxentryreceiver", "接收微信登陆广播"); 
    if(mlog.debug) 
      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(); 
      }else{ 
        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经常升级,如果你开发的时候有最新的就用最新的吧.....

如对本文有疑问, 点击进行留言回复!!

相关文章:

验证码:
移动技术网