# 一、接入准备
重要!
监管部门对隐私政策的要求:
- 必须要经过 用户同意相关协议 后,
- 游戏(包括打包在应用内的第三方SDK,下同)才能获取一定的用户隐私数据;
- 否则,会被认定为违规、并通报整改,可能将导致应用审核不通过,
严重者强制被下架 。
- 游戏在使用特定权限时(如 android.permission.ACCESS_NETWORK_STATE),
- 必须先告知用户为何需要使用该权限,
- 经用户同意后,才可以向系统申请该权限(整个过程用户需要两次确认);
- 相关接入事项:
监管部门对防沉迷要求:
- 游戏必须接入未成年人防沉迷机制:
- 限制未成年人游戏时长,支持强制下线机制;
- 限制未成年人游戏充值;
- 相关接入事项:
# 1.1 功能介绍
本文将介绍如何快速实现登陆、支付与数据上报,让开发者简单了解一个完整的接入。
完成本文必接
功能,你可以实现:
- 闪屏页面
- 初始化
- 协议
- 回调方法
- 登录
- 角色上报
- 退出登录
- 支付
- 退出游戏
- 实名 + 防沉迷系统
# 1.2 前置条件
- 已完成《第一步》
- 联系
接入方游戏运营
在USDK管理后台 (opens new window) 中获取初始化所必须的参数。 - 保证所有接口都在
主线程
中进行调用activity.runOnUiThread(new Runnable() { @Override public void run() { //做操作 //如果本身就在主线程,不用使用此方式 } });
1
2
3
4
5
6
7
# 1.3 时序图
# 二、 接入步骤
# 2.1 Application接入
操作步骤
自定义游戏的 Application类,继承自SdkApplication
调用示例:
# 2.2 闪屏接入
操作步骤
- 自定义游戏的闪屏Activity类,继承自
com.herosdk.SdkSplashActivity
- 将游戏自定义的闪屏Activity类添加到
AndroidManifest.xml
中
调用示例:
若使用USDK的协议,需要先在中台开启对应游戏产品的
协议开关
后,可在闪屏页面显示
,如下图:
# 2.3 回调方法设置
# 2.3.1 用户协议回调
场景介绍
- 使用 USDK 展示相关协议(如果游戏自己展示用户协议,则忽略此小节);
- 玩家的选择(同意、或拒绝)通过回调方式返回给游戏;
- 在用户选择「同意」前,不能做其他可能涉及读取用户隐私数据的流程,如第三方SDK初始化等;
- 请在
setProtocolListener
中的onAgree
方法执行后续业务流程,如 2.5 USDK初始化接口。
调用方法
public HeroSdk setProtocolListener(com.herosdk.listener.IProtocolListener l)
调用示例
HeroSdk.getInstance().setProtocolListener(new IProtocolListener() {
@Override
public void onAgree() {
//用户已经同意协议,在这里进行init等操作
//必须在这里进行sdk初始化操作,避免因过早读取设备信息而被渠道拒绝
HeroSdk.getIntance().init(activity, productId, productKey);
}
});
2
3
4
5
6
7
8
若游戏不需要中台的用户协议(即将 中台-业务支持能力-协议管理-协议弹窗 关闭),需要
HeroSdk.getInstance().setAgreeProtocol(activity)
# 2.3.2 防沉迷强制下线回调
场景介绍
根据政策要求,游戏必须接入「防沉迷强制下线」流程 ;- 游戏在收到「强制玩家下线通知」后,为了玩家有更好的体验,需要弹窗被踢下线理由(回调中的msg)告知玩家被踢下线,玩家点确认后,必须调用
notifyKickResult
接口反馈「游戏已经执行下线操作」; - 同时,游戏应
禁止玩家再次进入游戏场景
,或返回到登录界面
;
调用方法
public HeroSdk setKickListener(com.herosdk.listener.IKickListener l)
调用示例
HeroSdk.getInstance().setKickListener(new IKickListener() {
@Override
public void onKick(int code, String msg) {
//code:返回的状态码,为0表示渠道返回踢玩家下线成功
//msg:踢玩家下线的原因描述
//此处需要添加游戏踢玩家下线的处理
// 1.弹窗告知玩家踢下线原因
// 2.调用`notifyKickResult`接口
// 3.返回到登录界面
}
});
2
3
4
5
6
7
8
9
10
11
12
- 说明:
- 游戏需要将「下线结果」(成功、或失败)调用 2.3.3 防沉迷强制下线反馈接口通知渠道;
- 游戏在完成「下线操作」之后,重新回到登录状态之前,需要调用2.10 注销登录接口。
# 2.3.3 防沉迷强制下线反馈
场景介绍
- 游戏在执行「防沉迷强制下线」之后,需要结果(成功或失败)反馈给渠道。
调用方法
public void notifyKickResult(String result);
调用示例
// 玩家下线成功
HeroSdk.getInstance().notifyKickResult(com.herosdk.ExtendType.KICK_SUCCESS);
2
- 说明:
- 预设常量有:
com.herosdk.ExtendType.KICK_SUCCESS
下线成功com.herosdk.ExtendType.KICK_FAILED
下线失败
- 预设常量有:
# 2.3.4 USDK初始化回调
场景介绍
- 在调用2.5 USDK初始化接口前设置,用于接收SDK初始化是否成功;
调用方法
public HeroSdk setInitListener(com.herosdk.listener.IInitListener initListener)
调用示例
HeroSdk.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 HeroSdk setLoginListener(com.herosdk.listener.ILoginListener l)
调用示例
HeroSdk.getInstance().setLoginListener(new ILoginListener() {
@Override
public void onSuccess(UserInfo userInfo) {
// 若已有玩家正在游戏中,收到该回调,需要回到游戏主界面,切换玩家数据
// 否则直接进入游戏登录操作
// 渠道登录返回的用户id
// 需要注意华为等渠道返回的uid长度可能会超过256
String uid = userInfo.getUid();
// 渠道登录返回的username
String username = userInfo.getUsername();
// HeroUSDK登录返回的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
28
UserInfo
详情请参考UserInfo类字段说明
字段 | 类型 | 说明 | 备注 |
---|---|---|---|
uid | String | 渠道账号唯一标识 | userInfo.getUid()获取 |
username | String | 渠道账号昵称 | userInfo.getUsername()获取,可能为空,请酌情使用 |
token | String | 渠道账号登录校验令牌 | userInfo.getToken()获取 |
注意 :- 部分渠道(如,华为)返回的
uid长度
可能会超过256,如果游戏服务器有需要使用该字段,请注意预留适当长度。
- 部分渠道(如,华为)返回的
# 2.3.6 切换账号回调
场景介绍
- 部分渠道有账号切换的要求,需要游戏在「收到切换账号通知」时,使用新账号重新进入游戏;
- 回调中的
UserInfo
是 已登录的新账号,请按登录成功的逻辑处理;
调用方法
public HeroSdk setSwitchAccountListener(com.herosdk.listener.ISwitchAccountListener l)
调用示例
HeroSdk.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 HeroSdk setLogoutListener(com.herosdk.listener.ILogoutListener l)
调用示例
HeroSdk.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 HeroSdk setExitListener(com.herosdk.listener.IExitListener l)
调用示例
HeroSdk.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 HeroSdk setPayListener(com.herosdk.listener.IPayListener l)
调用示例
HeroSdk.getInstance().setPayListener(new IPayListener() {
@Override
public void onSuccess(String sdkOrderId, String cpOrderId, String extraParams) {
// 支付成功
// sdkOrderId 为 HeroUSDK订单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 时触发
HeroSdk.getInstance().onCreate(Activity activity);
// Activity 还在栈中时再次启动
HeroSdk.getInstance().onNewIntent(Activity activity, intent);
// 当 Activity 进入“已开始”状态时
HeroSdk.getInstance().onStart(Activity activity);
// Activity 不再位于前台
HeroSdk.getInstance().onPause(Activity activity);
// Activity 从后台恢复
HeroSdk.getInstance().onRestart(Activity activity);
// Activity 会在进入“已恢复”状态时来到前台
HeroSdk.getInstance().onResume(Activity activity);
// Activity 不再对用户可见,已进入“已停止”状态
HeroSdk.getInstance().onStop(Activity activity);
// 销毁 Ativity 之前
HeroSdk.getInstance().onDestroy(Activity activity);
// 获取 Activity 的结果
HeroSdk.getInstance().onActivityResult(Activity activity, int requestCode, int resultCode, Intent data);
// 请求应用权限的结果
HeroSdk.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 USDK初始化接口
场景介绍
- 请在用户同意相关协议后,再调用初始化接口,见 2.3.1 用户协议回调
- 在接入前,请先到 USDK管理后台的
游戏管理-游戏首页
中获取初始化所必须参数:productId
productKey
- 如果需要处理初始化的结果,请设置 2.3.4 USDK初始化回调
- 实测时需要使用真实参数;
- 该方法主要是用于渠道进行初始化必要的数据,必须要调用
调用方法
public void init(Activity activity, String productId, String productKey)
参数说明
字段 | 类型 | 说明 |
---|---|---|
activity | Activity | 当前的活动页面对象 |
productId | String | HeroUSDK后台的产品id |
productKey | String | HeroUSDK后台的产品key |
调用示例
HeroSdk.getInstance().init(activity, "productId", "productKey");
# 2.6 登录接口
场景介绍
为了优化玩家的登录体验,需要登录时需接入登录接口
、用户中心接口
、客服接口
三个接口
- 前置登录界面
- 在游戏更新前显示登录界面,以避免更新过程中导致玩家流失并无法联系客服
- 游戏到登录界面时自动调用登录接口,无感知快速登录并进入游戏
- 自绘
用户中心
按钮- 在登录界面上提供账号中心按钮,方便玩家查询当前账号、切换账号、绑定手机、联系客服等
- 自绘
联系客服
按钮- 在登录界面上提供联系客服按钮,方便玩家在登录出现问题时直接联系客服解决。
- 渠道的登录功能,可能会打开登录界面、或执行渠道自动登录流程:
- 如果需要使用登录结果来关联游戏账号,请 2.3.5 登录结果回调;
调用方法
//登陆接口
public void login(final Activity activity)
//扩展方法
public boolean callExtendApi(Activity activity, int apiName)
2
3
4
5
6
7
调用示例
//调用登陆
HeroSdk.getInstance().login(activity);
//打开用户中心,目前支持官方SDK
HeroSdk.getInstance().callExtendApi(activity, ExtendType.ACCOUNT_BIND)
//打开客服中心,目前支持官方SDK
HeroSdk.getInstance().callExtendApi(activity, ExtendType.CUSTOMER_SERVICE)
2
3
4
5
6
7
8
9
# 2.7 上传当前角色接口
场景介绍
- 在玩家选择角色进入游戏后,上传当前游戏角色的详细信息;
- 渠道要求必须上传 RoleInfo,
请传入真实有效的角色信息
- 角色上报接口用于统计游戏方的角色等信息,主要是方便USDK根据角色查询业务异常,必须在完成登录后方可调用
- 有些联运渠道也要求上传角色信息
- 角色上报的信息,会用于中台进行数据分析
- 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为计价单位
HeroSdk.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为计价单位
HeroSdk.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为计价单位
HeroSdk.getInstance().roleLevelUp(activity, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
# 2.10 注销登录接口
场景介绍
- 有需要时,游戏可以主动调用渠道的注销登录(退出登录)接口,用于渠道端清理账号登录状态。
调用方法
public void logout(Activity activity)
调用示例
HeroSdk.getInstance().logout(activity);
# 2.11 退出游戏接口
场景介绍
- 有需要时,游戏可以主动调用渠道的退出游戏接口,用于渠道记录玩家状态(如防沉迷的下线时间等):
- 请先通过
isChannelHasExitDialog
接口判断渠道是否有退出框, - 如果有退出框,则可以调用
exit
接口; - 如果没有退出框,则游戏自身需要创建退出框,在玩家确认后再调用
exit
接口。
- 请先通过
调用方法
public void exit(Activity activity)
调用示例
//根据isChannelHasExitDialog的返回值,判断渠道sdk是否有退出框
if (HeroSdk.getInstance().isChannelHasExitDialog()) {
//渠道sdk有退出框,则直接调用HeroSdk的exit函数
HeroSdk.getInstance().exit(activity);
} else {
//渠道sdk没有退出框,则游戏需要自己创建退出框,并在用户点击“退出”之后调用HeroSdk的exit函数
new AlertDialog.Builder(activity).setTitle("退出")
.setMessage("确定退出游戏?")
.setCancelable(true)
.setPositiveButton("退出",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int whichButton) {
HeroSdk.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 支付接口
场景介绍
- 玩家在游戏内的商城选择需要购买的档位后,
- 游戏先在自己的业务流程中产生 游戏订单,
- 再调用USDK支付接口,并传入 游戏订单号、角色信息等,调用接口后将拉起支付页面
- 部分渠道会唤起第三方支付界面
- 相关:
注意:
支付实际到账结果,请以服务端通知为准。
调用方法
public void pay(Activity activity, OrderInfo orderInfo, RoleInfo roleInfo)
参数说明
- OrderInfo 简要说明:
字段 | 类型 | 重要 | 说明 |
---|---|---|---|
goodsId | String | 商品ID,与后台配置相关联 | |
cpOrderId | String | 游戏的订单 | |
amount | double | 商品金额(单位分) | |
currency | String | 币种(默认值"CNY") | |
callbackUrl | String | 可选 | 支付的回调地址,也可以在后台配置 |
extraParams | String | 可选 | 透传参数,SDK服务端将会原样回调给游戏服务端 |
* 补充:
* **支付的回调地址** 在客户端和后台都设置的情况下,以后台设置的为准
* **支持币种** "USD"、"CNY"、"EUR"、"GBP"、"HKD"、"IDR"、"IRR"、"JPY"、"KRW"、"THB"、"TWD"
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("光明顶"); //玩家公会名称
HeroSdk.getInstance().pay(activity, orderInfo, roleInfo);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 三、自测指南
如果在接入、测试过程中遇到问题,你可以点击查看常见问题
# 3.1 母包的一些正常提示性页面
- 母包说明
- 登录测试说明
- 支付测试说明
# 3.2 遇到以下提示页面不要慌
Application未正常接入提示,请查看2.1 Application接入
闪屏未正常接入提示,请查看2.2 闪屏接入
# 3.3 如何验证登录功能接入成功?
- 开发者在代码中检查在用户登录后,是否有登录成功的回调
若有,即表示该功能接入成功;
示例:
打开登录界面(这是母包的登录,母包可以使用任意账号测试):
登录成功后收到回调(这里直接点母包登录的「成功」按钮即可)
# 3.4 如何验证支付功能接入成功?
- 点击商品购买后,如使用的是测试账号登录,会进入到如下正常支付页面,如:
- 点击支付成功 看游戏内是否收到相应的商品
恭喜你完成快速接入,登陆与支付功能即可正常使用啦~
# 四、补充说明
提示
您还可以了解更多 USDK的拓展功能