接入准备

工程必须使用 Android 最新 SDK 编译

APK包必须签名,提交Google Play商店以后,签名不可更改

APK包必须 zipalign 优化

天下平台将提供以下信息,用于Android App工程的配置

							
Package Name        Android应用标识
Display Name        应用显示名
AppID               SDK 应用ID
AppKey              SDK 应用Key
Fuid                渠道标识
Facebook ID         Facebook 应用ID
							
						
以上参数可以在SDK zip包中的 SDK更新说明.txt 文件中找到.

SDK 包文件结构

(ANDROID)com.txwy.passport.sdk(游戏名)版本.zip/
├── SDK更新说明(Bundle identifier).txt
├── com.txwy.passport.sdk/
│   ├── res
│   │   ├── drawable-hdpi
│   │   ├── layout-land
│   │   ├── layout-port
│   │   ├── values
│   ├── src
│   |   ├── com.android.vending.billing
│   |   |   ├── IInAppBillingService.aidl
├── libs
│   ├── com.txwy.passport.sdk.jar
│   ├── libTyrantdbGameTracker.jar
│   ├── mta-sdk.jar
│   ├── partytrack.jar
│   ├── GoogleConversionTrackingSdk-*.jar
│   ├── libammsdk.jar
│   ├── AF-Android-SDK-v*.jar
│   ├── analytics_sdk_v*.jar
│   └── google-play-services.jar
└── FacebookSDK
					
						

接入必做事项

客户端接入事项
OBB 分包 官网包,SK包只需要整包,Google包根据营运需求可能有两种打包方式(OBB 或 资源动态下载),请与天下网游营运人员确认
AndroidManifest 必须
SDK API 必须 (其中 设置SDK 语言 仅多语言包需要)
切换账号 , 用户中心 请注意UI需求
充值 必须 (其中 第三方充值 请注意UI需求)
Google兑换码 天下网游营运人员无明确要求,请忽略
SNS API 按照游戏分享需求使用不同的接口,请于天下网游营运人员沟通
进阶 必须 其中 Google Play Services获得 Google Play 商店推荐 在营运人员要求时再实现
服务器端接入事项
服务器对接 必须
生成MARK 如充值不需要Mark(透传参数)此接口可以忽略
查询Facebook好友 天下网游营运人员无明确要求,请忽略

OBB 分包

注意

提交 Google Play 的APK 必须小于 100 MB, 大于 100MB 的App,需要进行OBB分包 .

建议APK不大于 97 MB

Google 官方文档 http://developer.android.com/google/play/expansion-files.html 需要翻墙访问

OBB文件名格式


[main|patch].<expansion-version>.<package-name>.obb

main               OBB正式包
patch              OBB补丁包
expansion-version  android:versionCode
package-name       Your application's Java-style package name.

实例:<shared-storage>/Android/obb/com.example.app/main.314159.com.example.app.obb

<shared-storage>     可以通过系统函数 getExternalStorageDirectory 获取正确的存放位置


						

不用实现OBB文件的下载

玩家在Google Play商店安装游戏时,会自动安装APK和OBB,提示安装成功时,OBB已经被正确的安装.

读取OBB文件中的资源


// The shared path to all app expansion files
private final static String EXP_PATH = "/Android/obb/";

static String[] getAPKExpansionFiles(Context ctx, int mainVersion,
      int patchVersion) {
    String packageName = ctx.getPackageName();
    Vector<String> ret = new Vector<String>();
    if (Environment.getExternalStorageState()
          .equals(Environment.MEDIA_MOUNTED)) {
        // Build the full path to the app's expansion files
        File root = Environment.getExternalStorageDirectory();
        File expPath = new File(root.toString() + EXP_PATH + packageName);

        // Check that expansion file path exists
        if (expPath.exists()) {
            if ( mainVersion > 0 ) {
                String strMainPath = expPath + File.separator + "main." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strMainPath);
                if ( main.isFile() ) {
                        ret.add(strMainPath);
                }
            }
            if ( patchVersion > 0 ) {
                String strPatchPath = expPath + File.separator + "patch." +
                        mainVersion + "." + packageName + ".obb";
                File main = new File(strPatchPath);
                if ( main.isFile() ) {
                        ret.add(strPatchPath);
                }
            }
        }
    }
    String[] retArray = new String[ret.size()];
    ret.toArray(retArray);
    return retArray;
}


// Get a ZipResourceFile representing a merger of both the main and patch files
ZipResourceFile expansionFile =
    APKExpansionSupport.getAPKExpansionZipFile(appContext,
        mainVersion, patchVersion);

// Get an input stream for a known file inside the expansion file ZIPs
InputStream fileStream = expansionFile.getInputStream(pathToFileInsideZip);
					
						

