Unity Android平台接入支付宝SDK

这篇文章前面讲的创建Android Studio工程的流程是不正确的!!!

正确的流程请参见: Unity Android平台下插件/SDK开发通用流程

最近帮一个群里的朋友接了一下支付宝的SDK,开发环境是Unity 5.4.x + 最新的Android Studio2.3版本,最终Android Studio输出的文件格式是aar而不是之前的jar,鉴于网上的文章大多数是基于Eclipse + jar包,所以记录一下基于Android Studio进行开发的过程,供大家参考。

下载与整理支付宝SDK

首先下载最新的支付宝SDK,解压缩后找到alipay_demo和alipay_sdk文件夹,它们分别是Eclipse demo工程和是支付宝的jar包。接下来的步骤的会用到这两个文件夹里的内容。

创建并配置Android Studio工程

创建一个新的Android工程,Package Name要和Unity -> PlayerSettings里的Bundle Identifier保持一致,Minimum API Level最好也保持一致,防止出现意外的问题(没测过)。
设置Application Name和Company Name。当然Package Name在创建工程后也能修改,不过很麻烦就是了(代码里的可以批量修改,但是AndroidManifest里的需要手动修改)。
Unity Android平台接入支付宝SDK_第1张图片
设置Minimum API Level,API Level越低所能支持的设备越多,但为了向下兼容低版本的SDK,高版本的一些特有功能将无法使用。这里我选择了API Level 9,即Android 2.3.1,这样发布出来的插件可以跑在100%的安卓手机上了。
Unity Android平台接入支付宝SDK_第2张图片
Unity中Identification设置示例如下(Unity里的必须是小写!因为Android Studio导出的PackageName是小写):
Unity Android平台接入支付宝SDK_第3张图片
接着选择Activity的模版,我们选择Empty Activity。因为不需要编写Android原生界面。
Unity Android平台接入支付宝SDK_第4张图片
然后是设置Activity的名字界面,因为我们不需要编程Android界面,所以取消勾选Generate Layout File选项。不取消也可以,可以创建工程后手动删除Layout文件夹。
Unity Android平台接入支付宝SDK_第5张图片

至此,完成创建,工程结构应该如图所示:
Unity Android平台接入支付宝SDK_第6张图片
这里面有许多不需要的东西,比如测试工程,图标资源文件和安卓原生主题的配置文件。我们将其全部删除,删除完毕后工程清单如下所示:
Unity Android平台接入支付宝SDK_第7张图片
可以看到,我们只保留了两个文件—— AndroidManifest.xml和MainActivity。打开自动生成的AndroidManifest.xml,可以发现有许多关于应用的配置:



    
        
            
                

                
            
        
    

这里的android:icon,android:label,android:roundIcon和android:theme是不需要的,删除它们。同时必须在标签里插入一行属性,应该是Unity打包时Merge AndroidManifest时需要的,修改后如下所示:



    
        
            
                
                
            
            
        
    

最后,因为我们输出的是一个库而不是一个apk,所以需要修改输出的结果,打开Gradle Scripts(Gradle是一种安卓构建脚本)下的build.gradle(Moudle:app),将第一行的:
apply plugin: 'com.android.application'
修改为:
apply plugin: 'com.android.library'
点击上方的sync now,会出现错误提示:
Error:Library projects cannot set applicationId. applicationId is set to 'com.soulgame.magicgame' in default config.
这是因为库文件不能设置applcation Id,另外build.gradle会包含单元测试的配置,也需要删除,如下图所示:
Unity Android平台接入支付宝SDK_第8张图片
重新点击sync now,提示错误已经消失了。 注意这个过程可能会发生其他的问题,如提示build-tools或platform版本过低的提示等等,这时候按照提示给出的方案更新SDK即可。
至此,基本环境配置完毕,接下来就是接入支付宝SDK了。

接入支付宝SDK

首先我们需要引入支付宝SDK的jar包,将alipay_sdk下的alipaySdk-20XXXXXX.jar和Unity提供的jar包拷贝到项目路径/app/libs文件夹下,Unity提供的jar包路径是:
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\mono\Release\Classes\classes.jar
如果你的项目采用il2cpp编译,那么路径则是:
Editor\Data\PlaybackEngines\AndroidPlayer\Variations\il2cpp\Release\Classes\classes.jar
Unity Android平台接入支付宝SDK_第9张图片
然后回到AndroidStudio,菜单栏选择File -> Project Structure界面,点击app -> Dependencies如下图所示:
Unity Android平台接入支付宝SDK_第10张图片
点击旁边的减号,删掉目前这三个以来库,然后点击加号 -> Jar Dependency,选择刚才拷贝到Libs下面的那两个jar文件,点击确定。可以发现build.gradle(Moudle:app)下depedencies里出现了支付宝的Sdk jar包,完整的build.gradle如下:
apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.2"
    defaultConfig {
        minSdkVersion 9
        targetSdkVersion 25
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile files('libs/alipaySdk-20170309.jar')
    compile files('libs/classes.jar')
}

到这里后,我们先来测试一下配置是否正确,再进行下面的步骤。
点击Android Studio左下角的Build Variants,如图:
Unity Android平台接入支付宝SDK_第11张图片

将debug修改为release:

最后点击菜单栏Build -> Build APK,稍等,如果出现Build Successfully的提示,说明一切正常:

那么,生成的什么呢?点击Show in Explorer,选择outputs -> aar,会发现一个app-release.aar。这就是build生成的文件,aar可以视为jar的升级版,相关区别大家可以自行搜索。其实它们都只是一个zip文件。
注意:
生成的aar文件里,我们需要删除libs/class.jar!将aar文件后缀改为zip,使用压缩软件删除即可。因为Unity在打包时,会将自带的那个classes.jar拷贝进apk,如果aar里的classes.jar不删除,打包时就会产出冲突,得到下面的错误:
IOException: Failed to Move File / Directory from 'Temp/StagingArea\android-libraries\app-release\classes.jar' to 'Temp/StagingArea\android-libraries\app-release\libs\classes.jar'.
也就是说,每次我们测试后,都需要将aar里的这个jar包手动删除。

接下来就是正式开始参考支付宝提供的Demo和 官方文档写支付方法了,包括添加混肴规则,修改AndroidManifest.xml增加Activity以及相关的权限设置等等。
其中添加混肴规则需要在Gradle Scripts/proguard-rules.pro里添加对应的规则:
-libraryjars libs/alipaySDK-20XXXXXX.jar //这里改成你所使用的SDK jar版本
 
-keep class com.alipay.android.app.IAlixPay{*;}
-keep class com.alipay.android.app.IAlixPay$Stub{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback{*;}
-keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}
-keep class com.alipay.sdk.app.PayTask{ public *;}
-keep class com.alipay.sdk.app.AuthTask{ public *;}

研究支付宝给出的Demo可以发现,支付宝支付函数只需要一个加密后的订单信息字符串:
public void Pay(final String orderInfo)
{
    Runnable payRunnable = new Runnable()
    {

        @Override
        public void run()
        {
            PayTask alipay = new PayTask(MainActivity.this);
            Map result = alipay.payV2(orderInfo, true);
            Message msg = new Message();
            msg.what = SDK_PAY_FLAG;
            msg.obj = result;
            mHandler.sendMessage(msg);
        }
    };

    Thread payThread = new Thread(payRunnable);
    payThread.start();
}
orderInfo可以在客户端生成,需要AppId,pid以及RSA等等,这样做不安全,推荐的做法是由服务端生成订单信息并加密(生成相关的逻辑在Demo里已经给出了),然后传递给客户端,客户端支付完成后,支付宝将执行一个配置好的URL,例如通知服务端支付完毕,而客户端在支付完成后提示支付成功与否的信息只能作为参考。
最后,附上一份由服务端传入订单信息的代码:
package com.soulgame.magicgame;

import android.annotation.SuppressLint;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.Toast;

import com.alipay.sdk.app.PayTask;
import com.unity3d.player.*;

import java.util.Map;

public class MainActivity extends UnityPlayerActivity
{
    private static final int SDK_PAY_FLAG = 1;
    private static final String RESULT_SUCCESS = "9000";
    private static final String TIP_PAY_SUCCESS = "支付成功";
    private static final String TIP_PAY_FAILED = "支付失败";

    // 支付结果回调,仅作参考,以服务端确认为准!
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler()
    {
        @SuppressWarnings("unused")
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case SDK_PAY_FLAG:
                {
                    @SuppressWarnings("unchecked")
                    PayResult payResult = new PayResult((Map) msg.obj);
                    String resultInfo = payResult.getResult();
                    String resultStatus = payResult.getResultStatus();
                    if (TextUtils.equals(resultStatus, RESULT_SUCCESS))
                    {
                        Toast.makeText(MainActivity.this, TIP_PAY_SUCCESS, Toast.LENGTH_SHORT).show();
                    } else
                    {
                        Toast.makeText(MainActivity.this, TIP_PAY_FAILED, Toast.LENGTH_SHORT).show();
                    }
                    break;
                }
                default:
                    break;
            }
        }

        ;
    };

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
    }
    // Unity中调用
    public void Pay(final String orderInfo)
    {
        Runnable payRunnable = new Runnable()
        {

            @Override
            public void run()
            {
                PayTask alipay = new PayTask(MainActivity.this);
                Map result = alipay.payV2(orderInfo, true);
                Message msg = new Message();
                msg.what = SDK_PAY_FLAG;
                msg.obj = result;
                mHandler.sendMessage(msg);
            }
        };

        Thread payThread = new Thread(payRunnable);
        payThread.start();
    }
}

在Unity中进行调用

在Assets下创建Plugins文件夹,然后在Plugins下创建Android文件夹,将aar和AndroidManifest.xml文件复制到该文件夹下。使用起来可以参考 Unity官方文档。
下面演示了客户端生成字符串的C#脚本,注意商品描述不能有空格!
using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;

[System.Serializable]
public class PayInfo
{
    public string subject;  // 显示在按钮上的内容,跟支付无关系
    public float money;     // 商品价钱
    public string title;    // 商品描述
}

public class AlipayUI : MonoBehaviour
{
    public List
运行结果:
Unity Android平台接入支付宝SDK_第12张图片

总结

1.前一部分配置AndroidStudio适用于所有的SDK。
2.支付宝Demo里有授权信息的方法,手机app内支付用不到,删除即可。


你可能感兴趣的:(Unity)