# 一、接入准备
重要!
监管部门对隐私政策的要求:
- 必须要经过 用户同意相关协议 后,
- 游戏(包括打包在应用内的第三方SDK,下同)才能获取一定的用户隐私数据;
- 否则,会被认定为违规、并通报整改,可能将导致应用审核不通过,
严重者强制被下架 。
- 游戏在使用特定权限时(如 android.permission.ACCESS_NETWORK_STATE),
- 必须先告知用户为何需要使用该权限,
- 经用户同意后,才可以向系统申请该权限(整个过程用户需要两次确认);
- 相关接入事项:
监管部门对防沉迷要求:
- 游戏必须接入未成年人防沉迷机制:
- 限制未成年人游戏时长,支持强制下线机制;
- 限制未成年人游戏充值;
- 相关接入事项:
监管部门对账号删除功能要求: 上架安卓国内渠道必须拥有账号删除(账号注销)功能:
按照下面流程接入后,使用打包工具打【国内Android】、【海外Android】渠道包,SDK自带账号删除功能,无需单独接入
# 1.1 功能介绍
本文将介绍如何快速实现登陆、支付与数据上报,让开发者简单了解一个完整的接入。
完成本文必接
功能,你可以实现:
- 闪屏页面
- 初始化
- 协议
- 回调方法
- 登录
- 角色上报
- 退出登录
- 支付
- 退出游戏
- 实名 + 防沉迷系统
# 1.2 前置条件
- 已完成《第一步》
- 联系
接入方游戏运营
在UltraSDK管理后台 (opens new window) 中获取初始化所必须的参数。
# 1.3 时序图
# 二、 接入步骤
# 2.1 Application接入
操作步骤
自定义游戏的 Application类,继承自SdkApplication
调用示例:
# 2.2 闪屏接入
操作步骤
- 自定义游戏的闪屏Activity类,继承自
com.ultrasdk.SdkSplashActivity
- 将游戏自定义的闪屏Activity类添加到
AndroidManifest.xml
中
调用示例:
若使用UltraSDK的协议,需要先在中台开启对应游戏产品的
协议开关
后,可在闪屏页面显示
,如下图:
# 2.3 回调方法设置
# 2.3.1 用户协议回调
场景介绍
- 使用 UltraSDK 展示相关协议(如果游戏自己展示用户协议,则忽略此小节);
- 玩家的选择(同意、或拒绝)通过回调方式返回给游戏;
- 在用户选择「同意」前,不能做其他可能涉及读取用户隐私数据的流程,如第三方SDK初始化等;
- 请在
setProtocolListener
中的onAgree
方法执行后续业务流程,如 2.5 UltraSDK初始化接口。
调用方法
public UltraSdk setProtocolListener(com.ultrasdk.listener.IProtocolListener l)
调用示例
UltraSdk.getInstance().setProtocolListener(new IProtocolListener() {
@Override
public void onAgree() {
//用户已经同意协议,在这里进行init等操作
UltraSdk.getIntance().init(activity, productId, productKey);
}
});
2
3
4
5
6
7
若游戏不使用UltraSDK提供的协议功能,需要
UltraSdk.getInstance().setAgreeProtocol(activity)
# 2.3.2 防沉迷强制下线回调
场景介绍
根据政策要求,游戏必须接入「防沉迷强制下线」流程 ;- 游戏客户端在收到「强制玩家下线通知」后,必须调用
notifyKickResult
接口反馈「游戏已经执行下线操作」; - 同时,游戏应
禁止玩家再次进入游戏场景
,或返回到登录界面
; - 此接口是游戏客户端上报至UltraSDK即可,是客户端上报,与游戏服务端无关
调用方法
public UltraSdk setKickListener(com.ultrasdk.listener.IKickListener l)
调用示例
UltraSdk.getInstance().setKickListener(new IKickListener() {
@Override
public void onKick(int code, String msg) {
//code:返回的状态码,为0表示渠道返回踢玩家下线成功
//msg:踢玩家下线的原因描述
//此处需要添加游戏踢玩家下线的处理
}
});
2
3
4
5
6
7
8
9
- 说明:
- 游戏需要将「下线结果」(成功、或失败)调用 2.3.3 防沉迷强制下线反馈接口通知渠道;
- 游戏在完成「下线操作」之后,重新回到登录状态之前,需要调用2.10 注销登录接口。
# 2.3.3 防沉迷强制下线反馈
场景介绍
- 游戏在执行「防沉迷强制下线」之后,需要结果(成功或失败)反馈给渠道。
调用方法
public void notifyKickResult(String result);
调用示例
// 玩家下线成功
UltraSdk.getInstance().notifyKickResult(com.ultrasdk.ExtendType.KICK_SUCCESS);
2
- 说明:
- 预设常量有:
com.ultrasdk.ExtendType.KICK_SUCCESS
下线成功com.ultrasdk.ExtendType.KICK_FAILED
下线失败
- 预设常量有:
# 2.3.4 UltraSdk初始化回调
场景介绍
- 在调用2.5 UltraSdk初始化接口前设置,用于接收SDK初始化是否成功;
调用方法
public UltraSdk setInitListener(com.ultrasdk.listener.IInitListener initListener)
调用示例
UltraSdk.getInstance().setInitListener(new IInitListener() {
@Override
public void onSuccess() {
//初始化成功
//这里可以做其他三方sdk的初始化操作或者游戏的加载操作
//国内官方渠道与全球渠道调用初始化就会立即返回成功,避免因网络原因阻碍了游戏在这里的相关操作
}
@Override
public void onFailed(String msg) {
//初始化失败
//这里研发自行处理是否给玩家弹框提示
}
);
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.3.5 登录结果回调
场景介绍
- 在调用2.6 登录接口前设置;
- 处理登录结果(登录成功、失败,或取消登录);
调用方法
public UltraSdk setLoginListener(com.ultrasdk.listener.ILoginListener l)
调用示例
UltraSdk.getInstance().setLoginListener(new ILoginListener() {
@Override
public void onSuccess(UserInfo userInfo) {
// 若已有玩家正在游戏中,收到该回调,需要回到游戏主界面,切换玩家数据
// 否则直接进入游戏登录操作
// 渠道登录返回的用户id
// 需要注意华为等渠道返回的uid长度可能会超过256
String uid = userInfo.getUid();
// 渠道登录返回的username
String username = userInfo.getUsername();
// UltraSdk登录返回的token
String token = userInfo.getToken();
}
@Override
public void onFailed(String msg) {
//登录失败
}
@Override
public void onCancel() {
//登录取消
}
});
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
UserInfo
详情请参考UserInfo类字段说明
字段 | 类型 | 说明 | 备注 |
---|---|---|---|
uid | String | 渠道账号唯一标识 | userInfo.getUid()获取 |
username | String | 渠道账号昵称 | userInfo.getUsername()获取,可能为空,请酌情使用 |
token | String | 渠道账号登录校验令牌 | userInfo.getToken()获取 |
注意 :- 部分渠道(如,华为)返回的
uid长度
可能会超过256,如果游戏服务器有需要使用该字段,请注意预留适当长度。
- 部分渠道(如,华为)返回的
# 2.3.6 切换账号回调
场景介绍
- 部分渠道有账号切换的要求,需要游戏在「收到切换账号通知」时,使用新账号重新进入游戏;
- 回调中的
UserInfo
是 已登录的新账号,请按登录成功的逻辑处理;
调用方法
public UltraSdk setSwitchAccountListener(com.ultrasdk.listener.ISwitchAccountListener l)
调用示例
UltraSdk.getInstance().setSwitchAccountListener(new ISwitchAccountListener() {
@Override
public void onSuccess(UserInfo userInfo) {
//切换账号成功
//游戏需要回到主界面,切换玩家数据
}
@Override
public void onFailed(String msg) {
//切换账号失败
}
@Override
public void onCancel() {
//切换账号取消
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 2.3.7 账号注销登录回调
场景介绍
- 部分渠道有
登出账号
的流程,需要响应「账号注销登录」通知; - 账号注销登录(退出登录)后建议退出游戏,或返回到游戏登录界面;
调用方法
public UltraSdk setLogoutListener(com.ultrasdk.listener.ILogoutListener l)
调用示例
UltraSdk.getInstance().setLogoutListener(new ILogoutListener() {
@Override
public void onSuccess() {
//注销成功,一般这里CP需要返回至游戏的登录页面
}
@Override
public void onFailed(String msg) {
//注销失败
}
});
2
3
4
5
6
7
8
9
10
11
# 2.3.8 退出游戏回调
场景介绍
- 特定情况下,需要游戏响应「退出游戏」通知;
调用方法
public UltraSdk setExitListener(com.ultrasdk.listener.IExitListener l)
调用示例
UltraSdk.getInstance().setExitListener(new IExitListener() {
@Override
public void onSuccess() {
// 退出成功
// 此处游戏需要实现自己的退出处理,下面两行代码仅为示例代码,可删除
finish();
System.exit(0);
}
@Override
public void onFailed(String msg) {
//退出失败
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
# 2.3.9 支付回调
场景介绍
- 仅用于「非单机」游戏,
单机游戏请勿设置此回调 ; - 用于处理 2.12 支付接口 的客户端结果;
- 为了保障游戏开发者和玩家的利益,最终支付结果请以服务端通知为准;
调用方法
public UltraSdk setPayListener(com.ultrasdk.listener.IPayListener l)
调用示例
UltraSdk.getInstance().setPayListener(new IPayListener() {
@Override
public void onSuccess(String sdkOrderId, String cpOrderId, String extraParams) {
// 支付成功
// sdkOrderId 为 UltraSdk订单id
// cpOrderId 为 游戏订单id
// extraParams 为 游戏的透传参数
}
@Override
public void onFailed(String cpOrderId, String msg) {
// 支付失败
}
@Override
public void onCancel(String cpOrderId) {
// 支付取消
}
});
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
注意: - 充值是否成功到账,
必须以游戏服务器收到的通知为准 ,客户端的通知仅做参考。- 部分渠道SDK客户端的支付通知不准确。
- 单机游戏请匆设置此支付监听器
- 单机游戏支付 请参考单机游戏支付-拓展功能。
- 充值是否成功到账,
# 2.4 应用生命周期相关
场景介绍
Android渠道
要求关联游戏的主要窗口(Activity)的生命周期;- Application 的生命周期在继承的
SdkApplication
处理,见 2.1 Application接入; - 闪屏界面 不要求生命周期关联;
- 窗口(Activity)的生命周期包括(
必须接入 ):- onCreate / onNewIntent / onDestroy
- onStart / onStop / onRestart
- onPause / onResume
- onActivityResult
- onRequestPermissionsResult
- Application 的生命周期在继承的
调用方法
// 首次创建 Activity 时触发
UltraSdk.getInstance().onCreate(Activity activity);
// Activity 还在栈中时再次启动
UltraSdk.getInstance().onNewIntent(Activity activity, intent);
// 当 Activity 进入“已开始”状态时
UltraSdk.getInstance().onStart(Activity activity);
// Activity 不再位于前台
UltraSdk.getInstance().onPause(Activity activity);
// Activity 从后台恢复
UltraSdk.getInstance().onRestart(Activity activity);
// Activity 会在进入“已恢复”状态时来到前台
UltraSdk.getInstance().onResume(Activity activity);
// Activity 不再对用户可见,已进入“已停止”状态
UltraSdk.getInstance().onStop(Activity activity);
// 销毁 Ativity 之前
UltraSdk.getInstance().onDestroy(Activity activity);
// 获取 Activity 的结果
UltraSdk.getInstance().onActivityResult(Activity activity, int requestCode, int resultCode, Intent data);
// 请求应用权限的结果
UltraSdk.getInstance().onRequestPermissionsResult(Activity activity, int requestCode, String[] permissions, int[] grantResults);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 2.5 UltraSDK初始化接口
场景介绍
- 请在用户同意相关协议后,再调用初始化接口,见 2.3.1 用户协议回调
- 如果需要处理初始化的结果,请设置 2.3.4 UltraSdk初始化回调
- 该方法主要是用于渠道进行初始化必要的数据,必须要调用
调用方法
public void init(Activity activity)
参数说明
字段 | 类型 | 说明 |
---|---|---|
activity | Activity | 当前的活动页面对象 |
调用示例
UltraSdk.getInstance().init(activity);
# 2.6 登录接口
场景介绍
- 渠道的登录功能,可能会打开登录界面、或执行渠道自动登录流程:
- 自动登录流程会有UI提示,并且允许玩家中止自动登录或切换账号;
- 如果需要使用登录结果来关联游戏账号,请 2.3.5 登录结果回调;
调用方法
public void login(final Activity activity)
调用示例
UltraSdk.getInstance().login(activity);
# 2.7 上传当前角色接口
场景介绍
- 在玩家选择角色进入游戏后,上传当前游戏角色的详细信息;
- 渠道要求必须上传 RoleInfo,
请传入真实有效的角色信息,有些字段如果没有,可以默认传1
- 角色上报接口用于统计游戏方的角色等信息,主要是方便UltraSDK根据角色查询业务异常,必须在完成登录后方可调用
- 有些联运渠道也要求上传角色信息
- 角色上报的信息,会用于中台进行数据分析
- roleId、roleName、serverId、serverName 支付下单时也会使用,不上报会影响到支付功能
- 相关接口:
调用方法
public void enterGame(Activity activity, RoleInfo roleInfo)
调用示例
RoleInfo roleInfo = new RoleInfo();
roleInfo.setRoleId("1001"); // 必须:玩家角色Id
roleInfo.setRoleName("test112"); // 必须:玩家角色名
roleInfo.setServerId("20"); // 必须:区服Id
roleInfo.setServerName("server20"); // 必须:区服名称
roleInfo.setRoleLevel("10"); // 玩家角色等级,没有则传0
roleInfo.setVipLevel("0"); // 玩家vip等级,没有则传0
roleInfo.setPartyName("公会名称"); // 玩家公会名称
roleInfo.setRoleCreateTime("10位数时间戳"); //若游戏要到UC渠道发行,10位数时间戳的值必须来自于游戏服务器
roleInfo.setBalanceLevelOne(100); //玩家账户一级货币余额(充值货币),由人民币直接购买,如点券等
roleInfo.setBalanceLevelTwo(100); //玩家账户二级货币余额(非充值货币),游戏内获得或一级货币转化,如金币等
roleInfo.setSumPay(70007); //累计充值金额,以RMB为计价单位
UltraSdk.getInstance().enterGame(activity, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
- 注意:
setRoleCreateTime 所设置的时间戳,单位为秒,一般是10位数字,请使用游戏服务端的角色真实创建时间;
RoleInfo
详情请参考RoleInfo类字段说明,基本字段如下:字段 类型 重要 说明 serverId String (必传) 区服ID(数字字符串) serverName String (必传) 区服名称 roleId String (必传) 角色ID roleName String (必传) 角色名称
# 2.8 创建新角色接口
场景介绍
- 当玩家创建新游戏角色后,请上传角色详细信息
- 渠道要求必须上传 RoleInfo,
请传入真实有效的角色信息 - 相关接口:
调用方法
public void createNewRole(Activity activity, RoleInfo roleInfo)
调用示例
RoleInfo roleInfo = new RoleInfo();
roleInfo.setRoleId("1001"); //玩家角色Id
roleInfo.setRoleName("test112"); //玩家角色名
roleInfo.setServerId("20"); //区服Id
roleInfo.setServerName("server20"); //区服名称
roleInfo.setRoleLevel("10"); //玩家角色等级,没有则传0
roleInfo.setVipLevel("0"); //玩家vip等级,没有则传0
roleInfo.setPartyName("公会名称"); //玩家公会名称
roleInfo.setRoleCreateTime("10位数时间戳"); //若游戏要到UC渠道发行,10位数时间戳的值必须来自于游戏服务器
roleInfo.setBalanceLevelOne(100); //玩家账户一级货币余额(充值货币),由人民币直接购买,如点券等
roleInfo.setBalanceLevelTwo(100); //玩家账户二级货币余额(非充值货币),游戏内获得或一级货币转化,如金币等
roleInfo.setSumPay(70007); //累计充值金额,以RMB为计价单位
UltraSdk.getInstance().createNewRole(activity, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
# 2.9 角色升级接口
场景介绍
- 当角色升级的时候调用,请上传角色详细信息
- 渠道要求必须上传 RoleInfo,
请传入真实有效的角色信息 - 相关接口:
调用方法
public void roleLevelUp(Activity activity, RoleInfo roleInfo)
调用示例
RoleInfo roleInfo = new RoleInfo();
roleInfo.setRoleId("1001"); // 玩家角色Id
roleInfo.setRoleName("test112"); // 玩家角色名
roleInfo.setServerId("20"); // 区服Id
roleInfo.setServerName("server20"); // 区服名称
roleInfo.setRoleLevel("10"); // 玩家角色等级,没有则传0
roleInfo.setVipLevel("0"); // 玩家vip等级,没有则传0
roleInfo.setPartyName("公会名称"); // 玩家公会名称
roleInfo.setRoleCreateTime("10位数时间戳"); // 若游戏要到UC渠道发行,10位数时间戳的值必须来自于游戏服务器
roleInfo.setBalanceLevelOne(100); // 玩家账户一级货币余额(充值货币),由人民币直接购买,如点券等
roleInfo.setBalanceLevelTwo(100); // 玩家账户二级货币余额(非充值货币),游戏内获得或一级货币转化,如金币等
roleInfo.setSumPay(70007); // 累计充值金额,以RMB为计价单位
UltraSdk.getInstance().roleLevelUp(activity, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
# 2.10 注销登录接口
场景介绍
- 有需要时,游戏可以主动调用渠道的注销登录(退出登录)接口,用于渠道端清理账号登录状态。
调用方法
public void logout(Activity activity)
调用示例
UltraSdk.getInstance().logout(activity);
# 2.11 退出游戏接口
场景介绍
- 有需要时,游戏可以主动调用渠道的退出游戏接口,用于渠道记录玩家状态(如防沉迷的下线时间等):
- 请先通过
isChannelHasExitDialog
接口判断渠道是否有退出框, - 如果有退出框,则可以调用
exit
接口; - 如果没有退出框,则游戏自身需要创建退出框,在玩家确认后再调用
exit
接口。
- 请先通过
调用方法
public void exit(Activity activity)
调用示例
//根据isChannelHasExitDialog的返回值,判断渠道sdk是否有退出框
if (UltraSdk.getInstance().isChannelHasExitDialog()) {
//渠道sdk有退出框,则直接调用UltraSdk的exit函数
UltraSdk.getInstance().exit(activity);
} else {
//渠道sdk没有退出框,则游戏需要自己创建退出框,并在用户点击“退出”之后调用UltraSdk的exit函数
new AlertDialog.Builder(activity).setTitle("退出")
.setMessage("确定退出游戏?")
.setCancelable(true)
.setPositiveButton("退出",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
UltraSdk.getInstance().exit(activity);
}
})
.setNeutralButton("取消", null)
.show();
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 2.12 支付接口
场景介绍
- 玩家在游戏内的商城选择需要购买的档位后,
- 游戏先在自己的业务流程中产生 游戏订单,
- 再调用UltraSdk支付接口,并传入 游戏订单号、角色信息等,调用接口后将拉起支付页面
- 部分渠道会唤起第三方支付界面
- 相关:
注意:
支付实际到账结果,请以服务端通知为准。
调用方法
public void pay(Activity activity, OrderInfo orderInfo, RoleInfo roleInfo)
参数说明
OrderInfo 简要说明:
字段 类型 重要 说明 goodsId String 必传 商品ID,与后台配置相关联 cpOrderId String 必传 游戏的订单 callbackUrl String 可选 支付的回调地址,也可以在后台配置 extraParams String 可选 透传参数,SDK服务端将会原样回调给游戏服务端 - 补充:
- 支付的回调地址 在客户端和后台都设置的情况下,以后台设置的为准
- 如果想实现不同区服的回调,则需要游戏自己区分区服实现
- 补充:
RoleInfo 简要说明:
字段 类型 说明 备注 serverId String 区服ID(数字字符串) (必传) serverName String 区服名称 (必传) roleId String 角色ID (必传) roleName String 角色名称 (必传)
调用示例
OrderInfo orderInfo = new OrderInfo();
orderInfo.setCpOrderId("cpOrderId_1475896482" ); //游戏订单号
orderInfo.setGoodsId("1000"); // 商品id
orderInfo.setExtraParams("透传参数"); //如果游戏用不到透传参数,可以不传
RoleInfo roleInfo = new RoleInfo();
roleInfo.setServerId("100"); //区服id
roleInfo.setServerName("混沌漩涡"); //区服名称
roleInfo.setRoleId("8888"); //角色id
roleInfo.setRoleName("光之王"); //角色名称
roleInfo.setRoleLevel("8");//角色等级
roleInfo.setVipLevel("Vip6");//角色的vip等级
roleInfo.setBalanceLevelOne("100"); //玩家账户一级货币余额(充值货币),由人民币直接购买,如点券等
roleInfo.setBalanceLevelTwo("100"); //玩家账户二级货币余额(非充值货币),游戏内获得或一级货币转化,如金币等
roleInfo.setPartyName("光明顶"); //玩家公会名称
UltraSdk.getInstance().pay(activity, orderInfo, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 三 测试指南
如果在接入、测试过程中遇到问题,你可以点击查看常见问题
# 如何验证登入功能接入成功?
登陆接入是否的验证,只需要开发者在代码中检查在用户登陆后是否有登陆回调,若有,即表示该功能接入成功
# 如何验证支付功能接入成功?
支付成功的验证,只需要点击商品购买后,确保界面拉起ios支付验证界面即表示该功能接入成功。
# 3.1 开发自测
# 登录功能
用户登录后,在代码中检查是否有登录回调,有回调即表示接入成功。
- 开发者在代码中检查在用户登录后,是否有登录成功的回调
若有,即表示该功能接入成功;
示例:
打开登录界面(这是母包的登录,母包可以使用任意账号测试):
登录成功后收到回调(这里直接点母包登录的「成功」按钮即可)
# 支付功能
点击商品购买后,确保界面能拉起支付验证界面,能拉起即表示接入成功(注:母包支付过程中,客户端点击后弹出的【支付成功】和【支付失败】选项仅用于发出客户端通知,服务器发货通知则是以是否使用此处创建的测试账号且账号余额足够为判断依据)。
# 3.2 QA测试
完成登录、支付功能自测后,提交QA测试,可参考母包测试用例 (opens new window)
恭喜你完成快速接入,登陆与支付功能即可正常使用啦~
# 恭喜你完成SDK集成,如果需要打出渠道包用于提审,让我们开始《打包发布》吧~
# 四、补充说明
提示
您还可以了解更多 UltraSdk的拓展功能