客户端接入指南


本文档面向 Android 开发者,描述的接入方式适合运营在 4399 平台的联机游戏。

SDK版本 变更时间 变更内容
v3.2.0 2022.03.03 OperateCenterConfig 重命名为 OperateConfig
绑定手机/检查用户绑定手机接口变更:
  • 回调OpeResultListener接口
  • 状态码及其说明见接入示例
充值回调code,改成通用code,参考文档最后一部分
v3.3.0 2022.03.29 -(表示接口、接入方式不变,以下省略说明)
v3.3.2 2022.04.20 -
v3.3.3 2022.05.25 -
v3.3.4 2022.06.06 -
v3.4.0 2022.07.01 接口不变,aar接入方式不变
jar+res 接入方式,由于第三方SDK 更新的原因需要:
  • 添加渠道方 GenLoginAuthActivity
  • 更新渠道方 jar, so 包,建议重新替换 libs 目录
  • 联通渠道 assets/uniaccount_core.dat 文件可删除

SDK 说明

用户信息与隐私策略

SDK 中使用的用户信息及隐私政策参考:《4399通行证用户服务协议》《隐私政策》

功能描述

4399 运营 SDK(以下简称 SDK),为接入的游戏提供4399账户登录、充值、更新、游戏内容展示等功能。

SDK 组成

客户端 SDK

SDK 优先提供在线aar依赖方式,其 Demo 结构遵循 Android Studio(as) 规范,但仍然保留了 jar+res 的依赖方式。
SDK 支持的编译配置 android:minSdkVersion >= 16

服务端 API

需要充值功能、登录服务端校验,参考 SDK 服务端接入文档

集成流程

准备

首次接入 SDK,要在 4399 开放平台 注册应用,主要是提交APK、素材,配置游戏币、充值回调地址等信息。
完成后,开发者将得到 SDK 的基础参数:game keyGameKey,游戏在 4399 平台的运营标识

引入依赖

根据游戏需要,以下三种方式可选其一

repositories {
    maven {
        // 4399 SDK 开放仓库:正式
        url 'https://mvn.4399doc.com/repository/maven-releases'
    }
    maven {
        // 4399 SDK 开放仓库:快照
        url 'https://mvn.4399doc.com/repository/maven-snapshots'
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar', '*.aar'])
    
    // 运营 SDK:建议使用最新版本,可通过浏览仓库地址或向运营咨询版本
    implementation "cn.m4399.sdk:operate:3.5.0"
    
    // volley 和 support 是 SDK 使用的外部依赖,若接入方已有,可忽略
    implementation 'com.android.volley:volley:1.2.0'
    //noinspection GradleCompatible
    implementation "com.android.support:support-v4:28.0.0"
}

注意:若使用7.0+版本的 gradle 及 android build 插件,仓库地址应配置在settings.gradle

operate/libs/volley-v1.2.0.jar
operate/libs/support-v13-23.2.1.jar

Gradle 文件中注意添加本地依赖

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar','*.aar'])
}

abi 适配与 so 库

若游戏不需要支持所有 abi ,可以按需选用。
aar依赖方式,按以下方式配置需要的abijar+res依赖方式需要手动删除不需要abi目录

android {
    defaultConfig {
        ndk {
            // 根据游戏需要选择
            abiFilters "armeabi", "armeabi-v7a", "x86", "arm64-v8a"
        }
    }
}

接口调用:初始化(必须)

SDK 初始化后才能正确调用其他接口,建议在游戏主 Activity 的开始处如 onCreate方法中进行。

private void initSDK() {
    mOpeCenter = OperateCenter.getInstance();

    OperateConfig config = new OperateConfig.Builder(MainActivity.this)
        // 设置调试模式,可选,默认false, 发布前应设置为false或删除调用
        .setDebugEnabled(false)
        // 设置游戏运营 key,必须
        .setGameKey(GAME_KEY)
        // 设置 SDK 页面方向,必须,应与游戏方向一致,可取值见下文说明
        .setOrientation(GAME_ORIENTATION)
        // 设置悬浮窗风格,可选,悬浮窗更多信息参考下文
        .setPopLogoStyle(PopLogoStyle.POPLOGOSTYLE_FOUR)
        // 设置悬浮窗初始位置,可选,有四种,分别在屏幕上下左右
        .setPopWinPosition(PopWinPosition.POS_LEFT)
        // 设置游戏充值是否支持超出金额,可选,true支持,默认false
        .setSupportExcess(GAME_SUPPORT_EXCESS)
        // 设置是否在 Android 9.+系统上兼容全面屏,true兼容,默认false
        .compatNotch(GAME_COMPACT_NOTCH)
        .build();
        mOpeCenter.setConfig(config);

    // 注意:初始化完成后,其他接口才可用        
    mOpeCenter.init(MainActivity.this, new OperateCenter.OnInitGlobalListener() {
        /*
         * 初始化互调
         * 只有在init之后, isLogin()返回的状态才可靠
         */
        @Override
        public void onInitFinished(boolean isLogin, User userInfo) {
            // 初始化后处理
        }
            
        /*
         * 注销帐号的回调
         * @param fromUserCenter 标识区分是否从个人中心中注销的,若是则为true,不是为false
         */
        @Override
        public void onUserAccountLogout(boolean fromUserCenter) {
                // 用户登出,游戏应回到自身登录页面
        }
        
        /*
         * 切换账号回调
         */
        @Override
        public void onSwitchUserAccountFinished(boolean fromUserCenter, User userInfo) {
                // 用户切换,游戏应回到选服页面
        }
    });
}

