# 海外安卓游戏SDK-对接文档

# 注意

此SDK对接文档,标注必接的接口请在第一次接入时则必须接入,其余未标注说明必接的接口,可视运营情况及相关说明,再进行对接。

  1. 工程使用AndroidX实现 不支持Android support
  2. 游戏工程必须适配 android 34 targetSdkVersion 必须 大于等于 30
  3. 由于海外的出包性质(abb)无法注入分包,请提供对接完成的游戏 Android 工程,如果无法提供请联系我方技术

# 获取对接物料

开始对接时,我方会提供如下3个参数,如未获取,请联系我方运营或技术获取

参数字段 参数说明 示例
unionPacketCode 对接的唯一包ID 10000
unionGameId 游戏ID 10000
gameKey 登录加密Key 1111
gamePayKey 支付加密Key 1111

# 集成Android客户端SDK

# SDK下载

由于海外是不同的地区本地化域名不同,请联系我方技术获取当前地区的 SDK 版本

# 拷贝资源并添加依赖库

导入资源

  1. 导入assets资源,拷贝资源文件 union_config.json 合并到您的游戏工程assets目录下,并更改文件内的游戏参数

    如果不清楚如何根据参数修改,联系我方技术人员提供参数文件

    {
      "unionPacketCode": "20221000", #对接的唯一包ID
      "unionEnv": "dis", #默认
      "unionLog": "dis", #默认
      "unionGameId": "10011",游戏ID
      "unionVer": 100, #默认
      "unionGameRequestPermissionList": [
        "android.permission.READ_PHONE_STATE"
      ] #默认
    }
    
    
  2. 拷贝union-core-1.0-release.aar包资源到app/libs`文件夹下

  3. 添加依赖aarAndroid Studio中使用,需要在当前app的build.gradle根目录下添加

repositories {
    flatDir {
        dirs 'libs'
    }
}

dependencies { 
    implementation 'com.android.support:support-v4:28.0.0'
    implementation files('libs/union-core-1.0-release.aar') // 核心插件 union_core 默认打入GSON oaid  
}

androidx支持

如果使用的是AndroidX或者无法添加v4 包,union_config.json 里面的unionGameRequestPermissionList设置为[]即可

{
"unionPacketCode": "20221000", 
"unionEnv": "dis", 
"unionLog": "dis", 
"unionGameId": "10011",
"unionVer": 100, 
"unionGameRequestPermissionList": [] 
}
  1. 设置AndroidManifest.xml

    targetSdkVersion为30

配置application

如果您的应用无自定义application,则修改AndroidManifest.xmlApplication如下:

<application android:name="com.union.channel.GameApplication">

如果您的应用有自定义application,则自定义的Application需要继承com.union.channel.GameApplication

<application android:name="自定义的Application">

配置权限

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

配置应用支持

AndroidManifest.xml/application节点下面添加以下配置

 <application
        android:supportsRtl="true"
        android:hardwareAccelerated="true" #支持硬件加速
        android:usesCleartextTraffic="true" #支持http 请求
        android:theme="@android:style/Theme.DeviceDefault.Light.NoActionBar.Fullscreen" #全面屏样式
 />

配置Activity 注意:设置启动Activity和游戏的主activity属性,请根据游戏的横竖屏更改screenOrientation的属性为横屏或者竖屏,请设置configChanges属性为:

android:configChanges="screenSize|keyboardHidden|orientation"

配置闪屏页Activity

增加闪屏页Activity,您的闪屏页activity必须设置继承com.union.platform.view.ui.UnionSplashActivity,并将该Activity设置为程序启动时的Activity

public class SplActivity extends UnionSplashActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(saveInstanceState);
    }

    @Override
    public void startGameActivity() {
        startGameActivity(String channelActivity);
    }
		//MainActivity 为游戏的主Activity
    public void startGameActivity(String channelActivity) {
         Intent intent = new Intent(this, MainActivity.class);
        startActivity(intent);
        overridePendingTransition(android.R.anim.fade_in, android.R.anim.fade_out);
        finish();
    }
}

# 接口说明

所有接口均以默认runOnMainThread,无需再次处理

# SDK包体配置参数(登录之前可获取,需要正确配置Application)

一般游戏包会分不同的专服,不同的专服可能有不同的游戏地址

建议资源文件兼容不同的游戏地址

如果专服的地址在初始化之前需要根据特定配置走可获取 gameid 和 packetCode 作为条件判断

GamePackageConfig gamePackageConfig=UnionGameSDK.share().getGameConfig();
String gameId=gamePackageConfig.getUnionGameId();
String packetCode=gamePackageConfig.getUnionPacketCode();
UnionLog.i(gameId+":"+packetCode);

# 全面屏适配

UnionGameSDK.share().setFullScreenWithSystemUi(Activity activity);

# 显示Android Webview

常用于弹出用户协议 登录协议,分级

UnionGameSDK.share().showWebDialog(Activity activity,"标题","url");

# SDK初始化(必接)

所有其他接口均需要在初始化成功回调后使用

# 调用说明

UnionGameSDK.share().registerCallback(Activity activity,UnionGameCallback callback);

# 参数说明

参数 类型 例子 备注
activity Activity this
callback UnionGameCallback SDK回调 SDK 所有的操作做的回调信息都在这个里面

# 接入示例

UnionGameSDK.share().registerCallback(this, new UnionGameCallback() {
            @Override
            public void onInitResult(int code, String msg) {
                switch (code) {
                    case UnionSDKStatue.CODE_INIT_SUC:
                        // 初始化成功处理
                        break;
                    case UnionSDKStatue.CODE_INIT_FAI:
                        // 初始化失败处理
                        break;
                }
            }

            @Override
            public void onLoginResult(int code, UnionTK token) {

            }

            @Override
            public void onSwitchAccount(UnionTK token) {

            }

            @Override
            public void onLogout() {

            }

            @Override
            public void onPurchaseResult(int code, String msg) {

            }

            @Override
            public void onReportResult(int code) {

            }

            @Override
            public void onGameFunction(int code, String msg) {

            }

            @Override
            public void onExit() {

            }

            @Override
            public void onAdRewardVerify() {

            }
        });

# Activity 生命周期接口(必接)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        UnionGameSDK.share().onCreate(this,savedInstanceState);
    }   

	@Override
    public void onBackPressed() {
        super.onBackPressed();
        UnionGameSDK.share().onBackPressed();
    }

    @Override
    protected void onStart() {
        super.onStart();
        UnionGameSDK.share().onStart();

    }

    @Override
    protected void onPause() {
        super.onPause();
        UnionGameSDK.share().onPause();
    }

    @Override
    protected void onResume() {
        super.onResume();
        UnionGameSDK.share().onResume();

    }

    @Override
    protected void onStop() {
        super.onStop();
        UnionGameSDK.share().onStop();
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        UnionGameSDK.share().onRestart();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        UnionGameSDK.share().onDestroy();
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        UnionGameSDK.share().onNewIntent(intent);
    }

	@Override
    protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
        super.onRestoreInstanceState(savedInstanceState);
        UnionGameSDK.share().onRestoreInstanceState(savedInstanceState);
    }

    @Override
    protected void onSaveInstanceState(@NonNull Bundle outState) {
        super.onSaveInstanceState(outState);
        UnionGameSDK.share().onSaveInstanceState(outState);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data){
        super.onActivityResult(requestCode, resultCode, data);
        YUnionGameSDK.share().onActivityResult(requestCode, resultCode, data);

    }

    @Override
    protected void attachBaseContext(Context newBase) {
        super.attachBaseContext(newBase);
        UnionGameSDK.share().attachBaseContext();
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        UnionGameSDK.share().onConfigurationChanged(newConfig);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        UnionGameSDK.share().onRequestPermissionsResult(requestCode, permissions, grantResults);

    }

# 登录接口(必接)

# 调用说明

UnionGameSDK.getInstance().login(Activity activity);

# 回调示例

            @Override
            public void onLoginResult(int code, UnionToken token) {
                switch (code) {
                    case UnionSDKStatue.CODE_LOGIN_SUC:
                        // 登录成功处理
                         unionToken.getGameId();
                         unionToken.getSign();//登录验证需要
                         unionToken.getTs();//登录验证需要
                         unionToken.getOpenId();
                         unionToken.getTags();//分包TAG
                         unionToken.getPcode();//  游戏渠道包ID
                  	     unionToken.getExtend();//  附加控制参数,json字符串,需要原样回传给研发后端,方便后续新增需求扩展
                    //{"age":"16 年龄分级","ageUrl":"16 年龄分级地址"}
                        break;
                    case UnionSDKStatue.CODE_LOGIN_FAI:
                        // 登录失败处理
                        break;
                }

            }

# 返回的 UnionTK 参数说明

方法 返回类型 例子 备注
getOpenId() String u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
getGameId() int 100000 游戏ID
getCid() String 100000 渠道ID
getTs() String 1701931432675 毫秒级时间戳
getSignVer() int 1 签名版本,当前默认1
getSign() String 642029cf0c290e38a95ef59d232b338f 登录签名
getPcode String 10000 游戏渠道包ID
getExtend() String {"age":"16 年龄分级","ageUrl":"16 年龄分级地址"} 附加控制参数

# 服务端登录验证(必接)

根据登录接口返回的UnionTK字段参数判断以下等式是否成立,成立则通过验证,务必在服务端进行

sign=md5(openId+"|"+gameId+"|"+ts+"|"+gameKey)

# 支付接口(必接)

# 调用说明

UnionGameSDK.getInstance().purchase(Activity activity,UnionPurchaseParams purchaseParams);

# 回调示例

@Override
public void onPurchaseResult(int code, String msg) {
    switch (code) {
        case UnionSDKStatue.CODE_PURCHASE_SUC:
            // 支付成功回调
            break;
        case UnionSDKStatue.CODE_PURCHASE_FAI:
            // 支付失败回调
            break;
    }
}

# 参数说明

方法传入参数UnionPurchaseParams,其属性如下

方法 类型 例子 备注
setOpenId() String u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
setGameId() int 100000 游戏ID
setTs() String 1701931432675 毫秒级时间戳
setSignVer() int 1 签名版本,当前默认1
setSign() String 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
setRoleId() String 147176212 角色ID
setRoleName() String 齐天大圣 角色名称
setRoleLevel() String 10 角色等级
setRoleVipLevel() String 2 角色VIP等级
setRoleFight() String 12612 角色战力
setServerId() String 1001 区服ID
setServerName() String 1001服 区服名称
setGameOrderCode() String 16253651265x17631212 游戏订单号
setGameOrderCustomInfo() String 16253651265x17631212 订单自定义字符串,支付回调时会原样返回
setGameProductCode() String 1001 游戏商品计费点
setGameProductName() String 100元宝 游戏商品名称
setGameProductPrice() int 100 支付金额,单位(分)
setGameExtend() String 100 json格式字符串,扩展参数

# sign签名规则

sign=md5(gameId+"|"+openId+"|"+roleId+"|"+serverId+"|"+gameOrderCode+"|"+gameProductCode+"|"+gameProductPrice+"|"+ts+"|"+gamePayKey);

# 服务端支付回调(必接)

游戏方需要根据下面文档对接完成后提供URL地址给到我方进行配置,游戏在正常支付完成后,游戏方会收到我方接口调用。

# 回调通知方式

HTTP POST

# 回调通知格式

application/json

# 回调参数说明

本协议中所有字符串使用UTF8编码

参数 类型 例子 备注
openId String u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识
gameId int 100000 游戏ID
ts String 1701931432675 毫秒级时间戳
signVer int 1 签名版本,当前默认1
sign String 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
roleId String 147176212 角色ID
serverId String 1001 区服ID
orderCode String i-10000010000-20231109150147645-745gm 我方订单号
gameOrderCode String 16253651265x17631212 游戏方调起支付时传入的游戏订单号
gameOrderCustomInfo String 16253651265x17631212 游戏方调起支付时传入的游戏自定义参数
gameProductCode String 1001 游戏商品计费点
gameProductPrice int 100 支付金额,单位(分)
isSandBox int 0 是否测试订单,1-是测试订单,0-否
discountPrice int 0 优惠金额,单位(分)

# 回调签名说明

sign=md5(`${gameId}|${gameOrderCode}|${orderCode}|${gameProductPrice}|${gameProductCode}|${serverId}|${roleId}|${openId}|${ts}|${gamePayKey}`);

# 回调返回说明

返回类型:字符串

  1. 成功返回小写字母:"ok"
  2. 失败返回:"失败原因"

# 回调接口其他注意事项

  1. 游戏接入时,必须验证订单信息跟游戏方本地下订单信息进行匹配,防止中途被人串改
  2. sign值必须要验证,gamePayKey必须由服务端保存,防止泄漏
  3. 订单有可能会出现多次同步,请做好幂等性,并返回“ok”
  4. 同步失败情况,我方会根据定义好的规则进行多次尝试

# 角色上报接口(必接)

# 调用说明

UnionGameSDK.getInstance().report(UnionAnalyticsParams analyticsParams);

# 回调示例

@Override
public void onReportResult(int code, String msg) {
    switch (code) {
        case EventStatus.CODE_REPORT_SUC:
            // 上报角色信息成功回调
            break;
        case EventStatus.CODE_REPORT_FAI:
            // 上报角色信息失败回调
            break;
    }
}

# 参数说明

方法传入参数UnionAnalyticsParams,其属性如下

参数 类型 例子 备注
setType() int 1 角色上报类型,1-选服,2-创角,3-登录,4-升级,5-退出
setOpenId() String u-10000-579b2fe6d188e1a82dcb06cfff96ebf 用户唯一标识登陆之后返回
setGameId() int 100000 游戏ID 登陆之后返回
setTs() String 1701931432675 毫秒级时间戳,登陆之后返回
setSignVer() int 1 签名版本,当前默认1,登陆之后返回
setSign() String 642029cf0c290e38a95ef59d232b338f 支付下单签名,看下面签名规则
setRoleId() String 147176212 角色ID
setRoleName() String 齐天大圣 角色名称
setRoleLevel() String 10 角色等级
setRoleVipLeve() String 2 角色VIP等级
setRoleFight() String 12612 角色战力
setServerId() String 1001 区服ID
setRoleServerDay() int 1 开服时间
setServerName() String 1001服 区服名称
setGameExtend() String "{}" 扩展参数,json 格式字符串,后续有其他需求在此字段新增

# 签名规则

sign=md5(gameId+"|"+openId+"|"+roleId+"|"+serverId+"|"+ts+"|"+gameKey);

# 退出登录(必接)

当游戏内含有退出按钮或游戏发生顶号时,游戏方可主动调用退出接口

# 调用说明

UnionGameSDK.getInstance().logout();

# 回调示例

@Override
public void onLogout() {
    // SDK已登出,注销相关信息, 执行后续登出操作
}

# 调用显示其他定制功能(研发后端控制)

// 1-打开外部商城,2-打开客服,3-打开问卷,4-打开VIP客服,5-显示激励视频
UnionAnalyticsParams unionAnalyticsParams = new UnionAnalyticsParams();
unionAnalyticsParams.setType(3);
unionAnalyticsParams.setOpenId(unionToken.getOpenId());
unionAnalyticsParams.setRoleId("123456");
unionAnalyticsParams.setRoleName("123456");
unionAnalyticsParams.setRoleLevel("1");
unionAnalyticsParams.setRoleVipLevel("1");
unionAnalyticsParams.setRoleServerDay(5);
unionAnalyticsParams.setRoleFight("1"); //无传0
unionAnalyticsParams.setServerId("1");
unionAnalyticsParams.setServerName("神明一区");
unionAnalyticsParams.setGameExtend("{}");// json 格式字符串
UnionGameSDK.share().showDynamicFunction(unionAnalyticsParams);

# 关闭游戏

调用此接口,APP会被杀掉进程退出到桌面

# 调用说明

UnionGameSDK.getInstance().exit();

# 回调示例

@Override
public void onExit() {
    // 已登出
}