实现Unity接入安卓端的微信登录

分为五个大步骤

  1. 生成keystore安卓利用开发者签名
  2. 在微信开放平台申请挪动利用接入
  3. 编写Java Android局部代码, 生成arr文件
  4. 编写 Unity C# 代码
  5. Unity打apk包, 装置到手机中进行测试

倡议依照程序逐渐进行, 1, 2 步如果曾经实现, 可间接跳过. 尽管步骤有些多, 但这些步骤只有做一次就好, 往后点击两个按钮就能够实现代码更新.

生成keystore安卓利用开发者签名

  1. 关上 IDEA , 新建我的项目
  2. 抉择上方工具栏, Generate Signed Bundle/ APK生成密钥
  3. 点击 Create new
  4. 别离填入

    • Password
    • Confirm (再填一次明码)
    • Alias
    • Alias Password
    • Alias Confirm
    • Certificate 中填一个就好

    keystore签名蕴含一个密钥与多个子签名. 密钥用于开启 keystore 文件, 而一个子签名Key Alias 可用于对一个 Android 利用加密.
  5. 这时可在 key store path 中看见文件
  6. 须要将该文件转为 .keystore 文件
    我的testKey文件门路为 /Users/chenyuanzhen/Desktop/testKey
    执行以下命令

    keytool -importkeystore -srckeystore /Users/chenyuanzhen/Desktop/testKey -srcstoretype JKS -deststoretype PKCS12 -destkeystore /Users/chenyuanzhen/Desktop/testKey.p12keytool -v -importkeystore -srckeystore /Users/chenyuanzhen/Desktop/testKey.p12 -srcstoretype PKCS12 -destkeystore /Users/chenyuanzhen/Desktop/testKey.keystore -deststoretype JKS

    实现后会失去 keystore 文件

    只须要保留 .keystore 文件就好.
    到此第一步完结

在微信开放平台申请挪动利用接入

  1. 申请接入挪动利用后会到这个界面

    须要留神的是, 接入的挪动利用必须要有官网介绍这个利用或者曾经上线....
  2. 到这个界面后, 须要填写利用签名与利用包名

    • 利用签名须要填写 MD5 值, 而且只能有数字和字母, 其余须要去掉.
      这个利用签名是从 keystore 文件中获取的. 获取办法须要执行以下指令.

      keytool -exportcert -rfc -keystore  /Users/chenyuanzhen/Desktop/testKey.keystore  -alias myKey | openssl x509 -inform pem -outform der -out testKey.deropenssl md5 /Users/chenyuanzhen/Desktop/testKey.der 

      会失去如下输入


    其中的 85fd... 为利用签名

    • 利用包名倡议与刚在 IDEA 新建我的项目的包名统一

    申请通过后, 到此第二步曾经实现.