初始化的几点说明

页面方向

  <!-- 游戏 Activity 配置建议:
       应该使用 android:configChanges="orientation|screenSize|keyboardHidden"
       不应该使用 android:launchMode="singleTask" 启动模式,可以考虑 singleTop
  -->
方向参数 含义
SCREEN_ORIENTATION_LANDSCAPEint, 0 横屏
SCREEN_ORIENTATION_PORTRAIT, int, 1 竖屏
SCREEN_ORIENTATION_SENSOR_LANDSCAPEint, 6 横屏,可180度旋转
SCREEN_ORIENTATION_SENSOR_PORTRAITint, 7 竖屏
<!-- 
    4399 SDK:SDK 中除了以'cn.m4399.'开头的 Activity 都是第三方页面,
        假设游戏为横屏,需要锁定它们的方向为横屏,可以设置 android:screenOrientation,
        此设置应与初始化接口中设置的值保持对应,且若编译有错误,可以进一步设置‘tools:replace’
 -->
<activity 
        android:name="com.cmic.gen.sdk.view.GenLoginAuthActivity"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:launchMode="singleTop"
        android:screenOrientation="landscape"
        android:theme="@style/AppTheme.NoActionBar"
        tools:replace="android:theme, android:screenOrientation" />

悬浮窗

悬浮窗会在用户登录后附着在游戏页面上层,点击后打开对页面展示个人信息、设置,和游戏论坛、官网等入口。

极少数游戏登录 Activity 并不是游戏主 Activity ,则悬浮窗可能发生异常,建议游戏做相应调整

样式类型 图示
PopLogoStyle.POPLOGOSTYLE_ONE(默认) image
PopLogoStyle.POPLOGOSTYLE_TWO image
PopLogoStyle.POPLOGOSTYLE_THREE image
PopLogoStyle.POPLOGOSTYLE_FOUR image
样式类型 位置
PopWinPosition.POS_LEFT(默认) 屏幕左侧
PopWinPosition.POS_RIGHT 屏幕右侧
PopWinPosition.POS_TOP 屏幕上侧
PopWinPosition.POS_BOTTOM 屏幕下侧

接口调用:账号相关

账号登录(必须)

需要登录时调用此接口,如果 SDK 已存在有效登录状态,则直接回调,否则将打开登录页面登录。

mOpeCenter.login(MainActivity.this, new OnLoginFinishedListener() {
    @Override
    public void onLoginFinished(boolean success, int resultCode, User user) {
        // 登录结束后的游戏逻辑
    }
});

在登录成功回调的用户信息,即User对象(参考 API 详情),包含state字段,此值可用于游戏服务端进行 用户信息二次验证

查询是否有已登录账号

boolean isLogin = mOpeCenter.isLogin();

获取当前登录帐号信息

在 SDK 处于登录状态时,可通过该接口获取当前用户的信息。
注意:User 中的uid是 32 位整数字符串;若要转换为数值,注意溢出的可能性

User user = mOpeCenter.getCurrentAccount();

设置角色服务器 id

若游戏有区服,则应在角色进入分服时,通过以下接口设置所在服的 id。 服务器 id 为不超过10位的数字字符串

mOpeCenter.setServer(SERVER_ID);

账号切换(推荐)

当需要切换账号时调用

mOpeCenter.switchAccount(MainActivity.this, new OnLoginFinishedListener() {
    @Override
    public void onLoginFinished(boolean success, int resultCode, User userInfo) {
        //用户账号切换结束后的游戏逻辑
    }
});

有时账号切换是由于 SDK 内部发起的,切换成功后 SDK 调用OnInitGlobalListener.onSwitchUserAccountFinished()通知游戏

账号登出(推荐)

当需要登出账号时调用,SDK 立即清除本地用户状态、通知服务端,并调用OnInitGlobalListener.onUserAccountLogout()通知游戏

mOpeCenter.logout();

接口调用:充值(推荐)

关于超出金额模式(超额)
由于卡类等充值渠道有金额限制,可能出现充值金额无法匹配任何金额的情况;
如果游戏能处理超出传入金额 部分的货币,即将多余部分兑换为游戏币发放给用户,则可以设置true
否则,应设置为false或不设置,SDK将直接隐藏无匹配金额的充值渠道。

