本实例项目运行条件:
开发环境: 【Android Studio】
1. 到微信开放平台注册帐号并且创建移动应用
https://open.weixin.qq.com/cgi-bin/frame?t=home/app_tmpl&lang=zh_CN
2. 获得移动应用的权限【微信登录】
3. 配置应用签名, 这个签名通过 android打包文件jks生成或者keystore生成
签名文件生成方法:
3.1 keytool -list -v -keystore jks文件(或者keystore文件)
3.2 获取指纹证书md5值, 将md5中的冒号去掉, 大写换成小写 (详情)
总结: 微信开放平台Android应用签名的本质便是我们签名文件jks(或者keystore)的MD5值
4. 应用程序开发完成后,debug模式是无法自动登录的,应用程序必须由相应的jks签名之后生成的apk包才能进行分享(微信会校验应用签名)
2. 流程讲解
1.1 打开app(第一张图),点击【微信登录】,打开微信登录授权页面(第二张图),点击【确认登录】,授权成功后,获得登录人的详细信息(如: openid(微信帐号对应相应应用的唯一标志字符串), 昵称, 头像)
3. 代码详解
3.1 Android端
3.1.1 引入微信相应的jar包
3.1.2 在应用程序包名对应的路径下,新建包 wxapi, 添加新类 WXEntryActivity, 注意这里的包名与类名必须唯一
WXEntryActivity代码:
public class WXEntryActivity extends BaseActivity implements IWXAPIEventHandler { private static final String TAG = "WXEntryActivity"; private static final int RETURN_MSG_TYPE_LOGIN = 1; private static final int RETURN_MSG_TYPE_SHARE = 2; UserServiceImpl userService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); userService = new UserServiceImpl(); Constant.wxApi.handleIntent(getIntent(), this); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); setIntent(intent); Constant.wxApi.handleIntent(intent, this); } @Override public void onReq(BaseReq req) { } /** * 得到支付结果回调 */ @Override public void onResp(BaseResp resp) { switch (resp.errCode) { case BaseResp.ErrCode.ERR_AUTH_DENIED: case BaseResp.ErrCode.ERR_USER_CANCEL: if (RETURN_MSG_TYPE_SHARE == resp.getType()) { showToast("分享失败"); } else if(RETURN_MSG_TYPE_LOGIN == resp.getType()) { showToast("微信自动登录失败"); } finish(); break; case BaseResp.ErrCode.ERR_OK: switch (resp.getType()) { case RETURN_MSG_TYPE_LOGIN: //拿到了微信返回的code,立马再去请求access_token String code = ((SendAuth.Resp) resp).code; //使用微信进行第三方登录 userService .wxlogin(code) .subscribe(new Action1<User>() { @Override public void call(User user) { showToast(user.getOpenid()); Constant.user = user; finish(); } }, new Action1<Throwable>() { @Override public void call(Throwable throwable) { Toast.makeText(WXEntryActivity.this, throwable.getMessage(), Toast.LENGTH_SHORT).show(); finish(); } }); break; case RETURN_MSG_TYPE_SHARE: showToast("微信分享成功"); finish(); break; } break; } } }
3.1.3 点击登录按钮事件代码
判断微信客户端是否安装, 如果未安装则给个提示, 如果已经安装, 拉起微信授权页面,获得相应的code, 根据code去后台获得用户相应的信息(用户信息中不含有微信号)
@OnClick(R.id.login) public void login(){ if (!Constant.wxApi.isWXAppInstalled()) { showToast("您还未安装微信客户端"); return; } final SendAuth.Req req = new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "diandi_wx_login"; Constant.wxApi.sendReq(req); //finish(); }
3.2 JAVA后台代码
3.2.1 由于后台需要调用微信提供的接口函数获取用户信息, 故需要引入相应的jar包
<dependency> <groupId>com.github.liyiorg</groupId> <artifactId>weixin-popular</artifactId> <version>2.8.5</version> </dependency>
3.2.2 配置微信应用对应的 AppID, AppSecret, 注意这里的配置千万不能出错
获取用户信息的操作也可以放在android端,但为了AppID, AppSecret不被盗取,强烈建议放在后台
3.2.3 根据前台传递的 code 与 后台的 APPID, AppSecret 获取用户信息,传递给android端用于显示
@Controller @RequestMapping("/wx") public class WxController { public WxController() { System.out.println("WxController构造函数"); } //访问此资源的url: http://localhost:8080/AutoLogin/wx/wxLogin.htm @RequestMapping(value = "/wxLogin.htm", produces = MediaType.APPLICATION_JSON_VALUE) @ResponseBody public Result wxreg(HttpServletRequest request, String code){ Result result = new Result(); String strAppId = ConfigManager.getInstance().getConfigItem("WXAppID"); String strAppSecret = ConfigManager.getInstance().getConfigItem("WXAppSecret"); SnsToken token = SnsAPI.oauth2AccessToken(strAppId, strAppSecret, code); BaseResult baseResult = SnsAPI.auth(token.getAccess_token(), token.getOpenid()); if("0".equals(baseResult.getErrcode()) && "ok".equals(baseResult.getErrmsg())){ User user = SnsAPI.userinfo(token.getAccess_token(), token.getOpenid(), "zh-CN"); System.out.println("user: " + user.toString()); result.setStateCode("0"); result.setDesc("成功获得信信登录用户"); result.setData(user); }else{ result.setStateCode("-1"); result.setDesc("成功获得信信登录用户"); } return result; } //测试函数 public static void main(String[] args) { // TODO Auto-generated method stub } }