GHOME SDK 开发手册 for Android国际版


1. 前言

本文用于指导游戏开发商接入SDK,文中包含客户端的接入说明,以及服务器接口的介绍;

2. SDK接入流程概述

  • 搭建SDK开发环境

  • 初始化SDK

  • 初始化成功,调用账号功能相关接口

  • 用户在进行购买时,调用支付功能相关接口

  • 其他功能接口,可根据业务需要适时调用

  • 接入第三方渠道的个性化功能时,可调用SDK扩展接口实现

  • 销毁SDK

3. 开发环境要求

3.1. 集成SDK文件到游戏工程

  • GHomeSDK,google-play-services_lib,cardview,appcompat-v7,facebook均为lib包,依赖关系为: Android3

3.2. 增加Proguard配置信息

  • 若您使用Proguard混淆游戏代码,请加入以下配置:
-dontwarn com.ghomesdk.google.**
-keep class com.ghomesdk.google.** {*;}

-dontwarn com.ghomesdk.ghomecore.**
-keep class com.ghomesdk.ghomecore.** {*;}
-keep class android.support.v4.** {*;}

-keep class com.ghomesdk.android.utils.** {*;}
-keep class com.android.vending.billing** {*;}
-keep class com.google.android.gms** {*;}

3.3. 增加google配置

  • 在values目录下 string.xml 中增加
    <string name="app_id" translatable="false">请填写google appId</string>
  • 在manifest中增加 string.xml 中增加
    <meta-data android:name="com.google.android.gms.games.APP_ID"
            android:value="@string/app_id" />

    3.4. 增加支付配置

  • 在values目录下 string.xml 中增加
    谷歌支付
    <string name="gl_google_pay_key">请填写谷歌支付key</string>
    onestore支付
    <string name="onestore_pay_id">请填写onestore支付key</string>

    3.5. 增加facebook配置

  • 在values目录下 string.xml 中增加
    <string name="facebook_app_id">请填写facebook appId</string>
    <string name="fb_login_protocol_scheme">请填写fb_login_protocol_scheme</string>
  • 在manifest中增加 string.xml 中增加
    <meta-data android:name="com.facebook.sdk.ApplicationId"
            android:value="@string/facebook_app_id"/>    
    <provider
            android:authorities="该provider请查询facebook控制台"
            android:name=".internal.FacebookInitProvider"
            android:exported="false" />

3.6. 增加twitter配置

  • 在values中增加 string.xml 中增加
    <string name="com.twitter.sdk.android.CONSUMER_KEY">配置twitter分配的API Key对应的值</string>
    <string name="com.twitter.sdk.android.CONSUMER_SECRET">配置twitter分配的API secret Key对应的值</string>

    3.7. 增加line配置

  • 在values中增加 string.xml 中增加
    <string name="line_app_id">配置line分配的游戏ID的值</string>
    <integer name="line_channle_id">配置line分配的渠道ID对应的值</integer>
  • 在manifest中增加配置(在line登录所在Activity中增加 如下配置)

    
    
    <activity
            android:name="com.ghomesdk.international.DemoActivity"
           >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
    
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <!-- Trident's Native lib and module -->
            <meta-data
                android:name="android.app.trident_lib"
                android:value="trident" />
            <meta-data
                android:name="android.app.trident_modules_resource_id"
                android:resource="@array/trident_modules" />
        </activity>
    <meta-data
            android:name="jp.line.sdk.ChannelId"
            android:value="@integer/line_channle_id" />
        <meta-data
            android:name="jp.line.sdk.AuthScheme"
            android:value="line.游戏分配的id(line_app_id的值)" />
        <!-- DO NOT CHANGE THIS VALUE -->
        <meta-data
            android:name="jp.line.sdk.Phase"
            android:value="REAL" />
        <!-- LINE SDK END -->
    
        <!-- Trident SDK Phase -->
        <meta-data
            android:name="com.linecorp.trident.sdk.Phase"
            android:value="ReleasePhase" />
        <!-- Trident SDK Phase end -->

4. 基础功能(必接)

4.1. SDK域名指定

游戏客户端需要在游戏启动的第一个Activity的onCreate()方法中调用该接口。

  • 接口:

    GHome.getInstance().setCountryHostConfig(1);

4.2. SDK初始化接口

游戏客户端需要在游戏启动的第一个Activity的onCreate()方法中调用该接口,在调用其他API前需先调用此接口对SDK进行初始化(create生命周期接口,必须在initialize接口之前调用)。否则可能无法正常使用后续的接口。

  • 接口:

    initial(final Activity activity, final String gameId, final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    gameId: 游戏在手游直通车平台上申请得到的ID。

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 常量定义:
  public static final int ERROR_NO_ERROR= 0;
  • 注意事项:

    如果没有特别说明,在初始化接口成功之前调用其他接口都有可能出现错误,请确保初始化接口成功之后再调用其他接口。

  • 代码示例:
GHome.getInstance().initialize(this, "1000", new Callback(){

  @Override
  public void callback(int code, String message, Map<String, String> data) {
    // success
    if(code == ErrorCode.ERROR_NO_ERROR){

    }
  }

});

4.3. SDK销毁接口

游戏客户端需要在游戏退出之前调用该接口。

  • 接口:

    destroy(final Activity activity,final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

  • 注意事项:

    建议在主Activity的onDestroy接口中调用。

  • 代码示例:
GHome.getInstance().destroy(this,null);//一般不需要回调,一定成功

4.4. SDK支付回调

游戏客户端需要在onActivityResult实现该方法。

  • 注意事项:

    建议在主Activity的onActivityResult接口中调用。

  • 代码示例:
 @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (GHome.getInstance().handleActivityResult(requestCode, resultCode, data)) {
            return;
        }
        super.onActivityResult(requestCode, resultCode, data);

    }

4.5. SDK数据上报

游戏客户端需要在onResume及onPause实现该方法。

  • 注意事项:

    在主Activity的onResume及onPause接口中调用。

  • 代码示例:

    @Override
    protected void onResume() {
        super.onResume();
        //若包含line登录 需参考8. line解除授权回调(若有line登录必接)
        GHome.getInstance().resume(this,null);
    }
    
    @Override
    protected void onPause() {
        super.onPause();
        GHome.getInstance().pause(this);
    }

    5. 账号功能(必接)

5.1. 账号体系说明

  • 注册&登录原理

    1) 在游戏登录界面打开SDK注册&登录界面;

    2) 用户完成注册&登录之后,SDK把用户id和ticket票据返回游戏;

    3) 游戏如果有服务器,需要把客户端获取到ticket票据发送到“登录票据验证接口”(参考5.4节)进行验证,然后把返回的用户信息(用户id和账号)保存到游戏服务器;

  • 注册&登录时线图
    Android3

5.2. 客户端登录

5.2.1 客户端登录接口