引用依赖项

以下依耐项都必须正确应用到工程

依赖库
com.txwy.passport.sdk.jar 天下网游 SDK libTyrantdbGameTracker.jar TyrantdbGame Tracker
partytrack.jar Party Tracker GoogleConversionTrackingSdk-*.jar Google conversion Tracker
mta-sdk.jar 微信 libammsdk.jar 微信
AF-Android-SDK-v*.jar Appsflyer Tracker analytics_sdk_v*.jar Metaps Tracking tool
google-play-services.jar Google play services
需要合并到APK的资源 (复制到APK工程资源目录中)
res/drawable-hdpi res/values
res/layout-land res/layout-port

引入 IInAppBillingService
	
复制 com.txwy.passport.sdk\src\com\android\vending\billing\IInAppBillingService.aidl 到App工程的 \src\com\android\vending\billing 文件夹中


非 Unity 项目引入 FacebookSDK

FacebookSDK 是静态库,先导入 FacebookSDK 工程,然后在游戏工程中,按照引用静态库方法引用 FacebookSDK.


Unity 项目引入 Facebook

需要引入 facebook_unity.jar (点击下载)
不能引入 FacebookSDK 工程,需要把 FacebookSDK 工程中的资源文件 复制到 Unity工程资源目录中

* 安卓主工程bin/class下的文件夹将无用R文件开头的去除  然后生成class文件
* 将CLASS和安卓里res下的资源文件都放到unity对应目录下

					
						

AndroidManifest 配置

Android SDK版本

minSdkVersion 必须大于等于 11

权限与特性配置


<uses-feature android:name="android.hardware.telephony" android:required="false" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.vending.BILLING" />

<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:smallScreens="true" android:xlargeScreens="true"/>


						

请注意

没有使用到的权限请清理掉.

特别是 发短信,彩信,拨号 等权限,如非必要请去掉.

Activity 配置

请按照游戏的屏幕方向,选择添加SDK的Activity.

横屏游戏

<activity android:name="com.txwy.passport.model.MainActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.txwy.passport.model.RegActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.txwy.passport.model.WebViewActivity" android:theme="@style/Theme.Transparent" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.txwy.passport.model.SplashActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.txwy.passport.model.FBInviteActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.txwy.passport.model.FBFeedActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

<activity android:name="com.facebook.LoginActivity" android:label="@string/app_name"></activity>

<activity android:name="com.txwy.passport.model.TermsActivity" android:label="@string/app_name" android:screenOrientation="sensorLandscape"></activity>

竖屏游戏

<activity android:name="com.txwy.passport.model.MainActivity" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.txwy.passport.model.RegActivity" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.txwy.passport.model.WebViewActivity" android:theme="@style/Theme.Transparent" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.txwy.passport.model.SplashActivity" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.txwy.passport.model.FBInviteActivity" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.txwy.passport.model.FBFeedActivity" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

<activity android:name="com.facebook.LoginActivity" android:label="@string/app_name"></activity>

<activity android:name="com.txwy.passport.model.TermsActivity" android:label="@string/app_name" android:screenOrientation="sensorPortrait"></activity>

Meta-data 配置

请增加以下 meta-data


<meta-data android:name="com.facebook.sdk.ApplicationId" android:value="@string/facebook_app_id"/>

<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />

Receiver 配置

请增加以下 Receiver


<receiver android:name="it.partytrack.sdk.MultipleReferrerReceiver" android:exported="true" >
	<intent-filter>
		<action android:name="com.android.vending.INSTALL_REFERRER" />
	</intent-filter>
	<meta-data android:name="com.appsflyer.AppsFlyerLib" android:value="com.appsflyer.AppsFlyerLib" />
	<meta-data android:name="com.metaps.analytics.AnalyticsReceiver" android:value="com.metaps.analytics.AnalyticsReceiver" />	
</receiver>

<receiver android:name="com.txwy.passport.model.TxwyBroadcastReceiver">
	<intent-filter>
		<action android:name= "com.txwy.passport.model.TxwyBroadcastReceiver"/>
	</intent-filter>
</receiver>


						

URL Scheme 配置

启动 Activity 中增加 URL Scheme 配置


<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:scheme="fbFacebookAppID" android:host="cometid" android:path="/tw"/>
</intent-filter>

						

完整的实例


<activity
	android:name="com.txwy.passportdemo.MainActivity"
	android:label="@string/app_name" >
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
	<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:scheme="fb1122334455667788" android:host="cometid" android:path="/tw"/>
	</intent-filter>			
</activity>

						

fb1122334455667788 是例子,请勿使用!!!

FacebookAppID : Facebook 应用ID 可以在 SDK更新说明.txt 文件中找到参数值

SDK API使用说明