/*
 * 充值,直接传递参数,旧版接口
 *
 * money, 充值金额,整型,单位元,1 ~ 50000,必须
 * mark, 游戏方订单,必须,
 *      支持大小写字母、数字、'|'(竖线)、'-'(中划线)、'_'(下划线),最长32位,不可为空,不可重复
 * commodity, 商品名,可选,不传时认为商品名是游戏币
 */
mOpeCenter.recharge(MainActivity.this, money, mark, commodity, new OnRechargeFinishedListener() {
    /* 充值操作结果 */
    @Override
    public void onRechargeFinished(boolean success, int resultCode, String msg) {
        if (success) {
            // 充值操作成功,根据服务端回调决定是否道具
            // 注意:操作成功包含了订单成功、订单处理中两种情况
        } else {
            // 充值失败逻辑,resultCode查看文档结尾
        }
    }
});

/*
 * 充值,使用订单类,新版接口
 *
 * 与直接传递参数几乎一样,只是可以对单笔订单设置是否支持超出金额
 */
mOpeCenter.recharge(MainActivity.this,
    // 充值金额,整数,单位元
    new Order(money, mark)
        // 是否支持超出金额,默认不支持
        .supportExcess(false)
        // 商品名,可选,不传时认为商品名是游戏币
        .commodity(COMMODITY_NAME),
    new OperateCenter.OnRechargeFinishedListener() {
    @Override
    public void onRechargeFinished(boolean success, int resultCode, String msg) {
        
    }
});

接口调用:绑定手机

绑定

/*
 * 绑定手机
 */
mOpeCenter.bindPhone(this, new OpeResultListener() {
    /*
     * resultCode:0、绑定成功;1、取消绑定;2、已绑定;3、网络异常或服务器异常;
     * message:状态说明
     */
    @Override
    public void onResult(int code, @Nullable String message) { 
    }
});

检查绑定状态

/*
 * 检查用户绑定手机的状态
 */
mOpeCenter.checkBindPhoneState(new OpeResultListener() {
    /*
     * resultCode: 0、未绑定手机号;2、已绑定手机号;3、网络异常或服务器异常;6 、账号被踢
     * message:状态说明
     */
    @Override
    public void onResult(int code, @Nullable String message) { 
    }
});

接口调用:其他

退出游戏(必须)

当用户按“返回键”或者点击游戏内“退出游戏”时,调用,SDK 会弹出对话框挽留,并展示论坛、礼包等游戏内容

mOpeCenter.shouldQuitGame(MainActivity.this, new OnQuitGameListener() {
    @Override
    public void onQuitGame(boolean shouldQuit) {
        // 点击退出对话框上的“退出游戏”时,shouldQuit为true,游戏处理退出业务逻辑
    }
});

查看SDK版本号

mOpeCenter.getVersion();

更新支持

此功能需要在4399后台提交新版本,并开启相关开关,详情可咨询运营。

更新功能会检查是否有新版本游戏上线,如果有,则显示更新内容、提示用户升级。 按升级内容,可为全量更新和增量更新(只需下载新旧版 APK 文件中的差异部分)。
按接入方式又可分为自动更新(无需操作,默认初始化完成)和自定义界面更新

自定义界面增量更新接入方法详见: 4399运营SDK增量升级说明

渠道支持

接入 SDK 的游戏,希望在多个渠道投放,并分别统计数据,有两种方式打入渠道标识

// 游戏 apk 工程的 build.gradle中
signingConfigs {
  release {
    v2SigningEnabled false
  }
}  

在游戏模块的 AndroidManifest.xml中,设置FTNN_CHANNEL_ID字段值,作为渠道标识

<meta-data 
        android:name="FTNN_CHANNEL_ID"
        android:value="baidu" />

API 详情

User 类方法

User类中是一系列getter方法

public final class User {
    /** uid */
    public String getUid();
  
    /** 用户名 */
    public String getName();
  
    /** 昵称 */
    public String getNick();
  
    /** 登录状态 */
    public String getState();
  
    /** 绑定的手机号,已脱敏,若已绑定则此字段非空 */
    public String getPhone();
}

接口 code 列表

code 含义
0 成功,通用code
1 取消,通用code
2 处理中,通用code
3 失败,通用code
4 超时,通用code
5 中止,通用code
16 登录成功
17 不能取得游戏盒认证(一般是号被封了)
18 登录取消
19 游戏不存在,GameKey问题
20 已登录
21 没有初始化
22 一键登录失败
25 网络问题,或者服务端问题
6001 充值取消
0, 9000 充值成功
2, 9001 订单处理中,游戏应等待服务端的充值回调状态
9002 订单已提交,SDK 不能在有限时间内判断订单状态,游戏应以服务端状态为准