游戏客户端可以调用登录接口为玩家提供登录功能。若用户第一次登录,将显示登录和注册的界面。若用户上次使用账号成功登录过,则会用该账号自动登录。

  • 接口:

    login(final Activity activity, final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 注意事项:

    通常情况游戏不需要提示用户登录结果,无论是登录失败还是登录成功,SDK都有Toast提示。

  • 代码示例:
GHome.getInstance().login(this, new Callback() {

  @Override
  public void callback(int code, String message, Map<String, String> data) {
    // 登陆结果的回调。
    // 开发者可以仅处理登陆成功的情况。
    // 登陆失败会有Toast提示,所以开发者可以不处理登录失败的情况。
    if (code == ErrorCode.ERROR_NO_ERROR) {
      // 如果游戏需要,可以在登录成功后,通过data获取到以下信息。
      // userid是该玩家在我们平台的用户id号;
      // ticket是本次登录得到的票据,用来给游戏服务器向平台服务器验证本次登陆是否合法。
      //isGuest是否是游客,isBind是否绑定(只有游客才能绑定,如果是空则代表已绑定)
      System.out.println("userid=" + data.get("userid"));
      System.out.println("ticket=" + data.get("ticket"));
      System.out.println("isGuest=" + data.get("isGuest")==null?false:data.get("isGuest").equals("true"));
      System.out.println("isBind=" + data.get("isBind")==null?true:data.get("isBind").equals("true"));
      //
      // 登录成功,进入游戏界面,游戏开发者补充逻辑。
    }
  }

});
5.2.2 客户端区服登录

游戏客户端可以调用区服登录接口为玩家提供区服登录功能。在用户已登录状态下可用,若用户未登录,点击区服登录返回失败。

  • 接口:

    loginArea(final Activity activity,final String areaId,final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    areaId:区服id

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 代码示例:
GHome.getInstance().loginArea(this, areaId,new Callback() {

                                    @Override
                                    public void callback(int code,
                                                         String errMsg,
                                                         Map<String, String> data) {

                                    }
                                });

5.3 客户端游客绑定接口

游戏客户端可以调用游客绑定接口为玩家提供游客绑定功能。

  • 接口:

    GHome.getInstance().bindAccount(activity,, final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 代码示例:
 GHome.getInstance().bindAccount(this, new Callback() {

@Override
  public void callback(int code, String errMsg, Map<String, String> data) {
          if (code == 0) {
              // success
                 } else {
               // fail
                        }
                        }
                                });
  • 注意事项: 若不需要line登录请注销GHome中bindAccount方法中 AuthManager.getInstance().signOut()
  • 代码示例:
 public void bindAccount(final Activity activity, final Callback callback) {
...
         // AuthManager.getInstance().signOut();
...
                       }

5.4. 客户端注销接口

游戏客户端可以在游戏内需要注销账号的地方调用该接口,执行成功将删除自动登录的记录信息,玩家下次登录后将不再自动登录,而是显示出登录界面。

  • 接口:

    logout(final Activity activity, final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

  • 注意事项:

    暂无

  • 代码示例:
GHome.getInstance().logout(this, new Callback() {
  @Override
  public void callback(int code, String message, Map<String, String> data) {
    if (code == ErrorCode.ERROR_NO_ERROR) {
      // 注销成功
    } else {
      // 注销失败
    }
  }
});
5.5 客户端获取区服信息

游戏客户端可以调用获取区服信息接口得到当前游戏id配置下区服信息。在游戏已初始化状态下可用。

  • 接口:

    queryAreaInfo(final Activity activity,final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 代码示例:
 GHome.getInstance().queryAreaInfo(this,
                                new Callback() {

                                    @Override
                                    public void callback(int code,
                                                         String errMsg,
                                                         Map<String, String> data) {

                                    }
                                });
5.6 客户端获取商品信息

游戏客户端可以调用获取商品信息接口得到当前游戏id配置下商品信息。在用户已初始化状态下可用。

  • 接口:

    queryProductInfo(final Activity activity,final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 代码示例:
 GHome.getInstance().queryProductInfo(DemoActivity.this,
                                new ResultHandler() {

                                    @Override
                                    public void handleResult(int code,
                                                             String errMsg,
                                                             Map<String, String> data) {

                                    }
                                });
5.7 客户端获取商品信息

游戏客户端可以调用获取区服信息接口得到google或onestore商品对应id商品信息。在游戏已初始化状态下可用。

  • 接口:

    GHome.getInstance().getGoogleProductInfo(final Activity activity, final List skuList, final Callback2 callback);

  • 参数说明:

    activity: Activity对象。

    skuList: google或onestore商品id列表。

    callback: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 代码示例:
  GHome.getInstance().getGoogleProductInfo/getOnestoreProductInfo(DemoActivity.this, skuList, new IGHomeApi.Callback2()  {
                            @Override
                            public void callback(int code, String message ,String data) {
                                if (code == 0 && data != null) {

                                } else {

                                }
                            }
                        });

5.8. 服务器登录票据验证接口

  • 用法说明

    为了保证游戏服务器的安全性,游戏服务器在登记用户登录信息之前需要到国际版服务器做一个验证

  • 接口地址

    https://abroad.sdo.com/fh/open/ticket

  • 传值方式

    GET

  • 参数列表

    appid: 游戏对应的APPID

    timestamp: 精确到秒的unix时间戳

    sequence: 不重复的请求序列号(全局唯一)

    ticket_id: 从客户端登录接口返回的ticket字符串;

    sign: 签名串(参考:“附录A:服务器端签名算法”,签名原始串示例:appid=xxx&sequence=xxx&ticket_id=xxx & timestamp=xxxappsecretkey)

  • 返回结果

    返回结果按json编码,数据格式为:

{
  code:0, #返回状态,0为成功,1为失败,2  签名错误7 osap商户不存在,3001 票据不存在或超过有效期或被反复验证,1003 票据申请的appId和验证的APPID不一致
  msg:"ok", #错误信息
  data:{
    userid:123456, #平台用户id,纯数字,无类型。
    token:"40E00263-16A7-8CFA-D0E8-C951D683EA24", #平台TOKEN,36位字符串,暂时不用
    phone:"+86-139****6893" #手机帐号,带国际区号,可用于显示帐号
    invitation_code:"34343"  #邀请码
  }
}

6. 支付功能(必接)

6.1. 支付原理说明

  • 支付原理

    1) 游戏客户端发起支付请求;

    2) SDK服务器收到请求,并发送至第三方支付;

    3) 第三方支付成功收费以后通知SDK服务器,再由SDK服务器通知游戏服务器发货至游戏,需要游戏提供“订单通知接口”进行接受(参考6.3节);

  • 支付时线图

    Android4

6.2. 客户端支付接口

游戏客户端可以在购买道具的地方调用该接口。这将打开支付界面,引导玩家支付该订单。用户结束支付操作后,SDK会回调游戏客户端,告知支付结果是否已经成功。

  • 接口:

    pay(final Activity activity, final String orderId, final String areaId, final String productId, final ResultHandler handler);

    pay(final Activity activity, final String orderId, final String areaId, final String productId,final String extend, final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    orderId: 必传,游戏订单号。如果游戏需要记录订单号,可以传入唯一的字符串来标识此订单。

    areaId: 必传,在手游直通车平台上设置的区服的ID

    productId: 必传,在手游直通车平台上设置的商品的ID

    extend:非必传,若当前游戏不需要可忽略改字段

    handler: 回调对象,用来回调执行结果,详情请参考代码事例。

  • 注意事项:

    由于可能发生网络延迟等等原因,有时候客户端返回的支付结果可能与实际情况有出入,所以最终订单是否支付成功,建议以平台服务器端的通知为准,客户端的通知结果仅作为参考。

  • 代码示例:
GHome.getInstance().pay(this, "game order id", "1", "p001", new Callback() {
  @Override
  public void callback(int code, String message, Map<String, String> data) {
    if (code == ErrorCode.ERROR_NO_ERROR) {
      // 支付成功,游戏客户端可以在这里查询游戏服务器是否收到发货通知
      // 如果游戏服务器已经收到发货通知可以向用户发放道具
    } else {
      // 支付暂未成功,这种状态可能是用户未完成支付,也可能是尚未收到渠道的发货通知
      // 游戏客户可以不做处理,用户下次登录时再做查询
    }
  }
});

6.4. 服务器订单通知接口

  • 用法说明

    用于将用户支付结果通知给游戏。

  • 接口地址

    接口地址需要游戏提供,暂不支持配置,手工导入

  • 传值方式

    POST

  • 参数列表

    orderNo: 服务器的订单号

    userId:用户ID

    gameOrderNo: 游戏的订单号

    product: 产品ID(暂不支持配置,手工导入)

    extend:游戏发送过来的扩展信息,原格式返回

    sign:签名串(参考“附录A:服务器端签名算法”)

    time:到账时间

  • 参数示例
orderNo=791000012PP016140210105937000001&userId=18178&gameOrderNo=NONE&product=com.winggod.jingzhuan&extend=NONE&time=1392004960&sign=ad08d9e2d7b7df6603bc431392d1c707
  • 返回结果

    返回字符串:success,表示成功

    其他表示失败。

7. 渠道接口(必接)

7.1. 客户端上报游戏区接口

游戏客户端在用户选择区时需要调用该接口,否则数据报表将无法按区提供。

  • 接口:

    loginArea(final Activity activity, final String areaId,final ResultHandler handler);

  • 参数说明:

    activity: Activity对象。

    areaId: 用户进入的区号。

    handler: 回调接口

  • 注意事项:

    暂无

  • 代码示例:
GHome.getInstance().loginArea(this, "1",new Callback() {

    @Override
    public void callback(int code, String errMsg,Map<String, String> data) {
       if (code == ErrorCode.ERROR_NO_ERROR) {
           //成功
           } else {
           // 失败
          }        
     }
});

8. line解除授权回调(若有line登录必接)

游戏客户端在包含line登录的情况下,接入该方法,做解除授权后的操作处理。

  • 代码示例:
 @Override
    protected void onResume() {
        super.onResume();
        GHome.getInstance().resume(this,mResultHandler);
        GHome.getInstance().checkLineAuth(this, new IGHomeApi.Callback2() {
            @Override
            public void callback(int code, String message, String data) {
                if (mResultHandler != null)
                    mResultHandler.handleResult(code, message, null);
            }
        });
    }

 private ResultHandler mResultHandler = new ResultHandler() {

        @Override
        public void handleResult(int code, String errMsg,
                                 Map<String, String> data) {
            if (code == Constants.LINE_BIND_CANCEL) {
                Log.d(TAG, "Line授权取消");
                //此处进行line授权取消后的操作(调用登录logout方法或其他)
            }
        }
    };

9. 附录A:服务器端签名算法

  • 参数说明:

    1) timestamp为调用接口时的unix时间戳(精确到秒)

    2) sequence为请求序列号(游戏服务器端需要保证两次调用接口生成的sequence不重复)

  • 签名算法:

    1) 调用方首先需要将请求的参数根据参数的key(ASCII码值)进行升序排序

    2) 将排序好的接口请求参数和参数值按key=val&key2=val2…这样得格式拼装成一个字符串,并在最后加上与APPID对应的APPKEY

    3) 对上述拼接好的字符串进行md5编码,获得最终的签名串

  • 代码示例(PHP):