在代码中引用SDK


import com.txwy.passport.sdk.SDKTxwyPassport;

						

初始化 SDK


请确保在 Launcher Activity OnCreate 函数中初始化SDK

protected void onCreate(Bundle savedInstanceState) {

	String appID  = "天下APPID";
	String appKey = "天下APPKEY";
	String fuid   = "渠道标识";
	
	SDKTxwyPassport.setAppInfo(this, appid, appkey, fuid);
}

this 为 Activity 类指针.

所需要的参数,可以在 SDK更新说明.txt 文件中找到.

						

设置SDK 语言

设置SDK的系统语言(多语言版本适用)


this 为 Activity 类指针.

SDKTxwyPassport.setLanguage(this, "语言字符");



						
tw 繁体 cn 简体 en 英语 de 德语
jp 日语 kr 韩语 th 泰国 vi 越南
tr 土耳其语 es 西班牙语 ru 俄语 fr 法语

登录通行证


this 为 Activity 类指针.

SDKTxwyPassport.signIn(this, new SDKTxwyPassport.SignInDelegete() {
	
	@Override
	public void txwyDidPassport() {
		// 登录完成

		SDKTxwyPassportInfo passport = SDKTxwyPassport.getPassportInfo(this);
		// passport.uid 用户ID
		// passport.uname 用户名
		// passport.sid 用户登录凭证
		// passport.isGuest = true 则为游客身份登录
		// passport.isBindPhoneNum = true 则为用户已绑定手机
		
		if (passport == null) {
			// 帐号已登出
			return;
		}
	
		// 帐号已成功登录通行证
		// 将 passport.sid 传递给服务器,服务器通过通行证接口验证sid,以确保登录账号合法。
	}
});

						

SDKTxwyPassportInfo 结构


public class SDKTxwyPassportInfo  {

	int uid;              	通行证ID,玩家唯一数字标识
	String sid;          	通行证登录凭证
	String fuid;          	用户来源渠道标识
	boolean isGuest;      	标识是否游客身份登录
	boolean isBindPhoneNum; 标识用户是否已经绑定手机

}

						

注意

sid 仅用于服务器端登录验证,有效时间5分钟仅能使用一次,验证一次后自动失效

切换账号



this 为 Activity 类指针.

// 首先登出当前账号,无任何事件回调
SDKTxwyPassport.signOut(this);

// 紧接着调登入接口
SDKTxwyPassport.signIn(this, new SDKTxwyPassport.SignInDelegete() {
	
	@Override
	public void txwyDidPassport() {
		// 登录完成
		SDKTxwyPassportInfo passport = SDKTxwyPassport.getPassportInfo(this);
	}
});

						

游戏切换账号流程

* 游戏内提供登出按钮

* 点击登出按钮,游戏退出到选择服务器界面

* 如果玩家需要切换通行证账号,则通过选择服务器界面上的“切换账号”按钮,进行账号切换

游戏内提供登出按钮
点击登出按钮,游戏退出到选择服务器界面
如果玩家需要切换通行证账号,则通过选择服务器界面上的“切换账号”按钮,进行账号切换

跟踪玩家数据

请在玩家登录游戏服务器或者角色升级以后调SDK跟踪接口


this 为 Activity 类指针.

SDKTxwyPassport.trackAccount(this, "服务器ID", 角色等级);

						

服务器ID需要与天下网游平台协商,平台的客服中心,平台充值等都需要使用相同的服务器ID。

新手引导

完成游戏新手引导的时刻,调用此接口


this 为 Activity 类指针.

SDKTxwyPassport.evtCompletedTutorial(this);



						

达成成就

达成成就特定的时刻,调用此接口


this 为 Activity 类指针.

SDKTxwyPassport.evtUnlockedAchievement(this);



						

客服中心

游戏必须接入天下网游的客服中心


this 为 Activity 类指针.

SDKTxwyPassport.bugReport(this, "服务器ID", "角色昵称", "游戏客户端版本号");

						

用户中心


this 为 Activity 类指针.

SDKTxwyPassport.userCenter(this, "服务器ID", "角色昵称", "游戏客户端版本号");

若未登录游戏服务器,服务器ID 请传入 "1"
若游戏角色未登录,角色昵称 请传入 "未登入"

						
建议放置位置: 选服界面,右上角

						

系统回调

下列系统回调必须传递到SDK接口,否则SDK无法正常工作

onActivityResult


@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	// Pass on the activity result to the helper for handling
	if (!SDKTxwyPassportEx.handleActivityResult(requestCode, resultCode, data)) {
		// not handled, so handle it ourselves (here's where you'd
		// perform any handling of activity results not related to in-app
		// billing...
		super.onActivityResult(requestCode, resultCode, data);
	}
}

						

充值接入说明

充值界面由游戏开发方提供.

充值项的设定,可以在 SDK更新说明.txt 文件中找到.

支付产品的价格需要通过SDK提供的接口查询.

查询充值项价格

请在游戏启动过程中,后台异步查询价格.

避免在显示商店时同步查询价格,这会导致打开商店界面有明显的延迟.


this 为 Activity 类指针.

List products = new ArrayList();

products.add("txwy_001");
products.add("txwy_002");

SDKTxwyPassportEx.googleInventory(this, "服务器ID", products, "Mark 透传参数", new SDKTxwyPassportEx.InventoryDelegete() {
	@Override
	public void txwyDidInventory(List list) {
		for (int i = 1; i <= list.toArray().length; i++){
			sku = (SkuDetails) list.toArray()[i-1];
			if (sku!=null){
				//sku.getSku()		     	-- 产品ID
				//sku.getAmount()	     	-- 价格  
				//sku.getCur()		     	-- 货币
				//sku.getDisplayPrice()		-- 显示价格
			}
		}
	}

	@Override
	public void txwyDidInventory() {
		// 没有查询到任何产品信息
	}
});
 

						

注意

某些情况下 googleInventory 会失败,返回空的产品列表,请显示默认的产品价格,默认价格可以在 SDK更新说明.txt 文件中找到

充值


this          Activity 类指针.
产品ID         充值产品ID,由天下网游平台配置,可以在 SDK更新说明.txt 文件中找到
服务器ID       服务器ID
Mark 透传参数  充值透传参数,天下网游充值平台会原样传回到游戏服务器,详见支付服务器对接
level         角色等级,或者其它可以标识游戏进度的等级

SDKTxwyPassport.payWithProductIDv2(this, "产品ID", "服务器ID", "Mark 透传参数", 角色等级, new SDKTxwyPassport.PassportPayDelegete() {;
	@Override
	public void txwyWillPay(String productID, Number price,
					String Currency, Number num) {
		//充值前回调,通知用户即将充值的商品信息。(注:此时尚未充值成功)
	}

	@Override
	public void txwyDidPay(String productID, Number price,
					String Currency, Number num, String mark) {
		// 平台充值成功,游戏服务器可能还没有收到平台的充值请求。
	}
	
	@Override
	public void txwyDidBindAdExchange(String productID, Number price,
					String Currency, Number num) {
		//TAPJOY兑换时使用	
	}

	@Override
	public void txwyPayCancelled(String mark) {
		//出错或用户取消
	}
});


						

注意

收到 txwyDidPay 回调不代表充值已到账,以游戏服务端收到天下网游充值平台回调为准.

點數卡儲值 (第三方充值)

注意

滥用第三方充值接口,Google play 商店会将游戏下架.

显示为 點數卡儲值


this           Activity 类指针.
服务器ID        服务器ID
Mark 透传参数   充值透传参数,天下网游充值平台会原样传回到游戏服务器,详见支付服务器对接
level          角色等级,或者其它可以标识游戏进度的等级

SDKTxwyPassport.payWithWeb(this, "服务器ID", "Mark 透传参数", 角色等级, new SDKTxwyPassport.PassportPayDelegete() {;
	@Override
	public void txwyWillPay(String productID, Number price,
					String Currency, Number num) {
		//充值前回调,通知用户即将充值的商品信息。(注:此时尚未充值成功)
	}

	@Override
	public void txwyDidPay(String productID, Number price,
					String Currency, Number num, String mark) {
		// 平台充值成功,游戏服务器可能还没有收到平台的充值请求。
	}
	
	@Override
	public void txwyDidBindAdExchange(String productID, Number price,
					String Currency, Number num) {
		//TAPJOY兑换时使用	
	}

	@Override
	public void txwyPayCancelled(String mark) {
		//出错或用户取消
	}
});


						
建议放置位置:
						

是否开启第三方充值


this           Activity 类指针.
level          角色等级,或者其它可以标识游戏进度的等级
	
SDKTxwyPassport.isSupportWebPayment(this, 0);

函数返回 true 允许显示 第三方充值 按钮,否则隐藏按钮.

						

Google兑换码

由 Google 后台生成免费发放给游戏玩家的 游戏兑换码

游戏兑换码 类似于Google充值,也有产品ID。兑换流程也类似于Google商店充值.

兑换流程

Activity 中监听事件


    @Override
    public void onResume() {
	super.onResume();
	
	// 启动监听
	registerReceiver(mBroadcastReceiver, new IntentFilter("com.android.vending.billing.PURCHASES_UPDATED"));
    };
	
    @Override
    public void onPause() {
	super.onPause();
	
	// 暂停监听
	unregisterReceiver(mBroadcastReceiver);
    };

						

