Android 海外AAB接入文档
说明
- aab 是 google play 上传应用的一种资源格式
- (必须适配 android 14系统版本,否则会影响google play上架)
- 推荐使用Unity 导出 Android Studio 项目出包方式
- 如游戏首次接入,要做好 Android 手机全面屏适配(常见适配方式一般都是默认全屏展示,顶部刘海或摄像头相关不能影响到游戏相关 UI 功能,否则云测时会影响评级)
- 确保所有调用SDK的接口都放在()调用
- Unity 中调用到 java 中的接口注意需要切换到 UI 线程再调用 SDK 的接口
- 请务必详细查看文档,如有对某些接入部分存在疑问可直接在对接群与技术沟通
- 本文档会不定期更新,如涉及接口变动会在群内同步消息,更多更新内容请查看Android SDK更新
- 点击此处可进行Android-AAB-Demo 下载
接入流程
说明
- 1.找运营申请相关参数与配置,目前接入需要三个配置文件google-services.json, access.config以及 keystore 签名文件
- 2.下载 Demo 示例工程,文件使用参考Demo相关工程结构配置
- 3.配置远程仓库配置并调用相关接口
参数配置()
project:build.gradle
buildscript {
repositories {
maven {
url 'https://sdk.wdyxgames.com/nexus/repository/sdk-public/'
}
}
}
allprojects {
repositories {
maven {
url 'https://sdk.wdyxgames.com/nexus/repository/sdk-public/'
}
}
}
或 settings.gradle 下配置
pluginManagement {
repositories {
maven {
url 'https://sdk.wdyxgames.com/nexus/repository/sdk-public/'
}
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
maven {
url 'https://sdk.wdyxgames.com/nexus/repository/sdk-public/'
}
}
}
app:build.gradle 配置()
注意:apk 出包时仅引用 hoolai-core 库即可
//引入google插件 id 'com.google.gms.google-services'
plugins {
id 'com.android.application'
id 'com.google.gms.google-services'
}
//引入依赖库
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
//hoolai-core(必接)
implementation 'com.hoolai.access.open:hoolai-core:1.0.4.2-global'
//access-native(必接)
implementation 'com.hoolai.access.platform:access-native:0.1.2.1425-global'
//fangzhou(必接)
implementation 'com.hoolai.access.open.fangzhou:fangzhou:4.5.16.11'
//基础功能模块,登录/支付/分享等(必接)
implementation 'com.hoolai.oversea:hl-oversea-global:1.0.5.1'
//aihelp(必接)
implementation 'com.hoolai.oversea.aihelp:aihelp:1.0.0.1'
//appsflyer(必接)
implementation 'com.hoolai.oversea.appsflyer:appsflyer:1.0.0.2'
//firebase(必接)
implementation 'com.hoolai.oversea.firebase:firebase:1.0.1.0'
//facebooklinks(必接)
implementation 'com.hoolai.oversea.links:facebooklinks:1.0.1.0'
//openInstall(选接)
implementation 'com.hoolai.oversea.opins:openInstall:1.0.0.0'
//crashlytics(⚠️该库已废弃,和firebase类库已合并)
//implementation 'com.hoolai.oversea.crash:crashlytics:1.0.0.0'
}
AndroidManifest.xml 配置()
以下配置为 google 授权登录,Facebook 授权登录,以及 Google Play Games Services v2 授权登录配置,如不需要可不配置(这里需要在 demo 中验证)
<!--Games Services Sign In v2 如要使用PGS登录必须配置!否则不需要加-->
<meta-data android:name="com.google.android.gms.games.APP_ID"
android:value="@string/game_services_project_id"/>
<!--Games Services Sign In v2 如要使用PGS登录必须配置!否则不需要加-->
<!--注意需为游戏的启动类 Activity 中配置intent-filter!以下为示例无需 copy!-->
<activity
android:name="com.hoolai.access.demo.GameActivity"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:theme="@style/HlAccountTransparent"
android:configChanges="orientation|keyboardHidden|screenSize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- SDK内部配置(必须) 其中scheme的value值为accesssdk+channelId-->
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="accesssdk1"/>
</intent-filter>
<!-- SDK内部配置(必须) 其中scheme的value值为accesssdk+channelId-->
</activity>
<!--注意需为游戏的启动类 Activity 中配置intent-filter!示例无需 copy!-->
<!--Facebook login share-->
<provider
android:name="com.facebook.FacebookContentProvider"
android:authorities="com.facebook.app.FacebookContentProvider1234567890"
android:exported="true" />
<meta-data
android:name="com.facebook.sdk.ApplicationId"
android:value="@string/facebook_app_id" />
<meta-data
android:name="com.facebook.sdk.ClientToken"
android:value="@string/facebook_client_token" />
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="@string/fb_login_protocol_scheme" />
</intent-filter>
</activity>
<!--Facebook end-->
上面的参数配置位置在 res/values/strings.xml 文件中配置,以下参数由运营提供
<string name="facebook_app_id">facebookAppId</string>
<string name="fb_login_protocol_scheme">fbScheme</string>
<string name="facebook_client_token">facebookClientToken</string>
<string translatable="false" name="game_services_project_id">googleProjectId</string>
接口文档
生命周期接入
Application 接入()
方式一:游戏无自定义 Application 时使用 HLApplication,参考 AndroidManifest.xml 中的 <application name 标签属性配置
方式二:如游戏有自定义 Application 通过继承 HLApplication 即可
方式三:游戏有自定义 Application 且不能继承 HLApplication 时需要在 Application 生命周期进行以下调用:
public class YourApplication extends YourBaseApplication {
@Override
public void onCreate() {
super.onCreate();
FastSdk.onApplicationCreate(this);
}
@Override
public void onTerminate() {
super.onTerminate();
FastSdk.onTerminate(this);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
FastSdk.onConfigurationChanged(this, newConfig);
}
@Override
protected void attachBaseContext(Context context) {
super.attachBaseContext(context);
FastSdk.attachBaseContext(this, context);
}
}
Activity 生命周期接入()
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
FastSdk.onSaveInstanceState(outState);
}
@Override
protected void onStart() {
super.onStart();
FastSdk.onStart(this);
}
@Override
protected void onResume() {
super.onResume();
FastSdk.onResume(this);
}
@Override
protected void onStop() {
super.onStop();
FastSdk.onStop(this);
}
@Override
protected void onPause() {
super.onPause();
FastSdk.onPause(this);
}
@Override
protected void onRestart() {
super.onRestart();
FastSdk.onRestart(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
FastSdk.onDestroy(this);
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
FastSdk.onNewIntent(intent);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
FastSdk.onActivityResult(this, requestCode, resultCode, data);
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
FastSdk.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
FastSdk.onConfigurationChanged(this, newConfig, getResources());
}
@Override
public void onBackPressed() {
FastSdk.exit();
}
@Override
public Resources getResources() {
return FastSdk.getResources(super.getResources());
}
//以下为更新内容
@Override
protected void onRestoreInstanceState(@NonNull Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
FastSdk.onRestoreInstanceState(savedInstanceState);
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
FastSdk.onWindowFocusChanged(hasFocus);
}
SDK 功能接入
初始化()
注意
- SDK初始化期间,解决游戏黑屏的建议:准备一张名为"unity_static_splash"的图片,拷贝至res/drawable目录即可
- 游戏启动后首先调用此接口,后才能进行热更/版本检测/游戏初始化/登录等功能调用
- 在未收到初始化回调或收到onInitFailed时,游戏不可进行后续功能调用
- 初始化失败时建议引导用户重新初始化或重启游戏
//游戏主Activity的onCreate中
//SDK初始化回调
FastSdk.hlSystemListener = new HLSystemListener() {
@Override
public void onInitSuccess(InitResult initResult) {
//gameId,channelId,channel
}
@Override
public void onInitFailed(String reason) {
}
@Override
public void onCustomExit() {
/* demo 只作为参考,游戏应该根据自己所需逻辑实现
* 渠道没有退出二次确认框
* 根据需要加二次确认框
*/
//渠道不存在退出界面,如百度移动游戏等,此时需在此处弹出游戏退出确认界面,否则会出现渠道审核不通过情况
//游戏实现自己的退出界面 ,实现退出逻辑,请勿直接照搬demo
//根据需要加二次确认框
new AlertDialog.Builder(GameActivity.this)
.setTitle("游戏退出弹窗")
.setMessage("我是游戏的弹窗界面哦")
.setNegativeButton("取消", null)
.setPositiveButton("确定", (dialog, which) -> onExitSuccess(s))
.setCancelable(false).show();
}
@Override
public void onExitSuccess(String result) {
//如果渠道有退出界面,点击渠道退出后会触发该回调用于释放游戏资源,也有可能此时程序已被kill不会执行到此处,可预留处理一些资源释放操作
//处理退出逻辑
moveTaskToBack(true);
finish();
//建议游戏按照下面代码逻辑,退出程序兼容性最好,否则可能会造成oppop、vivo等渠道退出不彻底,导致再次点击启动应用黑屏。
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
android.os.Process.killProcess(android.os.Process.myPid());
}
@Override
public void onUpdate(String data) {
//版本升级
}
};
//SDK账号回调
FastSdk.hlAccountListener = new HLAccountListener() {
@Override
public void onRefreshUser(LoginResult result) {
//小号切换,此回调中之需要游戏验证用户合法性问题,无小号可忽略
//如果游戏不支持内部切换玩家信息,游戏需要调用登出,再重新登录(不需要重新初始化)
}
@Override
public void onLoginSuccess(LoginResult result) {
}
@Override
public void onLoginFailed(String reason) {
}
@Override
public void onLogout(Object... var1) {
}
};
//SDK支付回调
FastSdk.hlPaymentListener = new HLPaymentListener() {
@Override
public void onPaySuccess(String result) {
}
@Override
public void onPayFailed(String reason) {
}
@Override
public void onQuerySuccess(List<GoodsInfo> list) {
//海外游戏必须处理,获取商品列表用于展示
}
};
//SDK分享回调
FastSdk.hlShareListener = new HLShareListener() {
@Override
public void onShareSuccess() {
}
@Override
public void onShareFailed(String reason) {
}
};
//SDK初始化,此方法需要在启动游戏时的隐私权限回调方法中调用
//后面的所有SDK功能都需要在初始化回调成功之后调用
//注意:调用onCreate之前需要将以上用到的接口先进行实例化
FastSdk.onCreate(this);
登录()
注意
- 调用此方法时确保已经执行“game_init_result”事件报送,更多具体内容请查阅 游戏自定义报送
- 初始化未收到回调或初始化失败时禁止调用登录接口
FastSdk.login();
用户中心()
//调用时机必须在登录成功之后
FastSdk.openAccountCenter(activity);
获取商品列表信息()
//调用时机,必须在确认登录成功之后使用!
//必须在登录成功之后或商品详情界面展示之前调用,注意查询成功后会通过FastSdk.hlPaymentListener接口中将所有商品信息回调回来
//注意由于商品信息获取为异步获取,如登录成功之后由于网络等原因无法获取到商品信息或获取为空,请在打开游戏商城界面时或下次支付之前增加判断再次获取
//如果始终无法获取到商品信息,请使用游戏内默认配置的商品信息展示支付,注意要和 SDK 管理台中配置的商品信息保持一致
FastSdk.queryGoodsInfo();
支付()
//调用支付之前需要先进行基础事件的报送,比如创角,进服,升级等
PayParams payParams = new PayParams();
payParams.setItemId("item60");//商品ID,必传
payParams.setItemName("60钻石");//商品名称,必传
payParams.setAmount(100);//商品金额,必传,单位:分
payParams.setNotifyUrl("");//支付回调地址,非必传,如不设置可不写
//扩展信息,回调时原样返回,因为各渠道回调参数限制不一致。
//回调参数暂时只支持长度255。callBackInfo中不要使用这些符号:“|”、“=”、“+”、“/”。
payParams.setCallbackInfo("支付扩展信息,游戏透传参数");
payParams.setCurrency("USD");//币种通过商品信息接口查询获取,必传
FastSdk.pay(activity, payParams);
数据上报()
注意(支付之前必须先进行基础数据上报)
创角,进服,升级等事件进行数据上报时,roleId,roleName,serverId,serverName参数不能为空且必传,否则会影响支付功能!!
其他必接数据请查看
//eventType取值:
//创角: EventType.CreateRole
//进服: EventType.EnterServer
//升级: EventType.LevelUp
//前三种是必须上报,下面这种根据运营需求进行自定义事件上报
//自定义点:EventType.CustomerEvent,设置自定义点位后必须设置setExtendAction("game_init"),setPhylum("14")等
PlayerInfo playerInfo = new PlayerInfo();
playerInfo.setRoleId("32424");//角色唯一标识id,必传
playerInfo.setRoleName("昵称");//必传,String
playerInfo.setRoleLevel("6");//必传,注意字符串必须是数字,比如"123"
playerInfo.setZoneId("1");//必传,没有可传默认值"1",注意字符串中的值必须为数字
playerInfo.setZoneName("华东大区");//必传,没有可传默认值,比如"1区"等
playerInfo.setServerId("1");//必传,没有可传默认值"1",注意字符串中的值必须为数字
playerInfo.setServerName("区名称");//必传,没有可传默认值,比如"1区"等
playerInfo.setBalance("66");//必传,获取不到时传""
playerInfo.setVip("5");//必传
playerInfo.setPartyname("帮派名称");//非必传
//新增内容: extra必须携带数据,参考客户端数据报送特殊数据报送
//扩展信息,格式:key:value,key:value
playerInfo.setExtra("a:arm,b:bom,gameResourceUrl:xxx,gameLoginServerUrl:xxx");
playerInfo.setClassField("");//事件结果,可不填
//playerInfo.setPhylum("");//扩展数据报送时需要按照提供的事件编号填写,如:1
//playerInfo.setExtendAction("点位名称"); //基础打点不传,自定义打点传
FastSdk.report(EventType.EnterServer, PlayerInfo playerInfo);
注意
- 需要接入CLS网络探测功能的同学注意!!!点击查看规则详情
- 该功能请在SDK初始化之后尽早报送,可以单独报送,也可以跟着其他点位一起上报
- 探测地址可以是域名或IP
- 探测地址中的冒号用@替换,避免格式错误
- 探测地址的key必须使用以下三个字段:gameResourceUrl,gameLoginServerUrl,gameServerUrl
如:playerInfo.setExtra("key:value,gameResourceUrl:http@xxx/open/init, gameServerUrl:tcp@111.222.333.6@8888");
EventType
参数名 | 描述 | 是否必填 |
---|---|---|
EventType.CreateRole | 创建角色 | 是 |
EventType.EnterServer | 游戏进服 | 是 |
EventType.LevelUp | 角色升级 | 是 |
EventType.CustomerEvent | 自定义 | 是 |
PlayerInfo
参数名 | 类型 | 描述 | 是否必填 |
---|---|---|---|
roleId | String | 角色id | 是 |
roleName | String | 角色名称 | 是 |
roleLevel | String | 等级 | 是 |
zoneId | String | 大区id,没有大区传serverId | 是 |
zoneName | String | 大区名称,没有大区传serverName | 是 |
serverId | String | 服务器id | 是 |
serverName | String | 服务器名称 | 是 |
balance | String | 余额 | 是 |
vip | String | vip等级 | 是 |
partyName | String | 公会名称 | 否 |
appVersion | String | 应用版本号 | 是 |
appResVersion | String | 游戏资源版本号 | 是 |
extendAction | String | 事件名称 | 是 |
roleCreateTime | String | 角色创建时间 | 是 |
phylum | String | 事件id,参考“客户端数据上报”文档 | 是 |
classField | String | 事件结果,ok/fail | 否 |
extra | String | 扩展信息(注意:cls报点用到该字段) | 否 |
客服唤起(选接)
FastSdk.openService(activity);
系统分享与 Facebook 分享(选接)
ShareParams params = new ShareParams();
params.setTitle("标题");
params.setContent("内容");
params.setPicPath("picPath");//本地或网络图片链接
params.setShareUrl("http://xx.com");
//FACEBOOK
params.setBmp(bmp);
FastSdk.share(ShareType.FACEBOOK, ShareType.ChildType.WX_CHAT, params);
方舟 SDK 报送接口(选接)
额外游戏数据报送,例如游戏中某些特殊关卡,数据等,如非要求接入可不接
String action = "game_xxx";
Map<String, Object> hashMap = new HashMap<>();
hashMap.put("xxx", 123);
hashMap.put("ooo", "321");
FastSdk.gameDataReport(action, hashMap);
Appsflyer(选接)
appsflyer 深度链配置,如集成其他 appsflyer 报送功能后, SDK会自动引入相关配置默认生效
<!--appsflyer 深度链接(选接,非必接),此处参数配置由运营直接在appsflyer后台查看获取,需添加到游戏入口启动类中-->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https"android:host="xxxx-brand.onelink.me"android:pathPrefix="/xxx" />
</intent-filter>
<!--appsflyer 深度链接 end-->
Firebase(选接)
仅需加入 firebase 依赖库,功能由 SDK 侧自动集成可直接使用
Aihelp(选接)
仅需加入 aihelp 依赖库,可通过客服接口唤起
Facebooklinks(选接)
导入上面的依赖库,增加回调接口监听
//_TODO:Facebook DeepLink回调,该接口选接_
_//使用时必须在初始化之前配置,如需使用该功能需要先去Facebook后台填写游戏的启动Activity,且需要在游戏入口类配置scheme启动<intent-filter>_
//具体可参考https://developers.facebook.com/docs/applinks/add-to-content
FastSdk.hlDeepLinkListener = new HLDeepLinkListener() {
@Override
public void onDeepLinkSuccess(String jsonStr) {
//返回内容可参考https://developers.facebook.com/docs/applinks/navigation-protocol?locale=zh_CN
}
};
openInstall(选接)
导入依赖进行接口监听
<meta-dataandroid:name="com.openinstall.APP_KEY"android:value="OPENINSTALL_APPKEY"/>
<!--AndroidManifest.xml 游戏主Activity-->
<activityandroid:name=".MainActivity"
android:exported="true"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="OPENINSTALL_SCHEME"/>
</intent-filter>
</activity>
注意
将 OPENINSTALL_APPKEY
替换成 openinstall 为应用分配的 appkey
,将 OPENINSTALL_SCHEME
替换为真正的 scheme 参数,此处由运营提供
用户通过 openInstall 分享且安装后打开,会在 SDK 登录成功回调 UserInfo 中 getMap 中增加两个字段 key 为 openInstall_channelCode 与 openInstall_appData 通过此处获取到相关数据进行处理相应逻辑即可
Firebase Crashlytics(选接)
1.项目根目录下build.gradle配置
plugins {
//Make sure that you have the AGP plugin 8.1+ dependency
id 'com.android.application' version '8.1.4' apply false
//...
//Make sure that you have the Google services Gradle plugin 4.4.1+ dependency
id 'com.google.gms.google-services' version '4.4.2' apply false
//Add the dependency for the Crashlytics Gradle plugin
id 'com.google.firebase.crashlytics' version '3.0.2' apply false
}
2.app模块下build.gradle配置
plugins {
id 'com.android.application'
//Make sure that you have the Google services Gradle plugin
id 'com.google.gms.google-services'
//Add the Crashlytics Gradle plugin
id 'com.google.firebase.crashlytics'
}
//引入依赖库
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
...
implementation 'com.hoolai.oversea.crash:crashlytics:1.0.0.0'
}
3.如需增加其他额外功能配置,Demo已经有示例,可参照demo接入官方文档
Catappult支付
项目根目录下build.gradle配置替换依赖implementation 'com.hoolai.oversea:hl-oversea-global:1.0.5.0'为下面依赖配置
//引入依赖库
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
//如需接入catappult支付渠道请引用下面这个依赖,注意与com.hoolai.oversea:hl-oversea-global:${version}两个依赖同时只能引入一个
implementation 'com.hoolai.oversea:hl-oversea-global-catappult:1.0.5.2'
//access-native 1.0.2.1426版本及以上版本
implementation 'com.hoolai.access.platform:access-native:0.1.2.1426.1-global'
}
Q&A
初始化失败,出现“非正版应用”提示,如何处理?
签名文件不正确,如果没有签名文件可联系运营同学。
账密登录时没有账号?
账密登录方式没有注册功能,需要运营同学提供账号/密码。
如何测试沙箱环境支付?
和运营同学确认,确保已开启沙箱环境,并确保账号已加入测试白名单。
无法拉起支付?
检查进入游戏时是否报送创角或进服事件。
支付成功不到账?
1.检查提供的支付回调url是否正确。
2.检查支付接口,在支付参数中是否调用了setNotifyUrl(url),如果调用了则会优先回调此url。
渠道包中从游戏内登出时悬浮球不隐藏
游戏未调用Fastsdk.logout(),建议游戏“设置”界面做两个按钮:“切换服务器”、“切换账号”,在执行“切换账号”时调用logout。