public function sign ($params, $secret_key) { // $params数组必须包含timestamp
  $in = ksort($params);
  $pairs = array();
  foreach($in as $k => $v){
    $pair[] = $k. '=' .$v;
  }
  $str = implode('&', $pair); // 拼接字符串
  $str = $str.$secret_key; // 把APPKEY补充到最后
  return md5($str);
}

10. 附录B:特殊说明

  • 订单重发机制:

    平台对所有发货状态非“success”的订单,采取统一的重发机制。具体的重发策略为:每60秒重发1次,最大重发次数为60次。

    对尝试重发后,最终失败的订单,我们会隔天通过报表机制发现,由平台方补发货,游戏方不需要参与。

  • 发货重复处理机制:

    基于订单重发机制,可能导致游戏方重复收到相同orderNo的发货通知,此时要求游戏检查orderNo实际到货情况,避免重复向玩家发放游戏币等虚拟货品。建议对一个月内的orderNo做唯一性检查。

    针对已发货成功的订单,要求游戏方收到重复通知时,请务必返回success,状态为“success”的订单,将不会继续触发重发机制。

  • SDK常用类所在包:
    import com.ghomesdk.international.api.GHome;
    import com.ghomesdk.international.api.Constants;
    import com.ghomesdk.google.api.IGHomeApi.Callback;