android实现微信联合登录开发示例
随着现在社交app的越来越普及,微信,qq,微博几乎成了我们每个人的手机必备,而且第三方应用也越来越多,不是每个用户都想为你的应用注册一个独立帐号的,所以联合登录也就显得尤为重要,成了我们不得不掌握的开发要点,但你要用微信等帐号实现联合登录,人家也有要求,就是你必须遵守oauth2.0协议标准()就行。
接下来我们就以android studio为平台,介绍下接入微信的整个流程:
这里有一个官方参考资料:
那么在接入之前,我们还有一些准备工作要做:
1):登录微信开放平台,完成账号申请:
2):提交app完成审核,并开通相应权限:
在提交app完成审核的过程中,我们需要提供app的包名与签名:
包名就是我们创建app时候的名称,可以通过manifest.xml和build.gradle中查看,如在manifest.xml中:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.yeejay.reader" > ...
在build.gradle中:
defaultconfig { applicationid "com.yeejay.reader" ... }
如果manifest.xml与build.gradle中不一致,将以build.gradle中的声明为准:
应用签名的获取会有一些麻烦,因为我们需要通过签名工具对我们的应用进行签名,如果不进行签名,每次安装apk时android平台会为我们生成默认签名,由于平台的不一致性,导致我们的apk装到不同的手机上签名不一致,最后导致无法正常使用微信登录与分享功能,所以我们要提前做好统一签名,整个签名流程如下:
(1)点击 build ---> generate signed apk... ---> 选择app module ---> 填写生成keystore.jks的目录,密钥,有效期等信息;
(2)将生成的keystore.jks文件拷贝到project目录下的app目录下;
(3)在build.gradle文件中进行配置,代码如下:
signingconfigs { release { storefile file('keystore.jks') storepassword 'xxx' keyalias 'xxx' keypassword 'xxx' } } buildtypes { release { minifyenabled false proguardfiles getdefaultproguardfile('proguard-android.txt'), 'proguard-rules.pro' signingconfig signingconfigs.release } debug { signingconfig signingconfigs.release } }
将配置中的xxx改为生成keystore.jks时的密码信息;
(4)sync同步下项目代码,完成后在右边的gradle projects/app/build目录下双击assembledebug或assemblerelease即可生成对应版本带有签名的apk。
(5)下载apk签名检测工具:
https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_cn
在最下面有一个签名生成工具,单击下载进行下载;
(6)将下载的apk签名工具安装到手机上,将之前生成的带有签名认证的apk也装到手机上,打开签名工具apk,如下图:
输入包名,点击按钮生成对应的数字签名;
(7) 将包名与数字签名注册到我们的app审核过程中;
(8)漫长的等待...,也许是两三天,也许一两个礼拜。当我们的应用申请通过时,微信开放平台会返回给我们app_id与app_secret信息。
当应用审核通过后,就到我们的代码实施阶段了,不过在写代码之前,我们先来了解一下oauth2.0它的一个认证流程:
整个过程的交互一共七个流程,当用户使用第三方应用请求微信登录时,此时会调起微信登录确认页面,并请求微信oauth2.0进行授权,当用户确认登录时,这时微信平台会拉起我们的第三方应用,并将带有临时票据的信息返回给我们的第三方应用,当我们的应用拿到微信的临时票据时,我们就可以根据它的票据的code信息,再加上我们应用的appid与appsecret信息换取access_token。当然,为了用户帐号信息的保存,这个过程一般都是由我们的第三方应用的服务器完成的,我们只需要将我们的code传给我们的服务器,由服务器最终完成与微信平台的token换取。
接下来就是开始写代码了,首先我们需要下载微信的sdk包,在build.gradle中,添加下面一行代码:
dependencies { ... compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+' ... }
sync,将会下载我们最新的sdk版本。如果下载失败我们也可以使用离线包,添加到app/lib目录中,并添加引用即可(由于前段时间jcenter下架了微信的sdk,导致开发的过程中发现不能直接使用,这时候可以考虑在lib中添加即可);
根据微信开发平台的官方要求,调起微信登录的处理逻辑必须放在我们应用的包名.wxapi目录下,否则会报错。这点可以参考微信提供的官方sdkdemo,https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_cn 在范例代码进行下载。不过这里下载的代码可能会因为编码的原因,导致汉语注释变成了混乱字符,后来将utf-8编码改为gbk就ok了。
我们看一下代码的实现逻辑:
public class wxentryactivity extends activity implements iwxapieventhandler { public static final string app_id = "xxxxxxxxxx"; public static final string app_secret = "xxxxxxxxxx"; private static final string weixin_scope = "snsapi_userinfo"; private static final string weixin_state = "login_wx"; private iwxapi api; private sendauth.req req; private textview loginwx; private user user; private string wxcode; @override protected void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.login_wx); loginwx = (textview) findviewbyid(r.id.login_wx); api = wxapifactory.createwxapi(this, app_id, false); api.registerapp(app_id); try { api.handleintent(getintent(), this); } catch (nullpointerexception e) { e.printstacktrace(); } initlistener(); } private void initlistener() { loginwx.setonclicklistener(new view.onclicklistener() { @override public void onclick(view v) { sendauth(); } }); } private void sendauth() { req = new sendauth.req(); req.scope = weixin_scope; req.state = weixin_state; api.sendreq(req); } @override public void onreq(basereq basereq) { } @override public void onresp(baseresp baseresp) { int type = baseresp.gettype(); if (type == 1) { // 登录 sendauth.resp sendauthresp = (sendauth.resp) baseresp; wxcode = sendauthresp.code; string state = ((sendauth.resp) baseresp).state; int errcode = baseresp.errcode; intent intent = new intent(wxentryactivity.this, homeactivity.class); intent.putextra("login", "login"); intent.putextra("wxcode", wxcode); startactivity(intent); yeeutils.animopenactivity(this); finish(); } } @override public void finish() { super.finish(); yeeutils.animcloseactivity(this); } @override protected void ondestroy() { super.ondestroy(); api.unregisterapp(); } }
要实现微信登录的功能,我们的代码就必须实现iwxapieventhandler接口,实现onreq()与onresp()接口,首先我们要在activity创建的时候需要进行一些初始化的操作,这个照写就是:
api = wxapifactory.createwxapi(this, app_id, false); api.registerapp(app_id); try { api.handleintent(getintent(), this); } catch (nullpointerexception e) { e.printstacktrace(); }
当我们进行微信登录时,整个认证流程也就从sendauth()开始了,当调起微信登录并确认后,这个时候微信sdk会调起我们的当前activity并触发onresp()回调,并传回code信息,这时候我们就可以将接下来的处理交给我们的服务器,由它完成对微信token的换取。
当然如果你想自己实现对微信token的获取以及接下来的操作,也是可以的,不过不建议这样使用,下面就是获取token的代码:
private void getresult(string code) { string url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=" + app_id + "&secret=" + app_secret + "&code=" + code + "&grant_type=authorization_code"; jsonobjectrequest request = new jsonobjectrequest(request.method.post, url, null, new successresponse(), new errorlistener()); studyapplication.getinstance().newrequestqueue(this).add(request); } class successresponse implements response.listener<jsonobject> { @override public void onresponse(jsonobject response) { if (null != response) { string openid = null; try { openid = response.getstring("openid") .tostring().trim(); string access_token = response .getstring("access_token").tostring().trim(); sharepreferencehelper.putvalue(getapplicationcontext(), "access_token", access_token); getuid(openid, access_token); } catch (jsonexception e) { e.printstacktrace(); } } } }
通过这一步那么我们就拿到了用户的token信息,使用token我们就可以获取到用户信息,包括昵称,性别,头像,地址等信息,我们接下来看getuid()中的实现:
private void getuid(final string openid, final string accesstoken) { string url = "https://api.weixin.qq.com/sns/userinfo?access_token=" + accesstoken + "&openid=" + openid; jsonobjectrequest request = new jsonobjectrequest(request.method.post, url, null, new uidsuccessresponse(), new errorlistener()); studyapplication.getinstance().newrequestqueue(this).add(request); } class uidsuccessresponse implements response.listener<jsonobject> { @override public void onresponse(jsonobject response) { if (response == null) { return; } string nickname = null; nickname = response.optstring("nickname"); string unionid = response.optstring("unionid"); string headurl = response.optstring("headimgurl"); sharepreferencehelper.putvalue(getapplicationcontext(), "nickname", nickname); sharepreferencehelper.putvalue(getapplicationcontext(), "photourl", headurl); sharepreferencehelper.putvalue(getapplicationcontext(), "uin", unionid); if (user == null) { user = new user(); } user.setuin(unionid); user.setnickname(nickname); user.setheadimgurl(headurl); ... } };
当拿到用户的私人信息后,我们就完成了整个流程,但这些信息不应该由我们自己处理,所以当需要获取用户信息时,我们应该请求我们自己的服务器,然后由服务器再去请求微信服务器,这样的流程才是安全可靠的。
除了微信登录,微信sdk还集成了微信好友分享,朋友圈分享,小程序分享(比较早的版本是没有的...)等功能,分享内容包括图片,文本,网页等,这就看我们的需求了,分享这块我就不写了,大家可以参考下官方的sdkdemo关于分享的代码。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。