客户端接入指南


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

SDK 说明

用户信息与隐私策略

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

功能描述

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

SDK 组成

客户端 SDK

客户端支持的编译配置 android:minSdkVersion >= 16
从SDK 3.2.0开始,优先支持aar接入方式,发布结构遵循 Android Studio(as) 规范
若游戏只能以 jar+res 方式接入,请参考 jar+res 依赖引入

服务端 API

服务端支持额外的功能,参考 SDK 服务端接入文档

集成流程

准备

首次接入 SDK,要在 4399 开放平台 注册应用,主要是提交游戏包、游戏素材,配置游戏货币、充值回调地址等信息。
完成后,开发者将得到 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.2.0"
    
    // volley 和 support 是 SDK 使用的外部依赖,若接入方已有,可忽略
    implementation 'com.android.volley:volley:1.2.0'
    //noinspection GradleCompatible
    implementation "com.android.support:support-v4:28.0.0"
}
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 ,可以按需选用

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

jar+res依赖引入 比较繁琐,但是完成后,后续接口调用仍然是一样的。

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

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.+系统上兼容全面屏,可选,默认
            .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) {
            // 用户切换,游戏应回到选服页面
        }
    });
}

初始化的几点说明

页面方向

方向参数 含义
SCREEN_ORIENTATION_LANDSCAPEint, 0 横屏
SCREEN_ORIENTATION_PORTRAIT, int, 1 竖屏,可180度旋转
SCREEN_ORIENTATION_SENSOR_LANDSCAPEint, 6 横屏
SCREEN_ORIENTATION_SENSOR_PORTRAITint, 7 竖屏

悬浮窗

悬浮窗会在用户登录后附着在游戏页面上方,用户可通过悬浮窗进入个人中心和游戏圈。个人中心包含切换用户、修改密码、绑定手机、注销、游币余额显示功能。当用户有安装4399游戏盒时,会自动弹出本游戏的游戏圈页面。

极少数游戏登录 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);

账号切换(推荐)

当需要切换账号时调用,切换成功后 SDK 调用OnInitGlobalListener.onSwitchUserAccountFinished()通知开发者

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

账号登出(推荐)

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

mOpeCenter.logout();

接口调用:充值(推荐)

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

/*
 * 充值,直接传递参数,旧版接口
 *
 * activity,Activity对象,必须
 * money, 充值金额,整型,单位元,1 ~ 50000,必须
 * mark, 游戏方订单,必须,
 *      支持大小写字母、数字、'|'(竖线)、'-'(中划线)、'_'(下划线),最长32位,不可为空,不可重复
 * commodity, 商品名称,可选,最长8个字符
 */
mOpeCenter.recharge(MainActivity.this, money, mark, commodity, new OnRechargeFinishedListener() {
        /* 充值操作结果 */
        @Override
        public void onRechargeFinished(boolean success, int resultCode, String msg) {
            if (success) {
                //请求游戏服,获取充值结果
            } else {
               //充值失败逻辑
            }
        }
});

/*
 * 充值,使用订单类,新版接口
 * 
 * 与直接传递参数几乎一样,只是可以对单笔订单设置是否支持超出金额
 */
mOpeCenter.recharge(MainActivity.this,
    // 充值金额,整数,单位元
    new Order(6, 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
    }
}  
// 游戏 apk 工程的 AndroidManifest.xml中,设置'baidu'渠道
// 其中 android:value="baidu",也可以写出 build.gradle中的占位符
<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 boolean isActivated();
    
    /** 绑定的手机号,已脱敏,若已绑定则此字段非空 */
    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 不能在有限时间内判断订单状态,游戏应以服务端状态为准