Android微信第三方登录

Android微信第三方登录

转载请注明出处:

http://blog.csdn.net/Kaission/article/details/54670275

前言:

  • 前阵子由于公司需求做了微信、qq原生的第三方登录,由于需求不让使用第三方,像Mob、友盟等,踩了不少坑,在此记录一下,方便以后碰到同样的问题,有个正确的引导。由于qq的比较容易实现,在此本人只整理的微信;由于个人水平有限,如果文章中有错误,请直接联系本人进行改正。谢谢
这里特别吐槽一下官方的开发文档,对于没经验的小白来说,看得懂实在是有些困难,而且jar包都更新迭代了好些次了,开发文档还是老样子。。。
好了,接下来开始我们的接入吧。

首先:

微信的第三方登录功能是付费的,每年需要300软妹币(但是官方开发文档中却说免费提供,坑…),你需要做的是注册,提交相关资料,然后付费(微信的分享功能是免费的),静待审核通过,官方说大概是一周左右的时间。需要注意的是,注册时填写的项目的包名(包名一般是项目的Manifest文件中的包名)和MD5签名字符串,签名字符串官方有获取的工具,对于你后来的调试时非常重要的,后面还会提及到,在此先声明一下。

根据项目需求下载需要的Demo [官方Demo及签名工具下载 ]

以上工作都准备好之后,就可以进入我们的接入工作了

本人的工作环境是Eclipse,AS上面只会更简单,步骤出入不大,差别自行百度,在此不做重点说明

这个是需要引入的jar包,dfs s 这里写图片描述直接粘贴复制到项目的libs目录中,然后buildpath就可以了

接下来,就是关键的代码区了

第一步:在你逻辑需要的地方添加如下代码,发起微信的授权登录:
// 初始化IWXAPI
//这里的第一个参数是环境变量,第二个参数是在微信开放平台上审核通过得到的APP_ID,注意别和secret弄混了
//api变量是IWXAPI类的对象
api = WXAPIFactory.createWXAPI(Content, APP_ID, true);
api.registerApp(APP_ID);
if (api != null && api.isWXAppInstalled()) {
	final SendAuth.Req req = new SendAuth.Req();
	req.scope = "snsapi_userinfo";
	req.state = "wechat_sdk_demo";
	api.sendReq(req);
	DLog.i(TAG, "api: " + api.toString());
	} else
		Toast.makeText(Content, "用户未安装微信", Toast.LENGTH_SHORT)
						.show();

这样就可以调起微信的授权界面了。需要注意的是,微信的第三方登录,需要用户必须安装微信客户端,才能发起登录请求。

这是微信客客户端未登录的效果(也就是微信客户端未登录用户):
这里写图片描述
当微信客户端已经有用户登录时,效果是这样的:
这里写图片描述
这样,第一步就完成了。

接下来是第二步,也是最关键的:

这里需要自定义一个类,WXEntryActivity(必须是这个名字,不然微信回调,也就是上一步点击确认登录的回调);这个类需要继承Activity和实现IWXAPIEventHandler接口,此外,WXEntryActivity类的存放位置也是有讲究的,必须在包名路径下新建一个wxapi的文件夹里面,是必须这么写。效果如下:
这里写图片描述

第三步,就是有关WXEntryActivity这个类里面的详细代码了:

书接第一步,点击授权登录后,IWXAPIEventHandler这个接口会有两个实现的方法onReq、onResp,重要的是后面那个方法,在这个回调方法里,我们要获取微信登录返回到code,
在这里插一句。微信登录大概是这么个流程:首先我们请求微信登录,去获取code。然后拿着这个code再去请求获得openid、accessToken,最后拿着openid 和accessToken才能获取到用户的信息,像name,头像图片的url等。
那么,我们要怎么获取到code呢?这里还有个坑,且听我慢慢道来。。。。

上面说到了这个回调:onResp
我们可以这样写:

@Override
	public void onResp(BaseResp arg0) {
		// TODO Auto-generated method stub
		
		//微信授权返回code的回调
		int errorCode = arg0.errCode;
		switch (errorCode) {
		case BaseResp.ErrCode.ERR_OK:
			//这里是坑,请注意回避。。。。。。
			// 用户同意;此处Android端是token,而不是code;官方的demo里面竟然是code,唉唉唉...
			String code = ((SendAuth.Resp) arg0).token;

			DLog.i(TAG, "code:" + code);
			if (code != null) {
				getAccess_token(code);
			}

			break;
		case BaseResp.ErrCode.ERR_AUTH_DENIED:
			// 用户拒绝

			break;
		case BaseResp.ErrCode.ERR_USER_CANCEL:

			// 用户取消
			break;
		default:
			break;
		}
		//这里需要结束当前的activity,也就是我们的WXEntryActivity,不然会一直卡在这个activity里无法回到我们自己的activity中(本人就是这个问题纠结了好久啊)
		finish();
	}
	

好了,现在我们是拿到了code这个参数了,可是要怎么去获取openid、accessToken进而获取用户信息呢?
去请求这个地址path,填写好我们上一步拿到的code参数,以及之前在微信开放平台审核通过后给的APP_ID和APP_SECERT,就可以返回openid、accessToken了。返回到是一个json字符串,需要解析下。

String path = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
						+ APP_ID
						+ "&secret="
						+ APP_SECRET
						+ "&code="
						+ code
						+ "&grant_type=authorization_code";

最后,我们拿着openid、accessToken,请求这个地址:

String path = "https://api.weixin.qq.com/sns/userinfo?access_token="
						+ access_token + "&openid=" + openid;

同样,返回的也是一个json字符串,需要解析下,就可以拿到nickname、headimgurl等等;

哈哈哈哈,到这里,我们的微信登录就大功告成啦!

咦,等会儿,有同学会说,为什么我都严格按照上面的步骤写的,,怎么会没有成功登录微信呢?发起授权登录没有反应?

唉,继续讲吧,还没有结束嘞!
原本我以为这样就是可以的了,没想到微信在这里又给我们善良的小伙伴们挖了一个坑,微信啊微信…

反思之后,原来我们现在的这个项目是一个Debug包,微信这么严谨的大公司,是不允许不正规的项目登录他们的服务器滴,那,怎么办呢?
没办法,也是唯一的办法,就是签名打包呗,讲下具体操作:

有关Eclipse及AS的签名打包的方法,请读者们自行百度,在这里我只讲重点。
当你完成签名打包,生成一个release.apk文件时,安装到你的测试机或模拟器上,然后重新将我们的包名进行签名,也就是文章一开始提到的微信提供的那个签名工具,就是这个东西:

这里写图片描述

在这里输入你的包名,然后重新生成一个md5的签名字符串,去微信开放平台重填上就好,一般不需要再次审核了。

这次是真的真的完成了,好辛苦,晚上奖励鸡腿一个,哈哈。
没有成功的同学,可以随时找我,在这里,把我的WXEntryActivity完整的代码贴上吧,写的不好,没有优化,凑活着看吧,哈哈。


public class WXEntryActivity extends Activity implements IWXAPIEventHandler {

	private static final String TAG = "WXEntryActivity";
	public static final String APP_ID = "你的appid";
	public static final String APP_SECRET = "你的appkey";
	private IWXAPI api;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		DLog.i(TAG, "APP_ID: " + APP_ID);
		DLog.i(TAG, "APP_SECRET: " + APP_SECRET);
		api = WXAPIFactory.createWXAPI(this, App.WX_APPID, false);
        //将你收到的intent和实现IWXAPIEventHandler接口的对象传递给handleIntent方法
        api.handleIntent(getIntent(), this);
	}

	
	@Override
	protected void onNewIntent(Intent intent) {
		// TODO Auto-generated method stub
		super.onNewIntent(intent);
		setIntent(intent);
	}
		
	
	@Override
	public void onReq(BaseReq arg0) {
		// TODO Auto-generated method stub
		finish();
	}

	@Override
	public void onResp(BaseResp arg0) {
		// TODO Auto-generated method stub
		
		//微信授权返回code的回调
		int errorCode = arg0.errCode;
		switch (errorCode) {
		case BaseResp.ErrCode.ERR_OK:
			// 用户同意;此处Android端是token,而不是code
			String code = ((SendAuth.Resp) arg0).token;

			DLog.i(TAG, "code:" + code);
			if (code != null) {
				getAccess_token(code);
			}

			break;
		case BaseResp.ErrCode.ERR_AUTH_DENIED:
			// 用户拒绝

			break;
		case BaseResp.ErrCode.ERR_USER_CANCEL:

			// 用户取消
			break;
		default:
			break;
		}
		finish();
	}

	/**
	 * 获取openid accessToken值用于后期操作
	 * 
	 * @param code
	 *            请求码
	 */
	private void getAccess_token(final String code) {
		new Thread(new Runnable() {
			@Override
			public void run() {
				String path = "https://api.weixin.qq.com/sns/oauth2/access_token?appid="
						+ APP_ID
						+ "&secret="
						+ APP_SECRET
						+ "&code="
						+ code
						+ "&grant_type=authorization_code";
				try {
					
					//SinaHttpsUtil 为网路请求工具
					String res = SinaHttpsUtil.httpsGet(path, "");// 请求https连接并得到json结果
					DLog.i(TAG, "res :" + res);
					JSONObject jsonObject = new JSONObject(res);
					if (null != jsonObject) {
						String openid = jsonObject.getString("openid")
								.toString().trim();
						String access_token = jsonObject
								.getString("access_token").toString().trim();

						DLog.i(TAG, "openid:" + openid + "   access_token:"
								+ access_token);
						// 获取个人信息
						getUserMsg(access_token, openid);

					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}).start();
	}

	/**
	 * 获取微信的个人信息
	 * 
	 * @param access_token
	 * @param openid
	 */
	private void getUserMsg(final String access_token, final String openid) {
		new Thread(new Runnable() {

			@Override
			public void run() {
				// TODO Auto-generated method stub
				String path = "https://api.weixin.qq.com/sns/userinfo?access_token="
						+ access_token + "&openid=" + openid;
				try {

					String res = SinaHttpsUtil.httpsGet(path, "");// 请求https连接并得到json结果
					JSONObject jsonObject = new JSONObject(res);
					if (null != jsonObject) {
						String nickname = jsonObject.getString("nickname");
						int sex = Integer.parseInt(jsonObject.get("sex")
								.toString());
						String headimgurl = jsonObject.getString("headimgurl");

						DLog.i(TAG, "getUserMesg 拿到了用户微信基本信息.. nickname:"
								+ nickname + " sex:" + sex + " headimurl:"
								+ headimgurl);
					}
				} catch (Exception e) {
					e.printStackTrace();
				}
				return;
			}
		}).start();
	}

}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值