您的位置:首页 > 移动开发 > 微信开发

集成微信第三方登录功能获取微信用户信息

2015-05-28 15:48 976 查看
最近公司要做微信的第三方登录,本来打算直接用第三方的框架就算了,就闲的想自己集成试试看。

然后发现被腾讯坑得不省人事。


前提,应用必须要在微信开发平台上注册,并且通过审核,有微信登录的权限。

首先,下载官方的demo。把libs的jar包拷到自己的工程里。

在应用的包名下,建一个wxapi的包目录,在里建一个叫WXEntryActivity的activity并实现IWXAPIEventHandler监听,用于微信回调数据!

下面是我自己的WXEntryActivity,OnUserInfoListener 是我的数据回调的接口(忽略吧)

public class WXEntryActivity extends Activity implements IWXAPIEventHandler, OnUserInfoListener {

private static final String TAG = "hezb";

private IWXAPI api;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
api = WXAPIFactory.createWXAPI(this, ShareConstants.WX_ID, false);

api.handleIntent(getIntent(), this);
Log.d(TAG, "WXEntryActivity onCreate");
}

@Override
public void onReq(BaseReq arg0) {
switch (arg0.getType()) {
case ConstantsAPI.COMMAND_GETMESSAGE_FROM_WX:
break;
case ConstantsAPI.COMMAND_SHOWMESSAGE_FROM_WX:
break;
default:
break;
}
Log.d(TAG, "WXEntryActivity BaseReq:"+arg0.toString());
/** 打开/重启本APP */
Intent iLaunchMyself = getPackageManager().getLaunchIntentForPackage(getPackageName());
startActivity(iLaunchMyself);
}

@Override
public void onResp(BaseResp arg0) {
String result = null;
switch (arg0.errCode) {
case BaseResp.ErrCode.ERR_OK:
if (arg0 instanceof SendAuth.Resp) {
SendAuth.Resp resp = (SendAuth.Resp) arg0;
if (!TextUtils.isEmpty(resp.token)) {
Log.d(TAG, "resp token:"+resp.token);
//获取用户数据
GetWechatUserInfoThread getWechatUserInfoThread =
new GetWechatUserInfoThread(this, resp.token);
getWechatUserInfoThread.setUserInfoListener(this);
getWechatUserInfoThread.start();
}
} else {
result = "分享成功";
}

break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
result = "分享取消";
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
result = "分享被拒绝";
break;
default:
result = "分享返回";
break;
}
if (!TextUtils.isEmpty(result)) {
Toast.makeText(this, result, Toast.LENGTH_LONG).show();
finish();
}
}

@Override
public void onComplete(Map<String, String> map) {
Log.d(TAG, "wechat map:"+map.toString());
finish();
}

}

在Manifest中,注册该activity注意name
package="com.hezb.demo" 应用的包名,注册就用他

<!-- wechat 回调页 -->

        <activity

            android:name="com.hezb.demo.wxapi.WXEntryActivity"

            android:exported="true" />

第三方登录需执行:

IWXAPI api = WXAPIFactory.createWXAPI(mContext, ShareConstants.WX_ID);

SendAuth.Req req = new SendAuth.Req();

req.scope = "snsapi_userinfo";

req.state = "hezb_share_sdk_demo";//瞎填就行,据说用于防攻击

api.sendReq(req);

这样就启动微信展示是否授权的那个页面,点击确定,WXEntryActivity就会启动,并且调用onResp(BaseResp arg0)方法。

其中arg0就是SendAuth.Resp的对象,可强转。

坑的地方来了,这里官网的开发文档会让你找code,但无奈我找了一天都没找到SendAuth.Resp里有叫code的成员!!!抓狂吧程序员!


但是有一个token的成员,这时,你可能以为token就是access_token,微信简化了需要code来获取access_token的步骤,但是,你又会发现缺少openid这个参数,呵呵,腾讯你特么逗我呢!


然后折腾了半天,最后发现一个坑爹的真相:token就是code!!! 然后就无语了。。。腾讯你更新了好得改一下官方文档啊!
然后照着官方文档获取access_token获取用户信息,就行了。。。

废话不说了,贴上我获取数据的类:

public class GetWechatUserInfoThread extends Thread {

private static final String TAG = "hezb";
/**
* 获取token等信息的地址
* 传递参数: appid, secret, code, grant_type = authorization_code
* 返回参数:access_token, expires_in, refresh_token, openid, scope, unionid
*/
private static final String TOKEN_URL = "https://api.weixin.qq.com/sns/oauth2/access_token";

/**
* 获取用户信息的地址
* 传递参数:access_token, openid
* 返回参数:openid, nickname, sex, province, city, country, headimgurl, privilege, unionid
*/
private static final String USERINFO_URL = "https://api.weixin.qq.com/sns/userinfo";

private Context context;
private String code;
private OnUserInfoListener listener;

/**
* @author hezb
* @date 2015年5月28日下午2:26:23
*/
public GetWechatUserInfoThread(Context context, String code) {
this.context = context;
this.code = code;
}
/**
* 设置数据回调接口
*/
public void setUserInfoListener(OnUserInfoListener listener) {
this.listener = listener;
}

@Override
public void run() {
super.run();

try {
HashMap<String, String> params = new HashMap<String, String>();
params.put("appid", ShareConstants.WX_ID);
params.put("secret", ShareConstants.WX_SECRET);
params.put("code", code);
params.put("grant_type", "authorization_code");

String jsonResult = getJsonResultByUrlPath(context, TOKEN_URL, params);
JSONObject jsonObject = new JSONObject(jsonResult);
String accessToken = jsonObject.optString("access_token", "");
String openid = jsonObject.optString("openid", "");

if (!TextUtils.isEmpty(accessToken) && !TextUtils.isEmpty(openid)) {
params.clear();
params.put("access_token", accessToken);
params.put("openid", openid);
String userInfo = getJsonResultByUrlPath(context, USERINFO_URL, params);
if (listener != null && !TextUtils.isEmpty(userInfo)) {
listener.onComplete(ParseToMap.parse(userInfo, ParseToMap.TYPE_WECHAT));
}
}
} catch (ConnectionException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}

}

/**
     * 网络请求 使用了第三方jar包datadroid
     */
private String getJsonResultByUrlPath(Context context, String urlPath,
HashMap<String, String> params) throws ConnectionException {

String jsonResult = "";

NetworkConnection networkConnection = new NetworkConnection(context,
urlPath);
if (params != null) {
networkConnection.setParameters(params);
}

ConnectionResult connectionResult = null;
connectionResult = networkConnection.execute();
jsonResult = connectionResult.body;
Log.i(TAG, "urlPath " + urlPath + " params " + params
+ " jsonResult " + jsonResult);
return jsonResult;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息