Activity 中构建事件监听类


    private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
        // this always runs in UI Thread
        @Override
        public void onReceive(Context context, Intent intent) {
        
            // 取得兑换产品项
            SDKTxwyPassport.getExchangeProduct(this, new SDKTxwyPassport.GetExchangeDelegete() {
                @Override
                public void onGetExchange(String productID) {
                    // productID 为空字符串时,没有查询到兑换项
                    if(productID.isEmpty())
                        return;
                        
                    // 通知SDK执行兑换
                    SDKTxwyPassport.exchange(this, "服务器ID", "Mark 透传参数", 角色等级, new SDKTxwyPassport.PassportPayDelegete() {
                        @Override
                        public void txwyWillPay(String productID, Number price,
                                        String Currency, Number num) {
                            //充值前回调,通知用户即将充值的商品信息。(注:此时尚未充值成功)
                        }
                    
                        @Override
                        public void txwyDidPay(String productID, Number price,
                                        String Currency, Number num, String mark) {
                            // 平台充值成功,游戏服务器可能还没有收到平台的充值请求。
                        }
                        
                        @Override
                        public void txwyDidBindAdExchange(String productID, Number price,
                                        String Currency, Number num) {
                            //TAPJOY兑换时使用	
                        }
                    
                        @Override
                        public void txwyPayCancelled(String mark) {
                            //出错或用户取消
                        }
                    });                    
                }                        
            });                    
	}
};


						

服务器对接

登录验证


游戏服务器端访问下面的连接

http://p.txwy.tw/passport/auth?sid=1011e33ca7988e3804cc5e0da6298e27

sid       客户端登录成功以后通过 getPassportInfo 接口获取,并传递到游戏服务器。

请求成功返回
{"error":"","uid":12345678,"uname":"用户名"}

请求失败返回
{"error":"错误信息"}

						

注意

sid 有效时间5分钟仅能使用一次,验证一次后自动失效

p.txwy.tw 是港澳台地区通行证域名,其它地区通行证域名请以 SDK更新说明.txt 文件中说明为准.

充值平台服务器回调

需要游戏开发方提供游戏服务器充值的接口.


充值平台向游戏服务器充值接口发起 GET 请求

http://游戏服务器域名/充值接口

GET 参数

uid          玩家的唯一标识,数字类型,只要可以唯一标识一个玩家即可,要于登录接口一致
order        本次充值在平台上的订单号,字符串类型,充值请求的唯一性标识
token        必须为 0
sign         充值票据
server_id    游戏服务器ID,字符串类型
productid    产品标识,字符串类型
mark         充值透传参数(可选)
pay_way      支付方式. appstore iOS充值 | googleplay Google商店充值 | txwy 第三方充值

						

sign 充值票据验证算法



算法生成的哈希值(小写)
md5(uid + "_" + money + "_" + gold + "_" + order + "_" + token + "_" + AppKey)


						

游戏服务器充值接口返回值协议


调用返回用纯文本的数字错误编号,数字错误编号如下(不允许有任何换行和html代码1        充值成功(重复订单号储值也返回1)
2        充值的服务器不存在,请确认游戏服域名正确并已被添加到后台
3        充值游戏币有误
5        md5错误,请确认密钥正确,充值票据算法跟文档描述一致,参与票据计算的参数于传递给接口的参数一致
7        不存在此账号,请确认用户名和登录接口传递的是一致的
0        充值失败,订单处于待充状态,可以重复请求直到返回值为1
-1       充值请求参数错误

						

注意

对于充值失败的订单服务器有重跑机制,一般每5分钟会对充值状态为待充的订单进行重新请求,处理为成功状态(也就是返回0的订单),若超过5分钟订单还未执行成功请与运营同学联系。

仅接入Appstore, Googleplay充值时,可以暂时不实现此接口

如果游戏服务器充值接口没有用到 mark 参数则此接口不用实现


充值平台向游戏服务器生成Mark接口发起 GET 请求

http://游戏服务器域名/生成Mark接口

GET 参数

uid          玩家的唯一标识,数字类型,只要可以唯一标识一个玩家即可,要于登录接口一致
sid          游戏服务器ID,字符串类型

						

游戏服务器生成Mark接口返回值协议


调用返回用json格式数据

{
	ret: 0,
	error: "错误信息",
	mark: "开发方协商约定的参数"
}

ret      错误编码,无错误返回 0
error    返回错误信息
mark     生成的Mark参数

ret 取值:
0      查询成功,需要返回 mark 字段
1      查询失败,仅需要返回 error 字段

						

充值平台向游戏服务器查询昵称接口发起 GET 请求

http://游戏服务器域名/查询昵称接口

GET 参数

uid          玩家的唯一标识,数字类型,只要可以唯一标识一个玩家即可,要于登录接口一致
sid          游戏服务器ID,字符串类型

						

游戏服务器查询昵称接口返回值协议


调用返回用json格式数据

单角色
{
	ret: 0,
	error: "错误信息",
	roleid: "角色ID",
	nickname: "昵称",
	level: 1
	liftcard: 1 (角色终身卡状态: 1为已拥有, 2为未拥有, 可选字段)
	monthcard: 1 (角色月卡状态: 1为已拥有, 2为未拥有, 可选字段)
}

多角色
{
	ret: 0,
	error: "错误信息",
	players: [{
		roleid: "角色ID",
		nickname: "昵称",
		level: 1
		liftcard: 1 (角色终身卡状态: 1为已拥有, 2为未拥有, 可选字段)
		monthcard: 1 (角色月卡状态: 1为已拥有, 2为未拥有, 可选字段)
	}]
}

ret 取值:
0      查询成功,需要返回 roleid, nickname, level  字段
1      查询失败,仅需要返回 error 字段

						

游戏服务器需要配置 网页充值需要的产品项, 这些充值产品项不显示在客户端。



产品项:

web01          2元宝
web20          20元宝
web50          50元宝



						

游戏服务器向平台查询好友接口发起 GET 请求

http://sns.api.txwy.tw/friends.php?uid=xxx&accesstoken=xxx&appid=1001

GET 参数

uid              玩家通行证ID
accesstoken      Facebook AccessToken
appid            SDK 应用ID

uid, accesstoken 参数在客户端通过Facebook方式登录时,SDK的 getPassportInfo 接口返回。
非 Facebook 登录方式, 则 accesstoken 为空字符串,无法查询好友列表.
appid 参数可以在 SDK更新说明.txt 查看.

						

Facebook好友查询接口返回值协议


调用返回用json格式数据

查询成功,返回:
{
    "ret": "0",
    "friends": [
        {
            "id": "Facebook UID",
            "name": "Facebook Name",
            "picture": "头像URL",
            "uid": 通行证UID 可能为0
        },
        {
            "id": "Facebook UID",
            "name": "Facebook Name",
            "picture": "头像URL",
            "uid": 通行证UID 可能为0
        }
    ],
    "me": {
        "id": "Facebook UID",
        "name": "Facebook Name",
        "picture": {
            "data": {
                "url": "头像URL",
            }
        }
    }
}

查询失败,返回:
{
    "ret": "1005",
    "msg": "Invalid OAuth access token."
}


						

天下平台服务器游戏服务器请求发送各种奖励给游戏者

以发送礼包的形式向游戏者发放奖励

礼包ID及内容,平台与游戏开发方协商确定


平台服务器向游戏服务器接口发起 GET 请求

http://游戏服务器域名/发送奖励接口

GET 参数

uid              玩家通行证ID
server_id        游戏服务器ID,字符串类型
itemid           奖励礼包ID, 字符串类型(平台与游戏约定)
sign             请求验证串

						

sign 验证算法



算法生成的哈希值(小写)
md5(uid + "_" + server_id + "_" + itemid + "_" + AppKey)

AppKey 参数可以在 SDK更新说明.txt 查看.

						

接口返回值协议


调用返回用纯文本的数字错误编号,数字错误编号如下(不允许有任何换行和html代码1        发送奖励成功(重复订单号储值也返回1)
2        充值的服务器不存在,请确认游戏服域名正确并已被添加到后台
5        md5错误,请确认密钥正确,充值票据算法跟文档描述一致,参与票据计算的参数于传递给接口的参数一致
7        不存在此账号,请确认用户名和登录接口传递的是一致的
-1       充值请求参数错误

						

社会化API接口

Facebook 应用由天下网游平台配置,并提供可以测试分享的Facebook账号.

测试Facebook的相关功能,需要翻墙!

文本分享


this 为 Activity 类指针.

SDKTxwyPassport.shareToLine(this, "分享文本", "链接URL");

						

图片分享


this          Activity 类指针.
链接URL        链接URL
分享文本        分享文本
图片           Bitmap 类型图片对象

SDKTxwyPassport.feedWithImage(this, "链接URL", "分享文本", Bitmap, new SDKTxwyPassport.feedDelegete() {
		@Override
		public void txwyDidFeed(String error) {
			// TODO Auto-generated method stub
			Log.e("feed err is",error);
		}
	});

						

图片会自动转换为JPEG格式 85%质量

获取礼包接口


this          Activity 类指针.

SDKTxwyPassport.iLikeWithSvrID(this, "服务器ID", "角色昵称", new SDKTxwyPassport.ILikeDelegete() {
	@Override
	public void islogin(boolean completion) {
	}
});


						

获得用户电话接口


this          Activity 类指针.

SDKTxwyPassport.bindPhone(this, new SDKTxwyPassport.BindPhoneDelegete() {			
	@Override
	public void txwyDidBindPhone() {
		Log.d("bindPhone","bind ok");  //绑定成功
		
	}
});


						

区域说明

韩文SK

AndroidManifest 配置


    
新增权限
<uses-permission android:name="android.permission.READ_PHONE_STATE" />	
<uses-permission android:name="android.permission.RECEIVE_SMS" />	

新增 Activity

<activity android:configChanges="locale|keyboardHidden|orientation|screenSize|layoutDirection" android:excludeFromRecents="true" android:name="com.skplanet.dodo.IapWeb" android:windowSoftInputMode="stateHidden"/>


新增 Meta-Data

<meta-data android:name="iap:api_version" android:value="4" />

						

引入 JAR


libs/kr-iap-sk_*.jar

						

请勿在提交Google Play的包中,包含 libs/kr-iap-sk_*.jar

通行证域名


p-kr.playcomet.com

						

日文

通行证域名


p-jp.playcomet.com

						

进阶

隐藏虚拟键盘


public void hideNavigationBar() {
  int uiFlags = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
	| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
	| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
	| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide nav bar
	| View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
	| View.SYSTEM_UI_FLAG_IMMERSIVE ;

  if( android.os.Build.VERSION.SDK_INT >= 19 ){ 
	uiFlags |= 0x00001000;
  } else {
	uiFlags |= View.SYSTEM_UI_FLAG_LOW_PROFILE;
  }

  getWindow().getDecorView().setSystemUiVisibility(uiFlags);
}
	
@Override
public void onWindowFocusChanged(boolean hasFocus) {
  super.onWindowFocusChanged(hasFocus);
  if( hasFocus ) {
	hideNavigationBar();
  }	
}	

						

聊天室屏蔽规则


聊天屏蔽規則:

1,对指定等级做屏蔽字限制;
2,对等级高于我们设定值的玩家不做限制;
3,被屏蔽发言自己客户端可正常显示,无特殊提示;
4,被屏蔽的发言整句都不显示在聊天频道,触发屏蔽的玩家和其他玩家都无法得知是哪句话触发了屏蔽


舉例:
我們限制等級15級以下的玩家,聊天有限制

15級以下的玩家,如果聊天中包涵:line,LINE,=,元寶,等字眼,他所發的消息,就只有他自己看得到,其他玩家是收不到了。

						

整理权限

尽量避免在启动时候请求设备权限。仅在需要使用的位置请求权限。
详情参考:https://developer.android.com/training/permissions/index.html
必须去掉的权限 (文档中要求增加的除外)

android.permission.WRITE_SETTINGS
android.permission.READ_PHONE_STATE
android.permission.NFC
android.permission.MANAGE_ACCOUNTS
android.permission.GET_ACCOUNTS
android.permission.USE_CREDENTIALS
android.permission.AUTHENTICATE_ACCOUNTS
android.permission.MOUNT_UNMOUNT_FILESYSTEMS
android.permission.CHANGE_WIFI_STATE
android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
android.permission.CHANGE_CONFIGURATION
android.permission.SEND_SMS
android.permission.CALL_PHONE
android.permission.CHANGE_NETWORK_STATE
android.permission.PROCESS_OUTGOING_CALLS
android.permission.RECEIVE_BOOT_COMPLETED
android.permission.READ_SMS
android.permission.RECEIVE_SMS
android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
com.android.vending.CHECK_LICENSE

						
建议去掉的权限 (文档中要求增加的除外)
						
android.permission.ACCESS_COARSE_LOCATION
android.permission.ACCESS_FINE_LOCATION
android.permission.BROADCAST_STICKY
android.permission.GET_TASKS
android.permission.KILL_BACKGROUND_PROCESSES
android.permission.SYSTEM_ALERT_WINDOW
android.permission.RECORD_AUDIO
android.permission.READ_LOGS
android.permission.CAMERA

						

Google Play Services

Google Play Services 官方文档 https://developers.google.com/games/services/android/quickstart

成就 和 排行榜 参数由天下网游平台提供

Google Play Services 不是必须接入的项目,具体需求请与天下网游营运接洽


AndroidManifest 新增 Meta-data

<meta-data android:name="com.google.android.gms.games.APP_ID" android:value="用戶端 ID" />

用戶端 ID 由天下网游平台提供

						

  
主界面启动的 onStart() 回调中,通过 mGoogleApiClient.connect() 连接服务。

// 游戏进程中
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
  // 解锁成就或者更新排行榜数据
}

// 启动成就或者排行榜界面
if (mGoogleApiClient != null) {
  if (mGoogleApiClient.isConnected()) {
	// startActivityForResult(Games.Achievements.getAchievementsIntent(mGoogleApiClient),
        REQUEST_ACHIEVEMENTS);
	// OR
	// startActivityForResult(Games.Leaderboards.getLeaderboardIntent(mGoogleApiClient,
        LEADERBOARD_ID), REQUEST_LEADERBOARD);
  } else {
	// 未连接,尝试连接 Google Play Service
	mGoogleApiClient.connect()	
  }
}

// mGoogleApiClient 连接成功回调
@Override
protected void onConnected() {
  // 将所有已达成的成就和排行积分提交到Google。
  // 如果是用户打开成就或者排行榜引发的连接,需要在这里打开成就或者排行榜
}


// mGoogleApiClient 连接失败回调
@Override
public void onConnectionFailed(ConnectionResult result) {
	if (result.hasResolution()) {
		try {
			result.startResolutionForResult(this, 123456);
		} catch (SendIntentException e) {
			mGoogleApiClient.connect();
		}
	}
}


// onActivityResult 系统回调
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	super.onActivityResult(requestCode, resultCode, data);

	if (requestCode == 123456 && resultCode == RESULT_OK) {
	    mGoogleApiClient.connect();
	}
}
		

						

获得 Google Play 商店推荐

获得 Google Play 商店推荐的必做需求 Google 官方文档 http://developer.android.com/intl/zh-cn/design/style/devices-displays.html

以下是经过提炼的需求,一般做到本文档需求即可获得推荐

targetSdkVersion 必须是 23 或者更高

App Icon 须提供以下规格

返回和向上导航的规则



“向上”按钮用于根据屏幕之间的层级关系在某个应用内部导航。 例如,如果屏幕 A 显示项目列表,并且选择某个项目会调出屏幕 B(该屏幕显示项目的更多详情),则屏幕 B 应提供可返回屏幕 A 的“向上”按钮。

如果屏幕是应用中层级最高的屏幕(即应用的主屏幕),则无需提供向上按钮。

系统的“返回”按钮用于按照用户最近操作的屏幕历史记录,按时间逆序导航。 它通常基于屏幕之间的时间关系,而非应用的层级关系。

如果之前查看的屏幕也是当前屏幕的父级项,按下“返回”按钮的作用跟按下“向上”按钮一样 — 这种情况很常见。 但是,“向上”按钮可确保用户留在应用内,与此不同的是,“返回”按钮可让用户返回到主屏幕,甚至返回不同的应用。

战斗支持暂停的游戏,战斗中按返回键要暂停

战斗支持暂停的游戏,返回桌面时游戏要自动暂停

关闭按钮需要关闭窗口不能返回上一层级

						

尽可能少的申请权限

参考 整理权限
切换至后台,或者设备锁屏时,游戏应处于暂停状态。

App 其它杂项


游戏标题和开发者名不得包含宣传性文字
标题或者图标中不得包含宣传性文字

游戏截图不能有宣传性文字
至少上传一张最小 1280 x 800 的高清截图,并且是未修改过的截图
手机,7-inch平板,10-inch平台分别需要一张截图

App的Icon设计必须符合Android的风格,不能太圆角化,不能包含其他平台的元素
Google 官方Icon设计需求 http://www.google.com/design/spec/style/icons.html#icons-product-icons

去掉 READ_LOGS 权限,使用 Google 提供的 UncaughtExceptionHandler 方法处理崩溃异常,不要使用任何第三方的崩溃处理。

						

常见问题

充值项价格查询失败?

  • 首先平台需要先配置好充值项
  • 必须使用真机测试,模拟器取不到价格,也不可测试充值
  • 必须翻墙!!!
  • APK包名必须正确,而且正确签名

游客可以充值吗?

  • YES,游客账号和普通账号是同样的,可以正常充值
  • 游客账号在下次登录通行证时,可以绑定到自选账号,升级未普通账号
  • 游客账号绑定后,uid 不会变化。游戏不用处理绑定后账号的变化.

登录通行证账号出现问题?

  • 显示 游戏错误, 平台没有开放登录,请与天下网游运营联系
  • 使用 Facebook 方式登录时,Facebook App显示应用处于开发模式。请使用天下网游提供的Facebook 测试账号登录,或者请与天下网游运营联系
  • 使用 Facebook 方式登录时,登录成功跳回游戏后,SDK界面没有继续操作。系统回调 部分编码没正确完成.

怎样提交游戏App包到天下网游平台?

怎样测试Facebook分享和邀请?

  • 手机网络必须翻墙
  • APK包必须正确签名
  • Facebook 账号必须是Facebook App的测试人员账号,邀请的好友也必须是测试人员。
  • 邀请信息只能在手机Facebook App中看到.