编写Java Android局部代码, 生成arr文件

  1. 从 Unity 中搬移文件到 Android 我的项目中.

    点击任一一个 Copy Path 按钮, 目标是找到 Unity 的安卓环境门路.

    这个须要在 Unity Hub 中装置
    • 将目录中的classes.jar文件复制到安卓我的项目下的 lib 目录下
    /Applications/Unity/Hub/Editor/2021.3.23f1/PlaybackEngines/AndroidPlayer/Variations/il2cpp/Release/Classes
    • 将位于下方目录的文件复制到安卓我的项目包内, 并将 package com.unity3d.player; 包名批改为你本人的包名
    /Applications/Unity/Hub/Editor/2021.3.23f1/PlaybackEngines/AndroidPlayer/Source/com/unity3d/player/UnityPlayerActivity.java 
  2. 编写模块内的 build.gradle 文件.

    留神不是我的项目根目录的 build.gradle 文件
    plugins { id 'com.android.library'}android { compileSdkVersion 33 buildToolsVersion "33.0.1" defaultConfig {     minSdk 24     targetSdkVersion 33     testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"     consumerProguardFiles "consumer-rules.pro" } buildTypes {     release {         minifyEnabled false         proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'     } } compileOptions {     sourceCompatibility JavaVersion.VERSION_1_8     targetCompatibility JavaVersion.VERSION_1_8 }}dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'com.google.android.material:material:1.9.0' compileOnly files('tempLibs/classes.jar') api 'com.tencent.mm.opensdk:wechat-sdk-android:+' testImplementation 'junit:junit:' androidTestImplementation 'androidx.test.ext:junit:1.1.5' androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'}task copyPlugin(type: Copy) { dependsOn assemble from('build/outputs/aar') into('/Users/chenyuanzhen/UnityProject/projectname/Assets/Plugins/Android') include(project.name + '-release.aar')}
    其中 copyPlugin 中的 into 里的文件目录为 Unity 我的项目目录
  3. 同步 gradle 文件
    应用 IDEA 的话点击

    按钮
  4. 新建两个包 (假如你的包名为 com.company.project, 在微信平台上注销的也是该包名)

    • com.company.project.wechatplugin

      wechatplugin 能够随便取
    • com.company.project.wxapi

      这个包名必须是 微信平台注销的包名 + wxapi
      否则会呈现微信没有回调信息的问题
  5. 将 UnityPlayerActivity.java 文件搁置到 com.company.project.wechatplugin 下
  6. 在 com.company.project.wechatplugin 中创立 MainActivity 文件.

    package com.company.project.wechatplugin;import android.os.Bundle;import android.util.Log;import com.tencent.mm.opensdk.modelmsg.SendAuth;import com.tencent.mm.opensdk.openapi.IWXAPI;import com.tencent.mm.opensdk.openapi.WXAPIFactory;import com.lingdong.drone.wechat.playerActivity.UnityPlayerActivity;public class MainActivity extends UnityPlayerActivity { public IWXAPI wxapi = null; // 这个 APPID 由 Unity 传入 public static String APPID; @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState); } private void regWx(String appid){     APPID = appid;     if (wxapi==null){         wxapi = WXAPIFactory.createWXAPI(this,APPID);         // 将该app注册到微信         wxapi.registerApp(APPID);         Log.e("myTencent", "监听注册到微信");     }     Log.e("myTencent", "onCreate finished ! "); } public void Login(){     Log.e("myTencent", "Login!! ");     SendAuth.Req req = new SendAuth.Req();     req.scope = "snsapi_userinfo";     req.state = "wechat_sdk_demo_test";     wxapi.sendReq(req);     Log.e("myTencent", "SendReq Finish"); }}
  7. 在 com.company.project.wxapi 下创立 WXEntryActivity.java 文件.

    必须是这个名字
    package com.company.project.wxapi;//com.lingdong.droneimport android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.widget.Toast;import com.lingdong.drone.wechat.MainActivity;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 com.unity3d.player.UnityPlayer;public class WXEntryActivity extends Activity implements IWXAPIEventHandler { public IWXAPI wxapi = null; public static String gameObjectName = ""; // WXLoginCallBack public static String callBackFunctionName = ""; public static void setGameObjectName(String gameObjectName) {     WXEntryActivity.gameObjectName = gameObjectName; } public static void setCallBackFunctionName(String callBackFunctionName) {     WXEntryActivity.callBackFunctionName = callBackFunctionName; } @Override protected void onCreate(Bundle savedInstanceState) {     super.onCreate(savedInstanceState);     // WXLoginObject     Log.e("myTencent", "WxEntryActivity onCreate");     //初始化wxapi     if (wxapi == null) {         wxapi = WXAPIFactory.createWXAPI(this, MainActivity.APPID);     }     wxapi.registerApp(MainActivity.APPID);     wxapi.handleIntent(getIntent(), this); } @Override public void onReq(BaseReq baseReq) { } @Override public void onResp(BaseResp baseResp) {     Log.e("myTencent", "收到 resp ");     if (baseResp.getType() == 1) {//微信登录         if (baseResp.errCode == BaseResp.ErrCode.ERR_OK) {//用户批准             UnityPlayer.UnitySendMessage(gameObjectName, callBackFunctionName, ((SendAuth.Resp) baseResp).code);         } else if (baseResp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL) {//用户勾销             UnityPlayer.UnitySendMessage(gameObjectName, callBackFunctionName, "用户勾销");         } else if (baseResp.errCode == BaseResp.ErrCode.ERR_AUTH_DENIED) {//用户回绝             UnityPlayer.UnitySendMessage(gameObjectName, callBackFunctionName, "用户回绝");         } else {             UnityPlayer.UnitySendMessage(gameObjectName, callBackFunctionName, "其余谬误");         }     } else if (baseResp.getType() == 2) {     }     finish(); }}
  8. 批改我的项目内的 AndroidManifest.xml 文件

    <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"       package="com.company.project.wechatplugin"> <queries>     <package android:name="com.tencent.mm"/> </queries> <application         android:allowBackup="true"         android:supportsRtl="true">     <activity android:name="com.company.project.wechatplugin.MainActivity" android:exported="true">         <intent-filter>             <action android:name="android.intent.action.MAIN"/>             <category android:name="android.intent.category.LAUNCHER"/>         </intent-filter>         <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>     </activity>     <activity             android:name="com.company.project.wxapi.WXEntryActivity"             android:launchMode="singleTask"             android:exported="true">     </activity> </application></manifest>

    到此第三步实现.

编写 Unity C# 代码

  1. 在 Unity 我的项目中创立文件夹

    • /Assets/Plugins/Android

      该文件夹门路必须是这样, Unity官网规定
    • 关上安卓我的项目, 找到模块内build.gradle, 执行 copyPlugin 工作.

      这时 /Assets/Plugins/Android 目录会呈现一个 arr 文件
      倡议当前每次运行 copyPlugin 前, 先将旧的 arr 文件删除. 否则 Unity 可能会因缓存应用旧的 arr 文件.
  2. 将微信 sdk 的 jar 包移到 /Assets/Plugins/Android 目录中. 该 jar 包可在 idea 里的 External Libraries 中找到.
  3. 配置 Unity 设置

    • 覆写 Unity 打包的包名

      该包名必须与开放平台上注销的统一, 另外必须跟 Android 我的项目里的包名有所不同. 否则会呈现抵触
    • 配置 Unity 打包密钥并勾选 Custom Main Manifest
  4. 将安卓我的项目里的 AndroidManifest.xml 复制到 /Assets/Plugins/Android 目录中
  5. 对其进行批改

    <?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"       package="com.company.project"> <queries>     <package android:name="com.tencent.mm"/> </queries> <application         android:allowBackup="true"         android:supportsRtl="true">     <activity android:name="com.company.project.wechatplugin.MainActivity" android:exported="true">         <intent-filter>             <action android:name="android.intent.action.MAIN"/>             <category android:name="android.intent.category.LAUNCHER"/>         </intent-filter>         <meta-data android:name="unityplayer.UnityActivity" android:value="true"/>     </activity>     <activity             android:name="com.company.project.wxapi.WXEntryActivity"             android:launchMode="singleTask"             android:exported="true">     </activity> </application></manifest>
  6. 编写 C# 脚本

    using UnityEngine;using UnityEngine.UI;public class WXLogin : MonoBehaviour{ // public Button button_login, button_quit; // public Image image_head; public Text text_username, text_code; // public GameObject go_lobby; private AndroidJavaClass mainActivityClass = null; private AndroidJavaObject mainActivity = null; private AndroidJavaClass WXEntryActivityClass = null; private string APPID = "你的 APPID"; private string SECRET = "你的 APP 密钥"; // Start is called before the first frame update void Start() {     // 配置 APPID     mainActivityClass = new AndroidJavaClass("com.unity3d.player.UnityPlayer");     mainActivity = mainActivityClass.GetStatic<AndroidJavaObject>("currentActivity");     mainActivity.Call("regWx", APPID);     // 配置 WXEntryActivity     WXEntryActivityClass = new AndroidJavaClass("com.company.project.wxapi.WXEntryActivity");     WXEntryActivityClass.CallStatic("setGameObjectName", this.gameObject.name);     WXEntryActivityClass.CallStatic("setCallBackFunctionName", "WXLoginCallBack"); } public void Onbutton_login() {     mainActivity.Call("Login"); }  public void WXLoginCallBack(string str) {     if (str != "用户勾销" && str != "用户回绝" && str != "其余谬误")     {         Debug.Log("微信登录胜利,code是:" + str);         text_code.text += "微信登录胜利,code是:" + str + "\r\n";     }     else     {         Debug.Log("微信登录失败,code是:" + str);         text_code.text += "微信登录胜利,code是:" + str + "\r\n";     } }}
  7. 将WXLogin挂在一个 gameObject 下, 并将一个按钮 Onclick 事件触发 Onbutton_login 函数

到此第四步实现.

Unity打apk包, 装置到手机中进行测试

  1. 找到一台装置有微信, 且微信曾经登录的手机并与电脑连贯

    若用户没有登录微信, 那有可能会不弹窗
  2. 在 Unity 界面中按 command + B 构建 (或者点击按钮)

构建实现后会主动装置到手机中. 可从手机的日志查看是否登录胜利.

执行流程

整个程序执行流程

  1. 用户在 Unity 中点击微信登录按钮
  2. Unity 中的 C# 代码, 应用 AndroidJavaClass 与 AndroidJavaObject 类调用 Android 代码
  3. Android 代码中调用微信 sdk, 并将利用向微信注册
  4. 跳转到微信程序
  5. 用户点击登录确认
  6. 微信程序跳转回 Android 代码, WXEntryActivity
  7. Android 代码应用 UnityPlayer.UnitySendMessage 函数, 调用 Unity C#代码的函数, 并返回微信 code

    UnityPlayer.UnitySendMessage(挂载的 gameObject 名字, 须要调用的函数名, 函数参数)

留神点

  • 若呈现问题, 先核查本人的 APPID 与 密钥 是否配置正确. 如果这两个货色不正确, 会报一些意想不到的谬误. 例如

    Uninitialized ActivityThread, likely app-created Instrumentation, disabling AppComponentFactory

    很多问题都会报这个错, 例如 AndroidManifest.xml 配置谬误也会报这个错.

  • 若呈现这个问题

    那大概率是 arr 包里的文件与 Unity 里的配置抵触.
  • Unity 的 AndroidManifest.xml 配置与 arr 包里的AndroidManifest.xml 配置抵触
  • arr 包名与 Unity 覆写的包名雷同

具体可看构建时的报错 console

参考

  • Unity2018接入微信登录
  • (转)Unity Android 微信登录SDK接入
  • 如何在Unity中应用官网SDK实现微信、QQ、微博帐号登录(Android)
  • Extend the default Unity activity
  • Android接入指南