本文比较适合新手玩家,老玩家就不要看了
昨天整了下微信登陆,乍一看官方文档还有点难懂!遂自己整理了下流程,给大家参考参考。
官方文档链接:准备工作 | 微信开放文档微信开发者平台文档https://developers.weixin.qq.com/doc/oplatform/Mobile_App/WeChat_Login/Development_Guide.html
第一步 :申请应用AppID
申请地址:微信开放平台https://open.weixin.qq.com注意事项:包名和签名信息一定不能错,错了拉不起微信!应用通过审核了才能进行测试。
第二步:项目添加依赖
在app的build.grade文件里添加微信的依赖。至此,微信已经成功集成了
dependencies {
//微信
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
第三步:请求调用微信登陆
在需要调用微信登陆的地方调用下面方法,参数【你的微信appid】换成你自己的,第一步注册的那个就是这个玩意。
private void wcLogin() {
//发起登陆请求前先注册微信api
IWXAPI api = WXAPIFactory.createWXAPI(this,“你的微信appid”,true);
api.registerApp(“你的微信appid”);
if (!api.isWXAppInstalled()){
//todo 提醒未安装微信
return;
}
//开始发起登陆请求
final SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "自定义state";
api.sendReq(req);
}
第四步:创建微信回调的Activity
Activity路径一定要为:你的包名+/wxapi/WXEntryActivity
例如我的包名是:com.aaa.bbb
那么回调activity的路径就是com.aaa.bbb.wxapi.WXEntryActivity
该Activity需要实现IWXAPIEventHandler的接口。
然后在注册文件AndroidManifest.xml中注册该Activity
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:launchMode="singleTask">
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
exported属性一定要为true!另外注册文件AndroidManifest.xml中在权限下方添加安装包查询的请求权限,否则新版本无法检查出是否安装微信,直接拉不起来。
<uses-permission android:name="android.permission.INTERNET" />
<!-- 方案2 -->
<queries>
<package android:name="com.tencent.mm" />
</queries>
activity代码
package com.aaa.bbb.wxapi;
import androidx.appcompat.app.AppCompatActivity;
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 okhttp3.Response;
public class WXEntryActivity extends Activity implements IWXAPIEventHandler {
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
switch (baseResp.errCode){
case BaseResp.ErrCode.ERR_OK:
//拉起微信成功
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
//("授权出错");
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
//"用户取消登陆"
break;
default:
break;
}
}
}
第五步:获取微信的Token
到这一步我们已经成功的拉起微信了,如果没有成功,检查下签名和包名是否和开放平台的填写一致,是否添加了<queries>权限,或者acitivty的expoted是否为ture等,都有可能导致拉不起微信。
接下来我们开始获取token
在case BaseResp.ErrCode.ERR_OK:中,
getAccessToken(((SendAuth.Resp)baseResp).code);
private void getAccessToken(String code) {
//binding.tvLogin.setText("获取token中");
String url = "https://api.weixin.qq.com/sns/oauth2/access_token?"
+"appid="+“你的appid”
+"&secret="+“你的appSecret”
+"&code="+code
+"&grant_type=authorization_code";
//todo 这个get请求自己封装吧
HttpUtil.getInstance().doGet(url, new HttpUtil.CallBack() {
@Override
public void success(String jsong) {
log("请求token:"+jsong);
Gson gson = new Gson();
//todo 这个bean也自己解析吧
WXAccessTokenBean bean = gson.fromJson(jsong,WXAccessTokenBean.class);
if (isEmpty(bean.getErrMsg())){
refreshToken(bean);
}else {
loginFail(bean.getErrCode()+bean.getErrMsg());
}
}
@Override
public void failed(Exception e) {
loginFail("获取token失败:"+e.toString());
}
});
}
如代码中所示,把【你的appid】换成步骤1中的appid,然后步骤一通过审核后可以创建appSecret,创建好之后记得保存,他只显示一次;然后填到代码中【你的appSecret】位置。
第六步:刷新Token
官方文档说token有效期是2个小时,本人开始测试的时候,这个操作没做也能做第七步,但本着严谨的原则,还是按官方操作吧。官方说这个刷新操场相当于对token进行一个续时。
private void refreshToken(WXAccessTokenBean bean) {
binding.tvLogin.setText("刷新token中");
String url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?"
+"appid="+“你的appid”
+"&grant_type=refresh_token"
+"&refresh_token="+bean.getRefreshToken();
HttpUtil.getInstance().doGet(url, new HttpUtil.CallBack() {
@Override
public void success(String jsong) {
log("刷新token:"+jsong);
Gson gson = new Gson();
WXAccessTokenBean bean1 = gson.fromJson(jsong,WXAccessTokenBean.class);
if (isEmpty(bean1.getErrMsg())){
getUerInfo(bean1);
}else {
getUerInfo(bean);
}
}
@Override
public void failed(Exception e) {
getUerInfo(bean);
}
});
}
所以,这一步如果成功了,我就用新的bean1去请求微信用户数据,如果失败了,我就用第五步的bean去请求了。。
第七步:获取微信用户数据
private void getUerInfo(WXAccessTokenBean bean) {
binding.tvLogin.setText("获取微信用户信息中");
String url = "https://api.weixin.qq.com/sns/userinfo?"
+"access_token="+bean.getAccessToken()
+"&openid="+bean.getOpenid();
HttpUtil.getInstance().doGet(url, new HttpUtil.CallBack() {
@Override
public void success(String jsong) {
Gson gson = new Gson();
log("请求用户信息:"+jsong);
WXUserInfoBean bean1 = gson.fromJson(jsong,WXUserInfoBean.class);
if (isEmpty(bean1.getErrMsg())){
loginByWx(bean1);
}else {
loginFail("获取用户信息失败:"+bean1.getErrCode()+bean1.getErrMsg());
}
}
@Override
public void failed(Exception e) {
loginFail("获取用户信息失败:"+e.toString());
}
});
}
获取到的bean依旧大家自己去解析吧。
第八步:用获取到的微信数据调取自己服务器的登陆注册结果
获取到了这些就可以用获取的数据去调起自己服务器的登陆注册接口了。
附录:
最后本人良心发现,还是把bean附上吧,如果参考我的这个集成成功了,记得留个言哦,这样我才会有点动力
WXAccessTokenBean
package com.aaa.bbb.beans;
import com.google.gson.annotations.SerializedName;
public class WXAccessTokenBean {
@SerializedName("errcode")
private String errCode;
@SerializedName("errmsg")
private String errMsg;
public String getErrCode() {
return errCode;
}
public String getErrMsg() {
return errMsg;
}
@SerializedName("access_token")
private String accessToken;
@SerializedName("expires_in")
private Integer expiresIn;
@SerializedName("refresh_token")
private String refreshToken;
@SerializedName("openid")
private String openid;
@SerializedName("scope")
private String scope;
@SerializedName("unionid")
private String unionid;
public String getAccessToken() {
return accessToken;
}
public Integer getExpiresIn() {
return expiresIn;
}
public String getRefreshToken() {
return refreshToken;
}
public String getOpenid() {
return openid;
}
public String getScope() {
return scope;
}
public String getUnionid() {
return unionid;
}
}
WXUserInfoBean
package com.aaa.bbb.beans;
import com.google.gson.annotations.SerializedName;
import java.util.List;
public class WXUserInfoBean {
@SerializedName("errcode")
private String errCode;
@SerializedName("errmsg")
private String errMsg;
public String getErrCode() {
return errCode;
}
public String getErrMsg() {
return errMsg;
}
@SerializedName("openid")
private String openid;
@SerializedName("nickname")
private String nickname;
@SerializedName("sex")
private Integer sex;
@SerializedName("language")
private String language;
@SerializedName("city")
private String city;
@SerializedName("province")
private String province;
@SerializedName("country")
private String country;
@SerializedName("headimgurl")
private String headimgurl;
@SerializedName("privilege")
private List<?> privilege;
@SerializedName("unionid")
private String unionid;
public String getOpenid() {
return openid;
}
public String getNickname() {
return nickname;
}
public Integer getSex() {
return sex;
}
public String getLanguage() {
return language;
}
public String getCity() {
return city;
}
public String getProvince() {
return province;
}
public String getCountry() {
return country;
}
public String getHeadimgurl() {
return headimgurl;
}
public List<?> getPrivilege() {
return privilege;
}
public String getUnionid() {
return unionid;
}
}