XDSDK v7 Android 快速接入指南
· 阅读需 5 分钟
环境要求
- 最低支持 Android API Level 21(Android 5.0)。
- 使用 AndroidX。
配置
获取 SDK
- 请联系平台同事获取最新的 SDK 压缩包,解压后根据需要选择对应的 aar 导入到项目中。
- 压缩包分为
XDSDK、ThirdPartyLibrary、ADs三部分,按照添加依赖描述部分进行选择导入。
添加依赖
在项目 build.gradle 中添加 SDK 依赖:
XDSDK 目录
- XDGCommon_latest.aar(基础库,必须)
- XDGAccount_latest.aar(登录)
- XDThirdLoginCN_latest.aar(国内第三方登录支持库)
- XDGThirdLogin_latest.aar(海外第三方登录支持库)
- XDGPayment_latest.aar(支付)
- XDGPaymentUPPay_latest.aar(国内云闪付支付支持库)
- XDGTapTapWrapperInternal_latest.aar(内部封装 TapSDK 支持库)
- XDGTapTapWrapper_latest.aar(TapSDK 额外支持库)
- XDGAnnouncement_latest.aar(公告)
ThirdPartyLibrary 目录
- ThemisLite-release1.0.7.8.aar(基础库支持,必须)
- oaid_sdk_xxx.aar(信通院 SDK)
在项目级 build.gradle(.kts) 中 添加远程依赖:
// 基础库依赖
implementation("io.reactivex.rxjava2:rxandroid:2.1.1")
implementation("androidx.appcompat:appcompat:1.3.1")
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:adapter-rxjava2:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.7.2")
implementation("com.squareup.okio:okio:2.6.0")
implementation("androidx.recyclerview:recyclerview:1.2.1")
implementation("com.google.code.gson:gson:2.8.6")
implementation("androidx.localbroadcastmanager:localbroadcastmanager:1.0.0")
//XDSDK 依赖的 TapSDK 库
implementation("com.taptap.sdk:tap-core:4.9.0")
implementation("com.taptap.sdk:tap-login:4.9.0")
implementation("com.taptap.sdk:tap-compliance:4.9.0") // 国内防沉迷
// 支持的额外的 TapSDK 库
implementation("com.taptap.sdk:tap-moment:4.9.0")
implementation("com.taptap.sdk:tap-review:4.9.0")
implementation("com.taptap.sdk:tap-license:4.9.0")
implementation("com.taptap.sdk:tap-update:4.9.0")
// Google Advertising ID
implementation("com.google.android.gms:play-services-ads-identifier:18.0.1")
// 支付宝支付
implementation("com.alipay.sdk:alipaysdk-android:15.8.32@aar")
// 微信支付(同微信分享)
implementation("com.tencent.mm.opensdk:wechat-sdk-android:6.8.0")
// 海外支付支持库
implementation("androidx.browser:browser:1.4.0")
备注
具体使用哪些模块以及版本号请和平台同事确认。
参数文件
将给到的参数配置文件名改为 XDConfig.json,放到 app/src/main/assets/ 目录下。
备注
如果使用 Google 登录或 Firebase 埋点,请在 Firebase 后台下载 google-services.json 并添加到 app/ 目录下。
AndroidManifest.xml 配置
海外网页支付
提示
URL Scheme 组成规则:xd + xd_client_id,其中 xd_client_id 为全小写。 eg. : 你的 XD Client ID 为:hn5RcJei2JxCYlS0,在 AndroidManifest.xml 文件中添加的格式为 <data android:scheme="xdhn5rcjei2jxcyls0" />
<activity
android:name="com.xd.intl.payment.ui.SchemeCCTActivity"
android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation"
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:host="xdcctwebpay"
android:scheme="xd{your_xd_client_id}}"/>
</intent-filter>
</activity>
初始化
初始化 SDK
- 请将初始化代码放在尽可能靠前的位置,在初始化成功前请不要绘制登录相关的界面。
- 如果初始化失败一般为配置问题,请根据错误信息检查配置是否正确或者咨询平台。
- 初始化成功前大部分接口都不可使用。
// MainActivity.java
import com.xd.sdk.common.XDGCommon;
import com.xd.sdk.common.base.Lang;
import com.xd.sdk.common.callback.XDGInitCallback;
import com.xd.sdk.common.data.model.InitParams;
import com.xd.sdk.common.data.model.PackageType;
import org.json.JSONObject;
// ...
private void init() {
InitParams initParams = InitParams.newBuilder()
.setPackageType(PackageType.GooglePlay) // 默认: PackageType.Normal
.setLanguage(Lang.EN) // 初始化语言
.setChannelName("GooglePlay") // 初始化渠道,默认为空,SDK 内部会按照读取顺序获取渠道顺序,这里是保留字段,在非广告渠道的自定义。读取广告包配置(仅国内) -> this -> XDConfig.json 配置
.setDBProperties(new JSONObject().put("custom_key", "custom_value")) // db 参数可透传给 TapDB 的 device_login/user_login 事件
.build();
XDGCommon.initSDK(MainActivity.this, initParams, new XDGInitCallback() {
@Override
public void initCallback(boolean success, String message) {
if (success) {
// Success
} else {
// Failure
Log.e("MainActivity", "XDSDK Init failed: " + message);
}
}
});
}
修改多语言
在初始化后可根据需要修改 SDK 语言。
// MainActivity.java
import com.xd.sdk.common.XDGCommon;
import com.xd.sdk.common.base.Lang;
// ...
private void setLanguage() {
XDGCommon.setLanguage(Lang.ZH_CN);
}
通用
事件上报
// MainActivity.java
import com.xd.sdk.common.XDGCommon;
import java.util.HashMap;
import java.util.Map;
// ...
private void trackEvent() {
XDGCommon.trackEvent("自定义事件名称");
Map<String, Object> params = new HashMap<>();
params.put("key", "value");
XDGCommon.trackEvent("自定义带参数的事件名称", params);
}
商店评价
商店评价仅支持 Google Play 平台。
// MainActivity.java
import com.xd.sdk.common.XDGCommon;
// ...
private void storeReview() {
XDGCommon.storeReview(MainActivity.this);
}
打开网页
// PaymentActivity.java
import com.xd.sdk.common.XDGCommon;
import com.xd.sdk.common.callback.WebActionCallback;
import com.xd.sdk.common.entities.WebActionType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
// ...
private void openWebPage() {
String activityUrl = "https://www.xindong.com";
XDGCommon.openWebPage(PaymentActivity.this, activityUrl, new WebActionCallback() {
@Override
public void onAction(int type, @Nullable Map<@NotNull String, ?> data) {
if (type == WebActionType.CLOSE) {
// 网页关闭
} else if (type == WebActionType.MESSAGE) {
// 网页透传信息
if (data != null) {
Object value = data.get("key");
}
}
}
});
}
登录
- 在初始化成功后可以进入登录页面但暂时先不要绘制登录按钮,先设置好用户状态回调并调用自动登录,如果自动登录失败再绘制登录按钮。
- 登录按钮点击后调用手动登录接口,需要传入对应的登录类型。登录失败后需要继续展示登录按钮让用户重新登录。
- 自动登录在每次打开游戏时只能触发一次,失败后只能调用手动登录接口。
- 收到用户退出登录的回调时需要回到登录页面并展示登录按钮。此时不要再调用自动登录接口。
状态回调
- 需要在初始化前设置好
// MainActivity.java
import com.xd.sdk.account.XDGAccount;
import com.xd.sdk.common.callback.XDGUserStatusChangeCallback;
import org.jetbrains.annotations.Nullable;
// ...
private void addUserStatusChangeCallback() {
XDGAccount.addUserStatusChangeCallback(new XDGUserStatusChangeCallback() {
@Override
public void userStatusChange(int code, @Nullable String message) {
if (code == XDGUserStatusChangeCallback.UserStatus.LOGOUT) {
// 退出登录,回到登录页面,展示登录按钮
} else if (code == XDGUserStatusChangeCallback.UserStatus.BIND) {
// 绑定成功,没有更多登录方式可不处理
} else if (code == XDGUserStatusChangeCallback.UserStatus.UNBIND) {
// 解绑成功,没有更多登录方式可不处理
} else if (code == XDGUserStatusChangeCallback.UserStatus.PROTOCOL_AGREED_AFTER_LOGOUT) {
// 退出登录后同意协议,可不处理
} else if (code == XDGUserStatusChangeCallback.UserStatus.CUSTOMER_NO_UNREAD_MESSAGE) {
// 客服有未读消息,未开通服务可以不处理
} else if (code == XDGUserStatusChangeCallback.UserStatus.CUSTOMER_HAS_UNREAD_MESSAGE) {
// 客服没有未读消息,未开通服务可以不处理
} else {
// 未知 Code,不需要处理
}
}
});
}
发起登录
// LoginActivity.java
import android.util.Log;
import com.xd.sdk.account.XDGAccount;
import com.xd.sdk.common.base.XDGError;
import com.xd.sdk.common.bean.XDGUser;
import com.xd.sdk.common.callback.Callback;
import com.xd.sdk.common.entities.LoginEntryType;
import java.util.Map;
// ...
/**
* 登录
*
* LoginEntryType 枚举:
* LoginEntryType.DEFAULT - 自动登录
* LoginEntryType.TAP_TAP - TapTap 登录
* LoginEntryType.APPLE - Apple 登录
* LoginEntryType.GOOGLE - Google 登录
* LoginEntryType.FACEBOOK - Facebook 登录
* LoginEntryType.LINE - LINE 登录
* LoginEntryType.TWITTER - Twitter 登录
* LoginEntryType.STEAM - Steam 登录
* LoginEntryType.GUEST - 游客登录
* LoginEntryType.PHONE - 手机号登录
* LoginEntryType.EMAIL - 邮箱登录
*/
private void loginByType() {
XDGAccount.loginByType(LoginActivity.this, LoginEntryType.TAP_TAP, new Callback<XDGUser>() {
@Override
public void onCallback(XDGUser xdgUser, XDGError xdgError) {
if (xdgUser != null) {
// 登录成功
String userId = xdgUser.getId(); // 用户在 XD 账户系统的 XD User ID(用户唯一标识)
String avatarUrl = xdgUser.getAvatar();
String nickname = xdgUser.getNickName();
return;
}
// 登录失败
if (xdgError != null) {
int code = xdgError.getCode();
String message = xdgError.getMessage();
Log.e("LoginActivity", "XDSDK loginFailed, code=" + code + ", message: " + message);
Map<String, Object> errorDataMap = xdgError.getErrorDataMap();
if (errorDataMap != null) {
// ...
}
}
}
});
}
用户中心
// LoginActivity.java
import com.xd.sdk.account.XDGAccount;
// ...
private void openUserCenter() {
XDGAccount.openUserCenter(LoginActivity.this);
}
退出登录
// LoginActivity.java
import com.xd.sdk.account.XDGAccount;
// ...
private void logout() {
XDGAccount.logout(LoginActivity.this);
}
账号注销
// LoginActivity.java
import com.xd.sdk.account.XDGAccount;
// ...
private void openAccountDeletion() {
XDGAccount.openAccountDeletion(LoginActivity.this);
}
打开客服
// MainActivity.java
import com.xd.sdk.account.XDGAccount;
import com.xd.sdk.common.entities.RoleInfo;
import java.util.HashMap;
import java.util.Map;
// ...
private void openCustomerService() {
RoleInfo roleInfo = RoleInfo.newBuilder()
.setRoleId("game_role_id") // 必填
.setRoleName("game_role_name") // 必填
.setRoleLevel(100)// 必填
.setServerId("game_server_id") // 必填
.setExtra("extra_info")
.build();
String path = ""; // 客服内的相对路径,一般留空即可
Map<String, Object> extrasMap = new HashMap<>();
extrasMap.put("key", "value");
XDGAccount.openCustomerService(MainActivity.this, roleInfo, path, extrasMap);
}
个人信息页
仅限国内可使用
// LoginActivity.java
import com.xd.sdk.account.XDGAccount;
import com.xd.sdk.common.entities.RoleInfo;
// ...
private void openUserDashboard() {
RoleInfo roleInfo = RoleInfo.newBuilder()
.setRoleId("game_role_id") // 必填
.setRoleName("game_role_name") // 必填
.setRoleLevel(100)// 必填
.setServerId("game_server_id") // 必填
.setExtra("extra_info")
.build();
XDGAccount.openUserDashboard(LoginActivity.this, roleInfo);
}
内购
查询商品价格
- 在查询商品价格前请在后台配置好对应的商品信息。
- 当
XDConfig.json配置的regionType为Global且初始化参数指定的packageType为PackageType.GooglePlay时查询的是 Google 的商品。 - 其他情况查询的是在平台配置的商品。
// PaymentActivity.java
import com.xd.sdk.common.base.XDGError;
import com.xd.sdk.payment.XDGPayment;
import com.xd.sdk.payment.callback.PaymentResultCallback;
import com.xd.sdk.payment.entities.XDGProductInfo;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
import java.util.List;
// ...
private void queryProducts() {
// 当 XDConfig.json 配置的 regionType 为 Global 且初始化参数指定的 packageType 为 PackageType.GooglePlay 时查询的是 Google 的商品;
// 其他情况查询的是在平台配置的商品
List<String> productIdList = new ArrayList<>();
productIdList.add("product_id_1");
XDGPayment.queryWithProductIds(productIdList, new PaymentResultCallback<List<XDGProductInfo>>() {
@Override
public void onSuccess(@NotNull List<XDGProductInfo> xdgProductInfos) {
if (xdgProductInfos.isEmpty()) {
// 查询商品为空
} else {
// 查询成功
for (XDGProductInfo info : xdgProductInfos) {
String productId = info.getProductId();
String displayPrice = info.getDisplayPrice();
String title = info.getTitle();
String description = info.getDescription();
}
}
}
@Override
public void onError(@NotNull XDGError xdgError) {
}
});
}
发起内购
// PaymentActivity.java
import android.util.Log;
import com.xd.sdk.common.base.XDGError;
import com.xd.sdk.payment.XDGPayment;
import com.xd.sdk.payment.api.XDGPaymentParams;
import com.xd.sdk.payment.callback.PaymentResultCallback;
import com.xd.sdk.payment.entities.XDGOrderInfo;
import org.jetbrains.annotations.NotNull;
// ...
private void payWithParams() {
// 当 XDConfig.json 配置的 regionType 为 CN 发起的是国内支付宝&微信支付;
// regionType 为 Global 时:
// - 初始化参数指定的 packageType 为 PackageType.GooglePlay 时发起的是 Google 结算库购买
// - 其他,发起网页支付
XDGPaymentParams params = XDGPaymentParams.newBuilder()
.setGameOrderId("game_order_id") // 订单 ID
.setProductId("product_id") // 商品 ID
.setRoleId("game_role_id") // 角色 ID
.setServerId("game_server_id") // 服务器 ID
.setExt("extra_info") // 附加信息
.build();
XDGPayment.payWithParams(PaymentActivity.this, params, new PaymentResultCallback<XDGOrderInfo>() {
@Override
public void onSuccess(@NotNull XDGOrderInfo xdgOrderInfo) {
// 支付成功
Log.i("PaymentActivity", "支付订单数据: " + xdgOrderInfo);
}
@Override
public void onError(@NotNull XDGError xdgError) {
// 支付失败
int code = xdgError.getCode();
String message = xdgError.getMessage();
}
});
}
公告
展示公告
展示公告 UI,由 SDK 处理公告的获取和展示。可以在公告后台进行样式自定义。
// AnnouncementActivity.java
import com.xd.sdk.announcement.XDGAnnouncement;
import com.xd.sdk.announcement.domain.model.AnnouncementConfig;
import com.xd.sdk.common.callback.WebActionCallback;
import com.xd.sdk.common.entities.WebActionType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import java.util.Map;
// ...
private void openPage() {
AnnouncementConfig config = AnnouncementConfig.newBuilder()
.setServerCode("server_code") // 公告后台配置服务器后生成的代码
.setChannel("tap") // 渠道标识
.build();
XDGAnnouncement.openPage(AnnouncementActivity.this, config, new WebActionCallback() {
@Override
public void onAction(int type, @Nullable Map<@NotNull String, ?> data) {
if (type == WebActionType.CLOSE) {
// 页面关闭
} else if (type == WebActionType.MESSAGE) {
// 页面消息
if (data != null) {
Object value = data.get("key");
}
}
}
});
}
检查未读公告
检查是否有未读公告,请不要频繁调用该接口,可能影响性能。
// AnnouncementActivity.java
import com.xd.sdk.announcement.XDGAnnouncement;
import com.xd.sdk.announcement.domain.model.AnnouncementConfig;
import com.xd.sdk.common.base.XDGError;
import com.xd.sdk.common.callback.Callback;
// ...
private void requestUnread() {
AnnouncementConfig config = AnnouncementConfig.newBuilder()
.setServerCode("server_code") // 公告后台配置服务器后生成的代码
.setChannel("tap") // 渠道标识
.build();
XDGAnnouncement.requestUnread(ADsActivity.this, config, new Callback<Boolean>() {
@Override
public void onCallback(Boolean aBoolean, XDGError xdgError) {
if (aBoolean) {
// 有未读公告
} else {
// 无未读公告
}
}
});
}
TapSDK 相关内容
请参考 TapSDK 接入文档的使用方式,将方法调用类改为 XDSDK 封装类,以云存档为例:
// TapSDKActivity.java
import androidx.annotation.NonNull;
import com.taptap.sdk.cloudsave.ArchiveData;
import com.taptap.sdk.cloudsave.ArchiveMetadata;
import com.taptap.sdk.cloudsave.internal.TapCloudSaveRequestCallback;
//...
private void createArchive() {
ArchiveMetadata metadata = new ArchiveMetadata.Builder()
.setName("")
.setSummary("")
.setExtra("")
.setPlaytime(0)
.build();
// 存档文件路径(单个存档文件大小不超过10MB)
String archiveFilePath = "path/to/archive/file";
// 存档封面路径(可选,封面大小不超过512KB)
String archiveCoverPath = "path/to/cover/image";
// 请求回调
TapCloudSaveRequestCallback callback = new TapCloudSaveRequestCallback() {
@Override
public void onRequestError(int errorCode, @NonNull String errorMessage) {
// 处理请求错误
}
@Override
public void onArchiveCreated(@NonNull ArchiveData archive) {
// 处理存档创建成功
}
};
XDTapCloudSave.createArchive(metadata, archiveFilePath, archiveCoverPath, callback);
}
XDSDK 封装的 TapSDK 类包括: