前几天负责的程序说是要加入第三方登陆的功能,虽然现在有服务商集成了第三方登陆,但是平时所用的也就微信和QQ,就自己看文档写了,其中也遇到了一些问题,然后我把我做这个的流程贴出来,并附上对应的Demo,运行Demo前请将Android的SDK以及依赖包的版本升级到最新。
1:首先如果要使用微信的第三方登陆功能,必须要有微信官方认证的微信开放平台开发者账号,这个需要300一年,当然,还有很多其他很好的功能。
2:对你要接入第三方登陆的应用进行申请,申请通过之后,可以获取到关键的AppID和AppSecret,申请的时候有两个地方要注意,
应用包名是指在你的AndroidManifest文件下的package中的内容,
应用签名工具在微信开放平台中资源下载中的Android资源下下载,之后在你的手机上运行,输入你的应用包名即可得到。
3:下面就是正式开始操作代码,将微信的开发工具包导入你项目的libs目录中。
4:在AndroidManifest.xm添加权限支持,代码如下。
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
5:将你的应用程序注册到微信,只有这样你的程序启动后,微信才能响应你的程序,我是在重写Application的类中注册的,代码如下:
public class App extends Application {
public static final String WX_APPID = "wxb53411a37963b886";
public static final String WX_APPSecret = "d72be30f31c81dcc507d8c08c0d700f8";
private IWXAPI api;
@Override
public void onCreate() {
super.onCreate();
api = WXAPIFactory.createWXAPI(this, WX_APPID, true);
api.registerApp(WX_APPID);
}
}
6:在你的程序包下新建一个名为wxapi的包,并在下面新建一个名为WXEntryActivity的类,并实现IWXAPIEventHandler接口。其中微信发送给第三方应用的请求将会回调onReq方法,第三方应用发送到微信的请求的响应结果将回调nResp方法。在成功响应微信登陆请求后我会发送一个广播,并存储获得的code。code是获取access_token所必需的,具体可以参考微信的文档。代码如下:
public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, App.WX_APPID, false);
//将你收到的intent和实现IWXAPIEventHandler接口的对象传递给handleIntent方法
api.handleIntent(getIntent(), this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
api.handleIntent(intent, this);
finish();
}
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
String result = "";
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
String code = ((SendAuth.Resp) baseResp).code;
SharedPreferences WxSp = getApplicationContext().getSharedPreferences(PrefParams.spName, Context.MODE_PRIVATE);
SharedPreferences.Editor WxSpEditor = WxSp.edit();
WxSpEditor.putString(PrefParams.CODE,code);
WxSpEditor.apply();
Intent intent = new Intent();
intent.setAction("authlogin");
WXEntryActivity.this.sendBroadcast(intent);
finish();
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = "发送取消";
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
finish();
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = "发送被拒绝";
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
finish();
break;
default:
result = "发送返回";
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
finish();
break;
}
}
}
然后还需要在AndroidManifest中队新添加的类进行注册,并将exported属性设置为true(表示该Activity可以被其它程序调用)。
7:微信授权流程如下:这是官网上看的
按照流程来,请求code,代码如下:
private void weChatAuth() {
if (api == null) {
api = WXAPIFactory.createWXAPI(getActivity(), App.WX_APPID, true);
}
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wx_login_duzun";
api.sendReq(req);
}
执行该操作之后会拉起微信打开授权登陆页面,然后你操作的结果会返回到我们第六步建立的WXEntryActivity类中,若同意请求则可以获取到code执行接下来的操作。
8:通过code获取access_token,按下面的请求可以获取access_token
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
这里的APPID和SECRET就是我们申请应用时获得的。
正确返回如下:
{ “access_token”:”ACCESS_TOKEN”, “expires_in”:7200,
“refresh_token”:”REFRESH_TOKEN”, “openid”:”OPENID”, “scope”:”SCOPE”,
“unionid”:”o6_bmasdasdsad6_2sgVt7hMZOPfL” }
我是这样实现的
public void getAccessToken(){
SharedPreferences WX_Sp = getApplicationContext().getSharedPreferences(PrefParams.spName, Context.MODE_PRIVATE);
String code = WX_Sp.getString(PrefParams.CODE, "");
final SharedPreferences.Editor WX_SpEditor = WX_Sp.edit();
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
+ App.WX_APPID
+ "&secret="
+ App.WX_APPSecret
+ "&code="
+ code
+ "&grant_type=authorization_code";
Utils.log("获取access_token的地址"+url);
HttpUtil.sendHttpRequest(url, new HttpCallBackListener() {
@Override
public void onFinish(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
String access_token = jsonObject.getString("access_token");
Utils.log("---------access_token---------"+access_token);
String openid = jsonObject.getString("openid");
Utils.log("---------open_id---------"+openid);
String refresh_token = jsonObject.getString("refresh_token");
if (!access_token.equals("")) {
WX_SpEditor.putString(PrefParams.ACCESS_TOKEN, access_token);
WX_SpEditor.apply();
}
if (!refresh_token.equals("")) {
WX_SpEditor.putString(PrefParams.REFRESH_TOKEN, refresh_token);
WX_SpEditor.apply();
}
if (!openid.equals("")) {
WX_SpEditor.putString(PrefParams.WXOPENID, openid);
WX_SpEditor.apply();
ThirdLoginWeChat(access_token, openid);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onError(Exception e) {
Utils.showToast(LoginActivity.this, "通过code获取数据没有成功");
}
});
}
因为只是登陆而已,所以我没有请求refresh_token,也很简单,获取到access_token之后按照要求请求就可以了,
9:最后一步就是获取你需要的第三方登陆的用户个人信息了
请求说明
http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
可以获取到用户的昵称,性别,城市,头像等你需要的信息,我的请求代码如下:
private void ThirdLoginWeChat(String access_token, String openid) {
String url = "https://api.weixin.qq.com/sns/userinfo?access_token="
+ access_token
+ "&openid="
+ openid;
HttpUtil.sendHttpRequest(url, new HttpCallBackListener() {
@Override
public void onFinish(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
Utils.log(jsonObject.toString()+"-------获取个人信息---");
String nickName = jsonObject.getString("nickname");
String sex = jsonObject.getString("sex");
String province = jsonObject.getString("province");
String city = jsonObject.getString("city");
String country = jsonObject.getString("country");
String headimgurl = jsonObject.getString("headimgurl");
String privilege = jsonObject.getString("privilege");
String unionid = jsonObject.getString("unionid");
} catch (JSONException e) {
e.printStackTrace();
}
}
@Override
public void onError(Exception e) {
}
});
}```
更详细的Demo里面都有,有什么不清楚的地方可以留言,当然鉴于我个人的初级水平,错误的地方希望加以斧正。感谢~
demo演示图片: