Unity微信Android端第三方登陆

Posted 鹏易灵

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity微信Android端第三方登陆相关的知识,希望对你有一定的参考价值。

开发环境:
Unity2020.3.241f1c1
Andoird Studio

开发准备:
微信开发者账号:注册App应用,从这儿获取包名AppIDApp Secret

一、向微信开放平台注册App应用

1.点击创建应用

2.填写基本信息和平台信息,提交审核

注意:
1.填写的包名在android Studio中可能要用到
2.签名的获取
在plaer setting中点击KeystoreManager填写好保存,生成xxx.keystore文件,再点击Custom Keystore填写好下面信息就可以了。

打包该app放在手机上

在你的Andorid机上下载安装该Apk工具,然后输入包名获取签名。

3.审核通过后得到AppID然后生成AppSecret

二、在Android Studio中导出AAR包共Unity使用

1.打开Android Studio新建一个工程

选择Empty Activity,点击Next创建

2.创建新的模块

选择Android Library 点击Next创建


我这里的Module名为LoginShare

3.在工程中导入Unity安卓开发工具中的Classes.jar文件
一般来说在unity中的如下路径:xxx\\Unity 2020.3.24f1c2\\Editor\\Data\\PlaybackEngines\\AndroidPlayer\\Variations\\mono\\Release\\Classes

将该文件放在我们创建好的模块lib文件夹下

4.在工程中导入Unity安卓开发工具中的wechat-sdk-android-without-mta-x.x.x.jar文件
在微信开放平台中的操作过于繁琐,这里介绍一种简单的接入方式。
如下图所示,微信 SDK 已迁移到 Maven Central

所以,我们可以直接去它的官网上下载 Naven Central 地址
步骤一

步骤二

步骤三

然后用压缩文件工具打开arr文件,如下图所示

再把classes.jar文件拖到桌面并把名称命名为和arr文件的名称一样,最后把它放到Andorid Studio工程模块中的lib文件夹下图所示

5.按图下层级放入如下代码,及 AndroidUnityConnecter.java、WXEntryActivity.java、MainActivity.java、AndroidManifest.xml文件的编写

包名文件夹下创建AndroidUnityConnecter.java文件

package com.lyarcloud;

import com.unity3d.player.UnityPlayer;
public  class AndroidUnityConnecter 

    private static final String connecterName = "UnityAndroidConnecter"; //通信物体
    private static final String defaultMethodName = "ReceiveAndroidMsg"; //方法

    public static final String UnityTag="Unity";

    //发送消息到Unity
    public static void SendMsgToUnity(String args)
    
        UnityPlayer.UnitySendMessage(connecterName, defaultMethodName,args);
    

    //发送消息到Unity
    public static void SendMsgToUnity(String methodName,String args)
    
        UnityPlayer.UnitySendMessage(connecterName,methodName,args);
    

    /*接收到Unity发来的消息*/
    public static void ReceiveUnityMsg(String key,String args)
    
        //根据接受到的消息处理
        switch (key)
        
            case "getstring":
                MainActivity.Ins.GetString(args);
                break;
            case "toast":
                MainActivity.Ins.SayToast(args);
                break;
        
    
    public static  void  UnityPig(String msg)
    
        MainActivity.Ins.SayToast(msg);
        SendMsgToUnity("猪猪猪");
    

    public static  void  Login(String args)
        MainActivity.Ins.SayToast(args);
        MainActivity.Ins.Login();
    

包名.wxapi文件夹下创建WXEntryActivity.java文件

package com.lyarcloud.wxapi;

import androidx.appcompat.app.AppCompatActivity;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Toast;

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 
    private IWXAPI wxapi= null;
    private final  String APPID = "wxbf539d11da238208";
    @Override
    protected void onCreate(Bundle savedInstanceState) 
        super.onCreate(savedInstanceState);
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信API_ING");
        if(wxapi == null)
            wxapi = WXAPIFactory.createWXAPI(this,APPID);
            wxapi.registerApp(APPID);
            UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信API初始化成功");
        
        wxapi.handleIntent(getIntent(),this);
    

    @Override
    public void onReq(BaseReq baseReq) 

    

    @Override
    public void onResp(BaseResp baseResp) 
        switch (baseResp.getType())
            case 1://登陆
                if(baseResp.errCode == BaseResp.ErrCode.ERR_OK)
                    Toast.makeText(this,"登陆成功",Toast.LENGTH_SHORT).show();
                    UnityPlayer.UnitySendMessage("UnityAndroidConnecter","LoginCallback", ((SendAuth.Resp)baseResp).code);
                else if(baseResp.errCode == BaseResp.ErrCode.ERR_USER_CANCEL)//取消
                    Toast.makeText(this,"用户取消",Toast.LENGTH_SHORT).show();
                    UnityPlayer.UnitySendMessage("UnityAndroidConnecter","LoginCallback", "用户取消");
                else if(baseResp.errCode == BaseResp.ErrCode.ERR_AUTH_DENIED)//拒绝
                    Toast.makeText(this,"用户拒绝",Toast.LENGTH_SHORT).show();
                    UnityPlayer.UnitySendMessage("UnityAndroidConnecter","LoginCallback", "用户拒绝");
                else 
                    UnityPlayer.UnitySendMessage("UnityAndroidConnecter","LoginCallback", "其他错误");
                

                break;
            case 2://分享
                Toast.makeText(this,"分享",Toast.LENGTH_SHORT).show();
                UnityPlayer.UnitySendMessage("UnityAndroidConnecter","LoginCallback", baseResp.errStr);
                break;
        
    

在 MainActivity.java文件中 MainActivity 需要继承 UnityPlayerActivity,其与微信接口的具体实现如下:

package com.lyarcloud;

import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;

import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXVideoObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import com.unity3d.player.UnityPlayer;
import com.unity3d.player.UnityPlayerActivity;

public class MainActivity extends UnityPlayerActivity 

    public static MainActivity Ins=null;  //单例模式

    private IWXAPI wxapi= null;
    private final  String APPID = "wxbf539d11da238208";

    @Override
    protected void onCreate(Bundle savedInstanceState)
    
        super.onCreate(savedInstanceState);
        Ins=this;
        Log.i(AndroidUnityConnecter.UnityTag,"启动");
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信M_API_ING");
        if(wxapi == null)
            wxapi = WXAPIFactory.createWXAPI(this,APPID);
            wxapi.registerApp(APPID);
        
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信M_API初始化成功");
    

    public void GetString(String args)
    
        String a= "Unity:"+args;
        Log.i(AndroidUnityConnecter.UnityTag,a);
        AndroidUnityConnecter.SendMsgToUnity(a);
    
    public void SayToast(final String msg)
    
        runOnUiThread(new Runnable() 
            @Override
            public void run() 
                Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_LONG).show();
            
        );
    

    @Override
    protected void onStart()
    
        super.onStart();
        Log.i(AndroidUnityConnecter.UnityTag,"开始Start");
    

    public  void  Login()
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信登陆请求开始建立");
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "lyarcloud";
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信登陆请求开始发送");
        wxapi.sendReq(req);
        UnityPlayer.UnitySendMessage("UnityAndroidConnecter","TextMsg","微信登陆请求完成");
    

    public void  ShareText(String text,String description,int scene)
    
        //初始化一个 WXTextObject 对象,填写分享的文本内容
        WXTextObject textObj = new WXTextObject();
        textObj.text = text;

//用 WXTextObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = textObj;
        msg.description = text;

        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction(description);
        req.message = msg;
        req.scene = scene;
//调用api接口,发送数据到微信
        wxapi.sendReq(req);
    

    public void ShareImage(byte[] imageData,byte[] thumbImageData,int scene)
    

//初始化 WXImageObject 和 WXMediaMessage 对象
        WXImageObject imgObj = new WXImageObject(imageData);
        WXMediaMessage msg = new WXMediaMessage();
        msg.mediaObject = imgObj;

//设置缩略图
        msg.thumbData = thumbImageData;

//构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("img");
        req.message = msg;
        req.scene = scene;
        //req.userOpenId = getOpenId();
//调用api接口,发送数据到微信
        wxapi.sendReq(req);
    

    public  void ShareVideo(String url,byte[] imageData,byte[] videoData,int scene)
    
        //初始化一个WXVideoObject,填写url
        WXVideoObject video = new WXVideoObject();
        video.videoUrl = url;

//用 WXVideoObject 对象初始化一个 WXMediaMessage 对象
        WXMediaMessage msg = new WXMediaMessage(video);
        msg.title ="览易AR";
        msg.description ="视频描述";
        msg.thumbData = imageData;

