[!WARNING|labelVisibility:hidden|iconVisibility:hidden] 自 2026 年 8 月 31 日起:
- 新应用和应用更新必须以 Android 16(API 级别 36)或更高版本为目标平台,才能提交到 Google Play;但 Wear OS 和 Android Automotive OS 应用除外,此类应用必须以 Android 15(API 级别 35)或更高版本为目标平台,而 Android TV 和 Android XR 应用必须以 Android 14(API 级别 34)或更高版本为目标平台。
- 如果新用户的设备搭载的 Android OS 版本高于现有应用的目标 API 级别,则该应用必须以 Android 15(API 级别 35)或更高版本为目标平台,才能继续在此类设备上使用。以 Android 14(API 级别 34)或更低版本为目标平台的应用,包括以 Android 13(API 级别 33)或更低版本为目标平台的 Wear OS、Android TV 和 Android XR 应用,以及以 Android 12(API 级别 31)或更低版本为目标平台的 Android Automotive OS 应用,只能在所搭载 Android OS 版本不高于应用目标 API 级别的设备上使用。
- 如果需要更多时间来更新应用,可申请延期至 2026 年 11 月 1 日,开发者可以在 Play 管理中心内找到应用的延期表单。如需了解详情,请参阅符合 Google Play 的目标 API 级别要求。
1. 接入准备
1.1 前提条件
接入之前请确保项目满足以下要求:
- 最低 SDK 版本 23 或更高版本
- 编译 SDK 版本 36 或更高版本
- 对于 Kotlin 应用,请使用 Kotlin 版本 1.9 或更高版本
1.2 配置文件
- 获取配置文件
sf_config_gp.xml(游戏发行方提供),配置文件名称不做强制要求 - 将配置文件添加到游戏工程的应用级模块的
<project>/<app-module>/src/main/res/values目录中
2. 集成SDK
可以通过 Gradle 自动集成或手动集成。
2.1 自动集成(推荐)
在项目根目录的
settings.gradle文件中添加如下配置:dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() mavenCentral() ... maven { url 'https://maven.cnb.cool/zhiduohuyu/sdk-build/-/packages/' credentials { username 'cnb' password 'c8PhqkHaf1zli14e2yCl4h872OD' } } } }在模块级的
build.gradle文件中添加 SDK 的依赖项:dependencies { implementation fileTree(dir: 'libs', include: ['*.aar', '*.jar']) ... // Import the BoM for the Sofish platform implementation platform('com.sofish.game:game-bom:1.7.5') implementation 'com.sofish.game:game-sdk' }
2.2 手动集成
下载最新的SDK,并将 SFSDKDemo/sf-sdk/libs 目录下的 aar 文件拷贝到模块级的 libs 目录中,然后在模块的 build.gradle 文件中添加需要的第三方 SDK 依赖项:
dependencies {
api fileTree(dir: 'libs', include: ['*.aar', '*.jar'])
// Facebook
implementation 'com.facebook.android:facebook-login:18.2.3'
// Google Sign-In
implementation 'com.google.android.gms:play-services-auth:21.5.1'
implementation 'com.google.android.gms:play-services-games-v2:21.0.0'
// AppsFlyer
implementation 'com.appsflyer:af-android-sdk:6.18.0'
// ThinkingData
implementation 'cn.thinkingdata.android:ThinkingAnalyticsSDK:3.2.3'
// Google Play In-App Reviews
implementation 'com.google.android.play:review:2.0.2'
// Google Play In-App Update
implementation 'com.google.android.play:app-update:2.1.0'
// Google Play Billing
implementation 'com.android.billingclient:billing:8.3.0'
// Google Play Install Referrer
implementation 'com.android.installreferrer:installreferrer:2.2'
// Google Advertising ID
implementation 'com.google.android.gms:play-services-ads-identifier:18.3.0'
// Firebase
implementation platform('com.google.firebase:firebase-bom:34.13.0')
implementation 'com.google.firebase:firebase-analytics'
implementation 'com.google.firebase:firebase-crashlytics'
implementation 'com.google.firebase:firebase-messaging'
implementation 'com.google.firebase:firebase-config'
}
2.3 迁移到Gradle
- 删除之前添加到 libs 目录的 aar 文件
- 删除手动集成部分添加的依赖项
- 添加自动集成部分的配置和依赖项
- 其他配置文件保持不变
3. Application配置
- 如果游戏需要自定义Application, 则游戏的Application需要继承
com.sf.sdk.app.SFApplication类。 - 如果游戏不需要自定义Application,无需进行Application配置,保持默认配置即可。
4. 多语言设置(选接)
SDK目前支持的语言有:简体中文、繁体中文、英文、葡萄牙语、西班牙语、泰语、韩语。
如果应用使用的库包含语言资源(例如 AppCompat 或 Google Play 服务),则应用编译时都会包含这些库中包含的所有语言字符串。如果只想保留应用支持的语言,则可以使用
resConfig属性指定应用支持的语言,未指定的语言资源都将被移除。例如应用仅支持英语和简体中文,则需要在应用级模块的build.gradle文件中添加以下配置:android { defaultConfig { ... resConfigs "en", "zh-rCN" } }在游戏中切换语言时,如果游戏是通过Cocos/Unity开发的,在设置Cocos/Unity的语言环境时,同时还需要设置Android原生的语言环境。示例代码如下:
// 泰语 private static final Locale THAI = new Locale("th", "TH"); // 韩语 private static final Locale KOREAN = new Locale("ko", "KR"); // 英文 private static final Locale ENGLISH = new Locale("en", "US"); // 简体中文 private static final Locale CHINESE_SIMPLIFIED = new Locale("zh", "CN"); // 繁体中文(台湾) private static final Locale CHINESE_TRADITIONAL = new Locale("zh", "TW"); // 切换语言 SFPlatform.getInstance().switchLanguage(activity, locale);
5. 应用清单配置说明
5.1 冷启动优化
为了缓解游戏冷启动时CPU负载过高和GAID锁竞争问题,可以禁用部分第三方SDK的自动初始化功能,需要在项目应用级模块的 <project>/<app-module>/src/main/AndroidManifest.xml 文件中添加以下配置:
<!--Firebase-->
<provider
android:name="com.google.firebase.provider.FirebaseInitProvider"
android:authorities="${applicationId}.firebaseinitprovider"
android:exported="false"
tools:node="remove" />
<!--Facebook-->
<provider
android:name="com.facebook.internal.FacebookInitProvider"
android:authorities="${applicationId}.FacebookInitProvider"
android:exported="false"
tools:node="remove" />
<!--Google Play Games-->
<provider
android:name="com.google.android.gms.games.provider.PlayGamesInitProvider"
android:authorities="${applicationId}.playgamesinitprovider"
android:exported="false"
tools:node="remove" />
5.2 ContentProvider优化(选接)
接入其他第三方SDK或广告SDK时,会引入第三方SDK在AndroidManifest.xml注册的ContentProvider,注册过多的ContentProvider会拖慢应用冷启动的速度,有阻塞主线程导致ARN的风险。为了解决这个问题,SDK内部可以通过配置延迟加载ContentProvider的初始化,减少冷启动的时间,降低冷启动的资源争抢和 ANR 风险。如果游戏没有冷启动用户流失占比较高的问题,可以忽略该部分内容。
延迟加载ContentProvider可以通过以下步骤完成:
找出需要延迟加载的
ContentProvider,在AndroidManifest.xml文件中通过在<provider>标签中添加android:enabled="false"属性禁用该ContentProvider。代码示例如下:<provider android:name="com.google.android.gms.ads.MobileAdsInitProvider" android:authorities="com.sofish.watersort.gp.mobileadsinitprovider" android:enabled="false" android:exported="false" android:initOrder="100" /> <provider android:name="com.applovin.sdk.AppLovinInitProvider" android:authorities="com.sofish.watersort.gp.applovininitprovider" android:enabled="false" android:exported="false" android:initOrder="101" /> <provider android:name="com.squareup.picasso.PicassoProvider" android:authorities="com.sofish.watersort.gp.com.squareup.picasso" android:enabled="false" android:exported="false" /> <provider android:name="sg.bigo.ads.controller.provider.BigoAdsProvider" android:authorities="com.sofish.watersort.gp.BigoAdsProvider" android:enabled="false" android:exported="false" /> <provider android:name="com.mbridge.msdk.config.component.status.MBComponentLifecycleProvider" android:authorities="com.sofish.watersort.gp.mbcomponentlifcycleprovider" android:enabled="false" android:exported="false" />在
sf_config_gp.xml文件或者<project>/<app-module>/src/main/res/values目录下的其他资源文件中添加以下2项配置:<bool name="sf_allow_manual_disabled_provider">true</bool> <string-array name="sf_disabled_provider_names"> <item>com.google.android.gms.ads.MobileAdsInitProvider</item> <item>com.applovin.sdk.AppLovinInitProvider</item> <item>com.squareup.picasso.PicassoProvider</item> <item>sg.bigo.ads.controller.provider.BigoAdsProvider</item> <item>com.mbridge.msdk.config.component.status.MBComponentLifecycleProvider</item> </string-array>
[!TIP|labelVisibility:hidden|iconVisibility:hidden] 注意:
sf_allow_manual_disabled_provider为true时,sf_disabled_provider_names为上面禁用的需要延迟初始化的ContentProvider,这2条属性需要同时存在延迟初始化才会生效。
<provider>标签中有以下几种情况的不适合延迟初始化,保持原来的配置不变:
android:exported="true"表示跨进程访问android:process表示独立进程属性android:permission表示具有特定权限保护FileProvider 及其子类表示资源分发,同时带有android:grantUriPermissions="true"属性和android.support.FILE_PROVIDER_PATHS的meta-data属性。
5.3 变现说明(选接)
如果游戏需要接入 Facebook插屏广告,需要在项目应用级模块的 <project>/<app-module>/src/main/AndroidManifest.xml 文件中添加以下配置:
<activity
android:name="com.facebook.CustomTabActivity"
android:exported="true"
tools:node="merge"
tools:replace="android:exported" />
[!WARNING|labelVisibility:hidden|iconVisibility:hidden] 在SDK中
android:exported的值为false,如果设置为true,com.facebook.CustomTabActivity可能会导致游戏无法正常加载。如果需要修改android:exported的值请和游戏发行方确认!
6. 方法调用说明
[!WARNING] 所有方法调用,都必须通过
com.sf.sdk.SFPlatform类在UI线程中调用!!!
7. 初始化(必接)
7.1 调试模式
SFPlatform.getInstance().setDebugMode(true); // 正式发布时建议设置为false
7.2 SDK初始化
SDK初始化方法建议在游戏启动的Activity#onCreate()方法中调用,如果游戏包含热更新功能,则建议在不需要热更新时/完成热更新之后调用,代码示例如下:
SFPlatform.getInstance().init(activity, new SFSDKListener() {
@Override
public void onInitSuccess() {
// 初始化成功回调
}
@Override
public void onInitFailed(int code, String message) {
// 初始化失败回调
}
@Override
public void onLoginSuccess(SFUser user) {
// 登录成功回调,游戏需要刷新当前用户信息
}
@Override
public void onLoginSuccessWaitForNetwork(SFUser user) {
// 登录成功回调(触发登录操作时网络不可用,网络恢复时自动登录),游戏根据具体情况处理当前用户信息
}
@Override
public void onLoginFailed(int code, String message) {
// 登录失败回调
}
@Override
public void onLinkSuccess(SFUser user) {
// 账号绑定成功回调
}
@Override
public void onLinkFailed(int code, String message) {
// 账号绑定失败回调
}
@Override
public void onPaymentSuccess(SFOrder order) {
// 支付成功回调(不依赖服务端通知的可以直接进行发货)
}
@Override
public void onPaymentFailed(int code, String message) {
// 支付失败回调
}
@Override
public void onRestoreSuccess(List<SFOrderRecord> success, List<SFOrderRecord> failure) {
// 恢复购买成功回调(success表示恢复成功的购买,failure表示恢复失败的购买)
}
@Override
public void onRestoreFailed(int code, String message) {
// 恢复购买失败回调(表示恢复购买操作未成功处理)
}
@Override
public void onExitGame() {
// 退出游戏回调
}
@Override
public void onLogout() {
// 退出登录回调,游戏需要清除已登录的用户信息
}
@Override
public void onDeleted() {
// 账号注销回调,在玩家成功提交账号注销申请时回调
}
});
SFUser数据结构如下:
| 参数名称 | 参数类型 | 是否可为空 | 说明 |
|---|---|---|---|
| uid | String | 否 | 用户 ID |
| name | String | 否 | 用户名 |
| loginName | String | 是 | 用户登录名(昵称) |
| token | String | 否 | 用户登录令牌 |
| expiredTime | long | 否 | 用户登录令牌有效期(秒) |
| registerTime | long | 否 | 用户注册时间(时间戳) |
| accountType | Boolean | 否 | 当前登录账号类型 |
| newAccount | String | 否 | 是否为新用户 |