如何在 Android 应用中集成微信登录

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

在应用里集成第三方登录是比较常见的需求,尤其是微信登录,但是由于微信官方文档许久没有维护,直接上手还是会走一些弯路,本文将介绍当前移动端集成微信登录的方法。

1. 注册应用

来到微信开放平台后,进入管理中心:

  1. 首先选择 应用类目,创建自己应用对应的类目。

  2. 选择 创建移动应用,按照要求填写全部必填项

  3. 在开发信息中如实填写自己的应用相关信息,一个应用最多可以关联一个 Android 应用、一个 iPhone应用、一个iPad应用

    这里需要注意安卓应用需要填写 应用签名,微信官方的指示是安装一个签名生成工具然后获取。

    其实没有必要那么麻烦,直接从 AndroidStudio 的右侧边栏选择 Gradle - 你的项目 -Tasks - android - signingReport ,然后双击执行即可。

    只需要稍等片刻就可以在输出结果中看到如下的内容:

    找到我们使用的签名文件,其中的 MD5 指纹,就是我们需要的签名,主要注意移除其中的冒号 :,然后将该字符串转成小写。这一步可以在 AS 中新建一个文件,先替换,然后选中按 ctrl + shift + u 快捷键切换大小写即可。

完成这 3 步,工作日一般等待两三个小时就会出审核结果,审核通过后应用就有微信登陆权限了。

2. 集成SDK

我不得不吐槽,微信的文档真的很差劲。2022年了,资源中心页面挂的 maven 仓库地址还是 Jcenter,可以说是一点都没注意维护文档。

微信 sdk 现在其实已经迁移到了 MavenCentral,最新版本地址:https://search.maven.org/artifact/com.tencent.mm.opensdk/wechat-sdk-android-without-mta/6.7.9/aar

在项目中添加依赖:

1
implementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.7.9'

2.1 注册 App

在我们的 Application 文件中写下如下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
public IWXAPI wxapi;
private void registerWX() {
// 调用sdk函数,创建api对象,Constants.WX_APP_ID是微信开放平台中我们创建的应用的AppId
wxapi = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID, false);
// 将该app注册到微信
wxapi.registerApp(Constants.WX_APP_ID);
}
@Override
public void onCreate() {
super.onCreate();
// ...
registerWX();
}

2.2 创建回调页面:WXEntryActivity

微信SDK 在授权之后会访问一个固定的页面:{applicationId}/wxpai/WXEntryActivity,这里一定要注意,是在 applicationId 这个包名路径下创建 wxapi 目录,然后再创建 WXEntryActivity 这个页面!

一般的大家的项目根包名可能也就是你的 applicationId,但是有点项目可能不是,这是一个踩坑点需要注意!!!!

页面内容大致如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class WXEntryActivity : AppCompatActivity(), IWXAPIEventHandler {

lateinit var api: IWXAPI

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
//这里使用的是再Application中保存的api对象
api = MyApplication.getDsInstance().wxapi
// 必写
api.handleIntent(intent, this)
}

//必写
override fun onNewIntent(intent: Intent?) {
super.onNewIntent(intent)
setIntent(intent)
api.handleIntent(intent, this)
}

override fun onReq(req: BaseReq) {
LogUtils.d("openid = " + req.openId)
}

override fun onResp(resp: BaseResp) {
// 微信登录的响应是 1
if (resp.type == ConstantsAPI.COMMAND_SENDAUTH) {
when (resp.errCode) {
BaseResp.ErrCode.ERR_USER_CANCEL -> finishAuth("授权操作取消")
BaseResp.ErrCode.ERR_AUTH_DENIED -> finishAuth("微信授权失败")
BaseResp.ErrCode.ERR_OK -> {
val code = (resp as SendAuth.Resp).code
// 这里我通过EventBus将code传给原本的登录页面
EventBus.getDefault().post(WXLoginCodeEvent(code))
finish()
}
else -> {
finishAuth("未知错误")
}
}
} else {
finish()
}
}

private fun finishAuth(msg: String) {
ToastUtils.showShort(msg)
EventBus.getDefault().post(WXLoginCodeEvent(""))
finish()
}
}

data class WXLoginCodeEvent(val code: String)

因为微信sdk的设定,我们只能在这个特定的页面拿到微信的授权码,但是我们的其他业务还是在原来的登录页面,所以这里我使用了 EventBus 来进行跨页面通信,传递微信的授权码。

2.3 拉起微信,进行授权

在我们登录页面的微信登陆按钮的监听事件中这样写:

1
2
3
4
SendAuth.Req req = new SendAuth.Req();
req.scope = "snsapi_userinfo";
req.state = "none";
api.sendReq(req);

在登录页面中注册 EventBus 的事件响应函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
/**
* 处理微信登录成功获取code之后的一系列登录操作
*
* @param event 微信登录事件
*/
public void onEventMainThread(WXLoginCodeEvent event) {
if (event.getCode().length() > 0) {
LogUtils.d("微信登录返回的code:" + event.getCode());
//...
}else {
//没有传入code说明授权失败或取消
//...
}
}

至此我们的微信登录功能就集成完毕了,剩余的就是把获取到的授权码 code,传递给咱们自己应用的后台,由他们处理其他的逻辑即可。