简介:
App应用集成第三方登陆,已经是目前常用的功能,虽然现在有服务商集成了第三方登陆,但是平时所用的也就微信和QQ,就自己看文档写了,其中也遇到了一些问题,顾写简单的记录一下。
1、申请开发者权限:
使用微信的第三方登陆功能,必须有微信开放平台开发者账号。并对要接入的第三方登陆应用进行申请,申请通过后,可以获取到应用的AppID和AppSecret,申请的时候有两个地方要注意。**一个是应用的包名,一个是应用的签名**
2、引用资源包:
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
或者
直接加载 lib(需要从官网下载)包
3、manifest加载权限:
<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"/>
4、需要在Application中注册应用到微信平台:
public class ZHApplication extends Application {
public static final String WX_APPID = "wx4683d194d3db0bba";
public static final String WX_APPSecret = "2a2a6debce6680c9102b8d432f07a618";
private IWXAPI _api;
@Override
public void onCreate() {
super.onCreate();
_api = WXAPIFactory.createWXAPI(this, new String(WX_APPID), true);
_api.registerApp(new String(WX_APPID));
}
}
5、创建WXEntryActivity:
在程序包下新建一个名为wxapi的包,并在下面新建一个名为WXEntryActivity的类,并实现IWXAPIEventHandler接口。其中微信发送给第三方应用的请求将会回调onReq方法,第三方应用发送到微信的请求的响应结果将回调nResp方法。在成功响应微信登陆请求后我会发送一个广播,并存储获得的code。code是获取access_token所必需的,具体可以参考微信的文档。
代码如下:(**注意:需要在AndroidManifest中队新添加的类进行注册,并将exported属性设置为true(表示该Activity可以被其它程序调用)**。)
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.widget.Toast;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.ttook.wcmj.ZHConstants;
import com.ttook.wcmj.util.LogUtil;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
private IWXAPI api;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, new String(ZHConstants.WX_APPID_B), 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 = "";
LogUtil.i("==WXEntryActivity==onResp==" + baseResp.errCode);
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
String code = ((SendAuth.Resp) baseResp).code;
SharedPreferences WxSp = getApplicationContext().getSharedPreferences(ZHConstants.SpName, Context.MODE_PRIVATE);
SharedPreferences.Editor WxSpEditor = WxSp.edit(); WxSpEditor.putString(ZHConstants.CODE,code);
WxSpEditor.apply();
Intent intent = new Intent();
intent.setAction(ZHConstants.AUTH_LOGIN_ACTION); 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;
}
}
}
6、微信授权:
授权流程图,官网上有,我截取了一部分,如下
![授权流程图](https://img-blog.csdn.net/20170525104121977?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHhmMDUxNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
按照流程来,请求code,代码如下 /** 开始授权*/
private void weChatAuth() {
if (_api == null) {
_api = WXAPIFactory.createWXAPI(this, new String(ZHApplication.WX_APPID), true);
}
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wx_login_wcmj";
_api.sendReq(req);
}
**执行该操作之后会拉起微信打开授权登陆页面,然后你操作的结果会返回到我们第六步建立的WXEntryActivity类中,若同意请求则可以获取到code执行接下来的操作**
通过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就是我们申请应用时获得的。
正确返回如下:
![这里写图片描述](https://img-blog.csdn.net/20170525105057122?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvbHhmMDUxNQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
最后一步获取第三方登陆的用户个人信息 http请求方式: GET
https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
可以获取到用户的昵称,性别,城市,头像等你需要的信息
protected void requestInfoMsg(final String access_token,final String openid ){
LoadDialog.show(_context);
if(!NetworkUtil.isConnected(this)){
ZHApplication.getApplication(this).showToast("网络连接有误");
LoadDialog.dismiss(_context);
}else{
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, "https://api.weixin.qq.com/sns/userinfo" ,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
LogUtil.d("=获取个人信息=" + response);
try {
JSONObject jsonObject = new JSONObject(response);
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();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Message message = mHandler.obtainMessage();
message.what = ZHConstants.FAILUER;
mHandler.sendMessage(message);
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("access_token", access_token);
map.put("openid", openid);
return map;
}
};
getRequestQueue(_context).add(jsonObjectRequest);
}
}
7、授权过程的详细代码:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.ttook.wcmj.R;
import com.ttook.wcmj.ZHApplication;
import com.ttook.wcmj.ZHConstants;
import com.ttook.wcmj.model.WXModel;
import com.ttook.wcmj.ui.base.BaseActivity;
import com.ttook.wcmj.util.LogUtil;
import com.ttook.wcmj.util.NetworkUtil;
import com.ttook.wcmj.util.SPUtils;
import com.ttook.wcmj.widget.LoadDialog;
import com.ttook.wcmj.wxapi.WXEntryActivity;
import java.util.HashMap;
import java.util.Map;
public class ZHLoginActivity extends BaseActivity {
private Button _thirdLoginBut;
private IWXAPI _api;
private ReceiveBroadCast _receiveBroadCast;
private RequestQueue _requestQueue = null;
private Context _context;
@Override
protected void onCreate() {
setContentView(R.layout.activity_login);
_context = this;
initState();
initReceiveBroadCast();
}
@Override
protected void initView() {
_thirdLoginBut = getViewById(R.id.login_third_button);
}
@Override
protected void setListener() {
_thirdLoginBut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
weChatAuth();
}
});
}
@Override
protected void processLogic(Bundle savedInstanceState) {
}
public void initReceiveBroadCast(){
_receiveBroadCast = new ReceiveBroadCast();
IntentFilter filter = new IntentFilter();
filter.addAction(ZHConstants.AUTH_LOGIN_ACTION);
registerReceiver(_receiveBroadCast, filter);
}
/** 开始授权*/
private void weChatAuth() {
if (_api == null) {
_api = WXAPIFactory.createWXAPI(this, new String(ZHConstants.WX_APPID_B), true);
}
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "wx_login_wcmj";
_api.sendReq(req);
}
/**授权返回广播*/
public class ReceiveBroadCast extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
LogUtil.i("==onReceive()===action==" + intent.getAction());
if (intent.getAction() != null && intent.getAction().equals(ZHConstants.AUTH_LOGIN_ACTION)) {
getAccessToken();
}
}
}
/**
* 单建类,全局只初始化一个对象
* @param context
* @return
*/
private RequestQueue getRequestQueue(Context context) {
if (_requestQueue == null) {
synchronized (WXEntryActivity.class) {
if (_requestQueue == null) {
_requestQueue = Volley.newRequestQueue(context);
}
}
}
return _requestQueue;
}
/** 获取Token等数据*/
protected void getAccessToken(){
SharedPreferences WX_Sp = getApplicationContext().getSharedPreferences(ZHConstants.SpName, Context.MODE_PRIVATE);
final String code = WX_Sp.getString(ZHConstants.CODE, "");
if(!NetworkUtil.isConnected(this)){
ZHApplication.getApplication(this).showToast("网络连接有误");
}else{
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, ZHConstants.WX_ACCESS_TOKEN_URL ,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
WXModel info = WXModel.parseJson(response);
if(info != null && TextUtils.isEmpty(info.getUnionid()) != true) {
Message message = mHandler.obtainMessage();
message.what = ZHConstants.SUCCESS_WX;
message.obj = info;
mHandler.sendMessage(message);
}else{
Message message = mHandler.obtainMessage();
message.what = ZHConstants.FAILUER_WX;
mHandler.sendMessage(message);
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Message message = mHandler.obtainMessage();
message.what = ZHConstants.FAILUER_WX;
mHandler.sendMessage(message);
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("appid", ZHApplication.WX_APPID);
map.put("secret", ZHApplication.WX_APPSecret);
map.put("code", code);
map.put("grant_type", "authorization_code");
return map;
}
};
getRequestQueue(_context).add(jsonObjectRequest);
}
}
private Handler mHandler = new Handler(){
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what){
case ZHConstants.FAILUER_WX:
showToast("微信授权登陆失败");
break;
case ZHConstants.SUCCESS_WX:
WXModel info = (WXModel) msg.obj;
String _unionID = info.getUnionid();
wxGrantSuccessDealWith(_unionID);
break;
case ZHConstants.SUCCESS:
break;
case ZHConstants.FAILUER:
showToast("旺财麻将管理平台登陆授权失败");
finish();
break;
default:
break;
}
LoadDialog.dismiss(_context);
}
};
/**
* 授权后的处理操作
* @param unionId
*/
public void wxGrantSuccessDealWith(String unionId){
if(unionId == null) unionId = "";
LogUtil.i("put SPUtils unionid is " + unionId);
SPUtils.put(_context,ZHConstants.LOGIN_KEY,unionId);
Bundle bundle = new Bundle();
bundle.putString("unionid",unionId);
openActivity(ZHMainActivity.class,bundle);
finish();
}
/** 获取个人信息*/
protected void requestInfoMsg(final String access_token,final String openid ){
LoadDialog.show(_context);
if(!NetworkUtil.isConnected(this)){
ZHApplication.getApplication(this).showToast("网络连接有误");
LoadDialog.dismiss(_context);
}else{
StringRequest jsonObjectRequest = new StringRequest(Request.Method.POST, "https://api.weixin.qq.com/sns/userinfo" ,
new Response.Listener<String>() {
@Override
public void onResponse(String response) {
LogUtil.d("=获取个人信息=" + response);
try {
JSONObject jsonObject = new JSONObject(response);
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();
}
}
},
new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError volleyError) {
Message message = mHandler.obtainMessage();
message.what = ZHConstants.FAILUER;
mHandler.sendMessage(message);
}
}){
@Override
protected Map<String, String> getParams() throws AuthFailureError {
HashMap<String, String> map = new HashMap<>();
map.put("access_token", access_token);
map.put("openid", openid);
return map;
}
};
getRequestQueue(_context).add(jsonObjectRequest);
}
}
@Override
public void onDestroy() {
super.onDestroy();
if(_receiveBroadCast != null)
unregisterReceiver(_receiveBroadCast);
}
}