//构造一个Req
        SendMessageToWX.Req req = new SendMessageToWX.Req();
        req.transaction = buildTransaction("video");
        req.message = msg;
        req.scene = scene;
        //req.userOpenId = getOpenId();

//调用api接口,发送数据到微信
        wxapi.sendReq(req);
    

    private String buildTransaction(final String type)
        return (type == null) ? String.valueOf(System.currentTimeMillis()):type + System.currentTimeMillis();
    

然后,你会发现找不到 UnityPlayerActivity,原因是在Unity2019以后的版本unity中的Classse.jar包中不再包含UnityPlayerActivity这个类,而是把这个java类提到了其他文件夹下了,一般存在如下路径:xxx\\Unity 2020.3.24f1c2\\Editor\\Data\\PlaybackEngines\\AndroidPlayer\\Source\\com\\unity3d\\player
如下图所示

拷贝com文件加下的unity3d到Andorid Studio工程模块包名文件夹下,如下图所示

最后再配置一下AndroidManifest.xml文件,此内容需要参考一下unity中的AndroidManifest.xml的配置
具体操作如下:
在Unity中右上角点击Flie,再点击BuildSetting,然后再点击player setting

然后就会在Asset/Plugins/Andorid文件夹下多了AndroidManifest.xml文件,如下图所示

点击AndroidManifest.xml文件打开,温馨提示:在Android Studio中编写AndroidManifest.xml请注意参照

参考微信开放平台中Andorid接入指南,温馨提示:在Android Studio中编写AndroidManifest.xml请注意参照
targetSdkVersion升级到30的第三方应用,由于Android 11 软件包可见性 特性的影响,OpenSDK的接口可能无法正常拉起微信,从而无法使用微信的部分功能,需要在主工程的AndroidManifest.xml 中增加标签。

结合以上几个点进行参考配置,得到该版本环境下的最终==AndroidManifest.xml ==,如下

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.lyarcloud">

    <uses-permission android:name="android.permission.INTERNET"/>
    <application
        android:label="@string/app_name"
        android:icon="@mipmap/app_icon"
        >
        <activity android:name=".MainActivity"
            android:theme="@style/UnityThemeSelector">
            <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>
        http://www.cnblogs.com/unityExplorer/p/8404604.html

相比微信的登录和分享功能,微信支付sdk的接入显得相当简单,因为大部分的事情需要由服务端或者后台来做

基本流程如下:

  1、客户端向服务端发起购买商品请求

  2、服务端计算实际支付金额,向微信请求订单

  3、微信返回预支付订单信息,服务端将该信息传给客户端

  4、客户端解析预支付订单信息json,向微信发起支付请求

  5、支付成功后,微信向服务端预设的url和客户端返回支付结果

  6、服务端刷新用户商品数据,并向客户端推送支付结果

核心函数只有一个

    public static void SendPay(String appId, String partnerId, String prepayId, String nonceStr, String timeStamp, String packageValue, String sign) {
        PayReq req = new PayReq();
        req.appId = appId;
        req.partnerId = partnerId;
        req.prepayId = prepayId;
        req.nonceStr = nonceStr;
        req.timeStamp = timeStamp;
        req.packageValue = packageValue;
        req.sign = sign;
        api.sendReq(req);
    }

回调的处理和分享类似,java类文件名为WXPayEntryActivity,该类继承Activity并实现IWXAPIEventHandler,同样需要放在wxapi文件夹中

public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler   {
    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        if(api == null) {
            api = WXAPIFactory.createWXAPI(this, "APP_ID");
            api.registerApp("APP_ID");
            api.handleIntent(getIntent(), this);
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    @Override
    public void onResp(BaseResp resp) {
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            UnityPlayer.UnitySendMessage("ThirdPartySdkManager","WechatPayCallback", String.valueOf(resp.errCode));
            finish();
        }
    }
}

支付返回的errCode为int型:

  -2对应取消支付

  -1对应支付失败

  0为支付成功

不过这个值仅仅只是用户支付的结果,但不意味着支付到账,所以实际数据的更新,要取决于服务器

 

以上是关于Unity微信Android端第三方登陆的主要内容,如果未能解决你的问题,请参考以下文章

uni-app关于小程序及app端第三方微信登陆问题

unity探索者之微信支付,非第三方插件

Android App实现微信第三方授权登陆

Android调用微信登陆分享支付(第二版本)

Android调用微信登陆分享支付(第二版本)

android 微信开放平台登录问题,授权页无法调出