LayaBox
接入微信登录的方式网上几乎没有,在官方文档和上古教程的双重折磨下摸索了一天,终于实现近乎完美的接入方式,并作以记录。
我们用Android Studo打开打包后的项目文件。
基础框架配置
首先需要升级gradle tool和Android Gradle的版本,在用Android Studio打开工程时会提示更新,确认即可。
手动更新是在项目的build.gradle
中更改依赖为新版,这里用的是4.1.2版本。
1 2 3
| dependencies { classpath 'com.android.tools.build:gradle:4.1.2' }
|
同时在gradle-wrapper.properties
中更新gradle,这里用的是6.5版本
1
| distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-bin.zip
|
打开模块的build.gradle
文件。位于Gradle Script 下。
在依赖项中添加微信的SDK。同时升级 appcompat
到比较新的版本(打包后默认的版本很低)。
1 2 3 4 5 6
| dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) testImplementation 'junit:junit:4.12' implementation 'com.android.support:appcompat-v7:28.0.0' api 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+' }
|
更改默认配置中最低sdk版本为16或以上 ,默认为15,最新的微信SDK并不支持。
1 2 3 4 5 6 7
| defaultConfig { applicationId "com.c1oudust.test" minSdkVersion 16 targetSdkVersion 28 versionCode 1 versionName "2.0" }
|
同步gradle
更改,完成配置。
SDK配置
在java
目录下新建以包名命名的package。
在此package中新建名为wxapi
的package。
在此package中新建名为WXEntryActivity
的class并继承AppCompatActivity
类和IWXAPIEventHandler
接口。
IWXAPIEventHandler
接口需要实现onReq
和onResp
两个方法。这里可以用自动补全一键生成。我们在onResp
方法中处理登录回调。这里可以参考微信SDK官方文档
重写onCreate
方法,注册微信appid。
在授权成功的回调中使用LayaBox提供的ConchJNI.RunJS
调用JavaScript方法。此方法必须注册到window
对象上,否则找不到,后文有详细方式。这里直接把获取到的登录code
传给了Laya端。
参考代码:
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
| package com.c1oudust.test.wxapi;
import android.os.Bundle; import android.os.PersistableBundle; import android.support.annotation.Nullable; import android.support.v7.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 layaair.game.browser.ConchJNI;
public class WXEntryActivity extends AppCompatActivity implements IWXAPIEventHandler { private IWXAPI iwxapi; private static final String APP_ID = "wx123456123456123"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); iwxapi = WXAPIFactory.createWXAPI(this, APP_ID, false); iwxapi.handleIntent(getIntent(), this); }
@Override public void onReq(BaseReq baseReq) {}
@Override public void onResp(BaseResp baseResp) { switch (baseResp.errCode) { case BaseResp.ErrCode.ERR_OK: String code = ((SendAuth.Resp) baseResp).code; ConchJNI.RunJS("wxLoginCallback('" +code+"')"); finish(); break; case BaseResp.ErrCode.ERR_AUTH_DENIED: finish(); break; case BaseResp.ErrCode.ERR_USER_CANCEL: finish(); break; default: finish(); break; } } }
|
打开AndroidManifest.xml
,我们需要在MainActivity
中添加以下代码,taskAffinity
为包名。
1 2 3
| android:exported="true" android:taskAffinity="com.c1oudust.test" android:launchMode="singleTask"
|
同时添加一个activity
,注意name
须为WXEntryActivity
的路径。
1 2 3
| <activity android:name="com.c1oudust.test.wxapi.WXEntryActivity" android:label="@string/app_name" android:exported="true"/>
|
为了使安卓11的手机能调起微信,需要在根节点下添加以下代码,这部分在SDK文档的接入流程中。
1 2 3
| <queries> <package android:name="com.tencent.mm" /> </queries>
|
安卓端的配置基本完成。现在创建一个单独的静态方法,实现登录,供Laya端调用。
这里我们在java
目录新建wx
包,并新建wxLogin
类。
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| package wx;
import com.tencent.mm.opensdk.modelmsg.SendAuth; import com.tencent.mm.opensdk.openapi.IWXAPI;
public class wxLogin { public static IWXAPI api; public static void login() { if (!api.isWXAppInstalled()) { return; } final SendAuth.Req req =new SendAuth.Req(); req.scope = "snsapi_userinfo"; req.state = "wechat_sdk_demo_test"; api.sendReq(req); } }
|
其中的IWXAPI
必须是之前注册过的,因此我们在MainActivity
处理这部分。
打开demo包中的MainActivity
文件,可以理解为APP的主入口。
在onCreate
方法中注册appid
并将IWXAPI
赋值给wxLogin
中的IWXAPI
。
参考代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| private static final String APP_ID = "wx123456123456123"; private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); getWindow().requestFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); JSBridge.mMainActivity = this; mSplashDialog = new SplashDialog(this); mSplashDialog.showSplash();
regToWx(); initEngine(); } private void regToWx() { api = WXAPIFactory.createWXAPI(this, APP_ID, false); api.registerApp(APP_ID); wxLogin.api = api; }
|
Laya端处理
在想要调起微信登录的方法中添加
1 2 3 4
| if (window['PlatformClass']) { var wxLogin = window['PlatformClass'].createClass('wx.wxLogin'); wxLogin.call('login'); }
|
这里的createClass
参数即为之前创建的调起登录的java类。然后我们使用call
来调起wxLogin
类中的login
方法。
登录回调。在APP主页面的构造器中为window
对象添加一个方法,方法名需要和onResp
回调中ConchJNI.RunJS
执行的方法名一样。
1 2 3
| Laya.Browser.window['wxLoginCallback'] = (code) => { console.log('返回的code: ' + code); };
|
这里会拿到登录回调传过来的code
。
登录处理
以上操作初步完成了调起微信登录的流程。那么怎么获取到用户的个人信息呢?
这里在微信SDK文档中已经说的很清楚了,大概方式是通过登录返回的code
获取access_token
,再通过access_token
来获取用户个人信息。
access_token
涉及到有效期,有效期过了就需要重新获取。
由于获取access_token
涉及到注册微信开放平台的app secret,因此建议把这部分放在后端。
在这里由于是demo,因此本人给出一个大概的流程,请求我们用Okhttp框架。
我们在登录成功的回调中不要把code传给前端,而是调用getAccessToken
方法。
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
| private void getAccessToken(String code) { StringBuffer loginUrl = new StringBuffer(); loginUrl.append("https://api.weixin.qq.com/sns/oauth2/access_token") .append("?appid=") .append(APP_ID) .append("&secret=") .append(SECRET) .append("&code=") .append(code) .append("&grant_type=authorization_code");
OkHttpClient okHttpClient = new OkHttpClient(); final Request request = new Request.Builder() .url(loginUrl.toString()) .get() .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) {}
@Override public void onResponse(Call call, Response response) throws IOException { String responseInfo= response.body().string(); String access = null; String openId = null; try { JSONObject jsonObject = new JSONObject(responseInfo); access = jsonObject.getString("access_token"); openid = jsonObject.getString("openid"); } catch (JSONException e) { e.printStackTrace(); } getUserInfo(token, openid); } }); }
|
我们把access_token
和openid
传给getUserInfo
方法来获取个人信息。这里没有对access_token
失效的处理,各位可以自行发挥。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private void getUserInfo(String token, String openid) { String getUserInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=" + token + "&openid=" + openid;
OkHttpClient okHttpClient = new OkHttpClient(); final Request request = new Request.Builder() .url(getUserInfoUrl) .get() .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException e) {}
@Override public void onResponse(Call call, Response response) throws IOException { String responseInfo= response.body().string(); finish(); } }); }
|
参考文档
微信开放文档
Laya官方文档 - 二次开发
Laya打包AndroidStudio工程二次开发之相互调用