游戏SDK对接文档

SDK对接文档


【悦声】Android SDK对接文档

<h2>一、工程配置</h2> <ul> <li> <h3>引入工程</h3> <pre><code> AndroidStudio用户将lib目录下的aar文件拷贝到自己的项目lib下,加以引用即可! Eclipse用户请自行百度,添加对应的依赖</code></pre> </li> <li> <h3>其他資源添加(如果有则按以下目录规则添加即可)</h3> <p>assets的资源直接复制即可;</p> </li> <li> <h3>SDK下载地址</h3> <p><a href="https://pan.baidu.com/s/108oxNF-yiongn-afcHbLXg?pwd=2023">AndroidSDK 资源以及DEMO下载地址</a></p> </li> </ul> <h4>1.权限配置</h4> <pre><code> &lt;uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.WRITE_SETTINGS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.VIBRATE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.webkit.permission.PLUGIN" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.INTERNET" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.SEND_SMS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.READ_SMS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.RECEIVE_WAP_PUSH" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.RECEIVE_MMS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.RECEIVE_SMS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.READ_PHONE_STATE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.ACCESS_WIFI_STATE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.RESTART_PACKAGES" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.GET_TASKS" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.RECORD_AUDIO" &gt;&lt;/uses&gt; &lt;uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" &gt;&lt;/uses&gt;</code></pre> <h3>4、Application接入(注意:请务必接入)</h3> <p>游戏方自身的Application对应的方法中实现以下四个方法:</p> <ol> <li><em>onCreate 方法:</em><code>onApplicationCreate(Application application)</code></li> <li><em>attachBaseContext 方法</em>:<code>onApplicationAttachBaseContextInApplication(Application application, Context base)</code></li> <li><em>onConfigurationChanged 方法</em>:<code>onApplicationConfigurationChanged(Application application, Configuration newConfig)</code></li> <li><em>onTerminate 方法</em>:<code>onApplicationTerminate(Application application)</code></li> </ol> <p>示例如下:</p> <pre><code>/** * 必须要自定义一个application 并且要在manifest中声明, 其中所有方法要在super后面调用 */ public class MyApplication extends Application { @Override public void onCreate() { super.onCreate(); YsUnionSdk.getInstance().onApplicationCreate(this); } @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); YsUnionSdk.getInstance().onApplicationAttachBaseContextInApplication(this, base); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); YsUnionSdk.getInstance().onApplicationConfigurationChanged(this, newConfig); } @Override public void onTerminate() { super.onTerminate(); YsUnionSdk.getInstance().onApplicationTerminate(this); } }</code></pre> <p><strong>注意:记得在manifest中声明自定义的Application</strong></p> <h2>二、SDK接口调用</h2> <h3>1.AndroidManifest.xml文件的配置(必接)</h3> <pre><code>&lt;menifest&gt; &lt;application&gt; ... &lt;!-- 聚合sdk --&gt; &lt;!-- 请务必接入 我方SDK闪屏Activity --&gt; &lt;activity android:name="com.yssdk.base.communal.element.SplashScreenActivity" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:screenOrientation="portrait"&gt; &lt;intent-filter&gt; &lt;action android:name="android.intent.action.MAIN" /&gt; &lt;category android:name="android.intent.category.LAUNCHER" /&gt; &lt;/intent-filter&gt; &lt;/activity&gt; &lt;!-- 是否有闪屏图片 固定--&gt; &lt;meta-data android:name="sdk_ys_splash_pic" android:value="false" /&gt; &lt;!-- cp的启动Activity --&gt; &lt;meta-data android:name="sdk_ys_entryactivity" android:value="cp的启动Activity" /&gt; &lt;!-- sdk对接类 固定--&gt; &lt;meta-data android:name="sdk_ys_userimp" android:value="com.yssdk.sdk.channel.YsChannel" /&gt; &lt;!--游戏名称 我方运营提供--&gt; &lt;meta-data android:name="sdk_ys_game_name" android:value="SDK测试" /&gt; &lt;!--游戏ID,我方运营提供--&gt; &lt;meta-data android:name="sdk_ys_main_game_id" android:value="90" /&gt; &lt;!-- 自己渠道sdk的appid 我方运营提供--&gt; &lt;meta-data android:name="sdk_ys_sub_game_id" android:value="576" /&gt; &lt;!-- 自己渠道sdk的appkey 我方运营提供--&gt; &lt;meta-data android:name="sdk_ys_app_key" android:value="%167%173%217%102%105%158%172%194%210%144%153%167%216%221%168%145%101%157%218%196%160%97%152%158%219%221%167%146%148%164%168%147" /&gt; &lt;!--打包ID,固定--&gt; &lt;meta-data android:name="sdk_ys_package_id" android:value="1" /&gt; &lt;!--现网填true 测试网填false--&gt; &lt;meta-data android:name="sdk_ys_online" android:value="true" /&gt; &lt;!--投放系统-&gt;监测链接-&gt;广告包ID--&gt; &lt;meta-data android:name="sdk_ys_site_id" android:value="1001" /&gt; &lt;!--投放系统-&gt;监测链接-&gt;投放标签--&gt; &lt;meta-data android:name="sdk_ys_pfname" android:value="yuesheng" /&gt; &lt;!--我方SDK组件--&gt; &lt;activity android:name="com.yssdk.sdk.LoginActivity" android:configChanges="keyboard|keyboardHidden|screenLayout|screenSize|orientation" android:launchMode="singleTask" android:hardwareAccelerated="true" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" android:windowSoftInputMode="adjustPan" /&gt; &lt;service android:name="com.yssdk.sdk.CallbackResultService" /&gt; &lt;service android:name="com.yssdk.sdk.ui.floatView.FloatBallService" android:exported="false" /&gt; &lt;activity android:name="com.yssdk.sdk.CommonWebviewActivity" android:configChanges="orientation|screenSize|keyboardHidden" /&gt; &lt;activity android:name="com.yssdk.base.communal.element.YsChaActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /&gt; &lt;activity android:name="com.yssdk.base.communal.element.NoticeActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /&gt; &lt;activity android:name="com.yssdk.sdk.PaymentActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@style/yssdk_gift_dialog" /&gt; &lt;activity android:name="com.yssdk.sdk.ui.ActicitySide" android:configChanges="keyboardHidden|orientation|screenSize" android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen" /&gt; &lt;/application&gt; &lt;/menifest&gt;</code></pre> <h3>2.SDK初始化(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().initSDK(Activity activity, YsSdkListener listener);</code></p> <p>接口示例:</p> <pre><code>private void initSdk() { Log.i(TAG, "initSdk..."); // init方法只能在主Activity的onCreate中调用,第二个参数为全局回调 YsUnionSdk.getInstance().initSDK(activity, new YsSdkListener() { @Override public void initSuc(String msg) { initSuc = true; YsUnionSdk.getInstance().loginSDK(activity); Log.e(TAG, "收到回调初始化成功: " + msg); Log.e(TAG, "收到回调初始化成功: " + msg); } @Override public void initFailed(String reason) { initSuc = false; Log.e(TAG, "收到回调初始化失败: " + reason); } @Override public void onLoginSuc(String data) { Log.e(TAG, "收到回调登录成功 " + data); try { JSONObject jsonObject = new JSONObject(data); String cur_uid = jsonObject.getString("userId");//服务端登录验证使用,账号唯一标识, 建议和渠道id拼接作为唯一标识,避免多渠道渠道userId重复.某些渠道此字段可能有点长,建议留100位保存. String new_sign = jsonObject.getString("new_sign");//服务端登录验证使用 String timestamp = jsonObject.getString("timestamp");//服务端登录验证使用 String cp_ext = jsonObject.getString("cp_ext");//服务端登陆验证使用,这是一个json, 目前写死为{"test":"test"} String guid = jsonObject.getString("guid");//服务端登陆验证使用 String channelId = jsonObject.getString("channelId");//渠道id 如联想为15 具体参见&lt;各渠道参数&gt; String channelVersion = jsonObject.getString("channelVersion");//渠道版本 String packageId = jsonObject.getString("packageId");//包id.对应一个游戏安装包. String age = jsonObject.getString("age");//年龄 String realNameStatus = jsonObject.getString("realNameStatus");//实名状态 0:未实名:1:已实名 String isVisitors = jsonObject.getString("isVisitors");//是否游客 0:不是 ,1:游客 //上面的参数,每次登录成功一定会返回。所以可用getString方法获取. userId = cur_uid; } catch (Exception e) { e.printStackTrace(); } } @Override public void onLoginFailed(String reason) { Log.e(TAG, "收到回调登录失败 " + reason); userId = ""; } @Override public void onLogout(boolean shouldRelogin) { Log.e(TAG, "收到回调登出 " + shouldRelogin); userId = ""; if (shouldRelogin) { // 1.退出游戏场景,回到游戏主界面。 TODO // 2.重新调起sdk登录 YsUnionSdk.getInstance().loginSDK(activity); } else { // 1 退出游戏场景,回到游戏主界面。 // 2 不需主动再调用sdk登录, 但需要有用户点击主界面能调起sdk登录的功能. } } @Override public void onPaySuc(String extension) { Log.e(TAG, "收到回调支付成功:" + extension); } @Override public void onPayFail(String extension) { Log.e(TAG, "收到回调支付失败:" + extension); } @Override public void onExit() { Log.e(TAG, "收到回调退出 onExit"); // 上报角色信息 TODO YsUnionSdk.getInstance().submitDataSDK(activity, createUserPrams(YsUserExtraData.TYPE_EXIT_GAME)); //清理资源 杀死进程 TODO finish(); System.exit(0); } @Override public void onResult(int code, String msg) { Log.e(TAG, "收到回调其他 code=" + code + " msg=" + msg); } }); }</code></pre> <h3>3.登陆(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().loginSDK(Activity activity)</code></p> <h5>回调结果onLoginSuc(String json)解析之后的数据如下</h5> <table> <thead> <tr> <th>参数</th> <th>类型</th> <th>说明</th> </tr> </thead> <tbody> <tr> <td>userId</td> <td>String</td> <td>服务端登录验证使用,账号唯一标识, 建议和渠道id拼接作为唯一标识,避免多渠道渠道userId重复.某些渠道此字段可能有点长,建议留100位保存.</td> </tr> <tr> <td>new_sign</td> <td>String</td> <td>服务端登录验证使用</td> </tr> <tr> <td>timestamp</td> <td>String</td> <td>服务端登录验证使用</td> </tr> <tr> <td>cp_ext</td> <td>String</td> <td>服务端登陆验证使用,这是一个json, 目前写死为{“test”:”test”}</td> </tr> <tr> <td>guid</td> <td>String</td> <td>服务端登陆验证使用</td> </tr> <tr> <td>channelId</td> <td>String</td> <td>渠道id</td> </tr> <tr> <td>channelVersion</td> <td>String</td> <td>道版本</td> </tr> <tr> <td>age</td> <td>String</td> <td>年龄</td> </tr> <tr> <td>realNameStatus</td> <td>String</td> <td>实名状态 0:未实名:1:已实名</td> </tr> <tr> <td>isVisitors</td> <td>String</td> <td>是否游客 0:不是 ,1:游客</td> </tr> </tbody> </table> <h3>4.支付(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().paySDK(Activity activity, YsUnionPayParams params)</code></p> <p>支付参数YsUnionPayParam获取示例:</p> <pre><code>private YsUnionPayParams createPayParams() { orderId = orderId + "_"; YsUnionPayParams payParams = new YsUnionPayParams(); payParams.setBuyNum(1);// 一般只买一份 // cp测试回调写 https://rh-api.hnjst.cn/success.php payParams.setCallBackUrl("https://rh-api.hnjst.cn/success.php"); payParams.setExtension("回传参数"); payParams.setOrderId(orderId);//cp的订单id payParams.setPartyName("武当派"); payParams.setPer_price(1);// 单位为分, 但只支持元为单位,所以传100的整数 payParams.setProductDesc("一锭做工完美的金元宝"); payParams.setProductId("11100"); payParams.setProductName("元宝"); payParams.setRatio(10);// 1人民币 10个 payParams.setRemainCoinNum(5000);// 此玩家钱袋里还有5000个元宝 payParams.setRoleId("123"); payParams.setRoleLevel(100); payParams.setRoleName("悟饭"); payParams.setServerId("1"); payParams.setServerName("华中区"); payParams.setTime(System.currentTimeMillis());// 13位毫秒 payParams.setTotalPrice(1); // 总价格 = 购买份数 * 单价 payParams.setVip(12 + ""); String gsonToString = GsonUtil.GsonToString(payParams); Log.d(TAG, "支付参数:" + gsonToString); return payParams; }</code></pre> <p>支付结果会在初始化监听回调中返回,onPaySuc(String extension)回调支付成功,onPayFail(String extension)回调支付失败结果;</p> <h3>5.账号切换与注销(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().logoutSDK(Activity activity, boolean isRelogin)</code></p> <p>其中参数:isRelogin表示是否重新拉起登陆的意思,调用注销或者切换的逻辑为:玩家在悬浮窗、或者游戏内设置中点击注销账号,应回到游戏登陆界面,最后重新拉起登陆;如果isRelogin设置为false,需要cp方手动拉起登陆界接口!</p> <h3>6.游戏数据上报(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().submitDataSDK(Activity activity, YsUserExtraData params)</code></p> <p>YsUserExtraData数据获取示例:</p> <pre><code>// 上报参数 private YsUserExtraData createUserPrams(int type) { YsUserExtraData userExtraData = new YsUserExtraData(); // 设置上报类型 userExtraData.setDataType(type); userExtraData.setServerId("1");//玩家所在服务器的ID userExtraData.setServerName("华中区");//玩家所在服务器的名称 userExtraData.setRoleId("123456789111");//玩家角色ID userExtraData.setRoleName("悟饭");//玩家角色名称 若无则传"无" userExtraData.setRoleLevel(100);//玩家角色等级 userExtraData.setProfessionId(2);//当前玩家职业id userExtraData.setProfession("刺客");//当前玩家职业名称 若无,传入"无" userExtraData.setPower(10000);//战斗力 userExtraData.setVip(5);//玩家VIP等级 userExtraData.setRoleGender("女");//角色性别 (男或女) userExtraData.setPayTotal(2000);// 累计充值金额 元为单位 userExtraData.setRemainCoinNum(5000);// 1级货币余额,此玩家钱袋里还有5000个元宝. userExtraData.setPartyId(1);//帮派id userExtraData.setPartyName("武当派");//帮派名称 若无,传入"无" userExtraData.setPartyRoleId(1);//角色在帮派中的称号id userExtraData.setPartyRoleName("武当-大师兄");// 角色在帮派中的称号 若无,传入"无" userExtraData.setRoleCreateTime((int) (System.currentTimeMillis() / 1000));//10位 秒 // 人民币能买到的货币统计(传json) 若无则传0 JSONArray balancelist = new JSONArray(); JSONObject balance1 = new JSONObject();// 1级货币 JSONObject balance2 = new JSONObject();// 2级货币 try { balance1.put("balanceid", "1"); balance1.put("balancename", "元宝"); balance1.put("balancenum", "5000"); balance2.put("balanceid", "2"); balance2.put("balancename", "钻石"); balance2.put("balancenum", "100"); } catch (JSONException e) { e.printStackTrace(); } balancelist.put(balance1).put(balance2); userExtraData.setBanlance(balancelist.toString()); //userExtraData.setBanlance("0");//若无则传0 // 此角色的好友关系(传json) 若无好友则传"无" JSONArray friendlist = new JSONArray(); JSONObject friend1 = new JSONObject(); JSONObject friend2 = new JSONObject(); try { friend1.put("roleid", "150");//关系角色id friend1.put("intimacy", "100");//亲密度 friend1.put("nexusid", "1");//1:夫妻,2:结拜,3:情侣,4:师徒 ,5:仇人;其余关系从6开始自定义编号 不能为空 friend1.put("nexusname", "夫妻");// friend2.put("roleid", "151"); friend2.put("intimacy", "2"); friend2.put("nexusid", "6");//自定义关系id为6 friend2.put("nexusname", "师兄弟");//自定义关系名称:师兄弟 } catch (JSONException e) { e.printStackTrace(); } friendlist.put(friend1).put(friend2); userExtraData.setFriendShip(friendlist.toString()); //userExtraData.setFriendShip("无");//若无好友关系则传无 /* 以上都为常规参数,各个上报事件都需要传. 选择服务器,创角的时候肯定很多参数是没有的,那么只传已经存在参数 */ /** 上报类型为TYPE_LEVEL_UP 的时候传下面的参数 **/ userExtraData.setRoleLevelUpTime((int) (System.currentTimeMillis() / 1000));// 10位秒 /** * 上报类型为TYPE_TASK 的时候传下面的参数 任务统计 (任务完成时,不管是成功还是失败) */ userExtraData.setTask_id(11);//ID cp定义 userExtraData.setTask_name("追查凶手"); userExtraData.setTask_status(1);// 1:成功 2:失败 /** * 上报类型为TYPE_HONOR 的时候传下面的参数 荣誉统计(一个角色可以获得多个荣誉 如:排行榜多少名、xx勋章、称号) */ userExtraData.setHonor_id(1);//ID cp定义 userExtraData.setHonor_name("晋升副掌门"); String gsonToString = GsonUtil.GsonToString(userExtraData); Log.d(TAG, "上报参数:" + gsonToString); return userExtraData; }</code></pre> <h3>7.退出接口(必接)</h3> <p>接口:<code>YsUnionSdk.getInstance().exitSDK(Activity activity)</code></p> <p>退出回调会在onExit()中返回,请在此回调方法中处理游戏退出的相关逻辑;</p> <h3>8.获取实名信息(选接)</h3> <p>接口:<code>YsUnionSdk.getInstance().onGetRealNameInfo(Activity activity, RealNameCallback callback)</code></p> <h3>9. 获取SDK生成的设备识别码(选接)</h3> <p>接口:<code>YsUnionSdk.getInstance().getUtma(Context context)</code></p> <h3>10.主Activity声明周期(必接)</h3> <p><strong>请务必尽可能的接入以下生命周期!!</strong></p> <pre><code>/* 生命周期 全部都要在super后面调用,除了onBackPressed不需要调用super*/ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); YsUnionSdk.getInstance().onActivityResult(activity, requestCode, resultCode, data); } @Override public void onBackPressed() { //同步生命周期 YsUnionSdk.getInstance().onBackPressed(activity); // 监听返回键调用退出接口 YsUnionSdk.getInstance().exitSDK(activity); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); YsUnionSdk.getInstance().onConfigurationChanged(activity, newConfig); } @Override protected void onStart() { super.onStart(); YsUnionSdk.getInstance().onStart(activity); } @Override protected void onPause() { super.onPause(); YsUnionSdk.getInstance().onPause(activity); } @Override protected void onResume() { super.onResume(); YsUnionSdk.getInstance().onResume(activity); } @Override protected void onNewIntent(Intent intent) { super.onNewIntent(intent); YsUnionSdk.getInstance().onNewIntent(activity, intent); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); YsUnionSdk.getInstance().onRequestPermissionsResult(activity, requestCode, permissions, grantResults); } @Override protected void onStop() { super.onStop(); YsUnionSdk.getInstance().onStop(activity); } @Override protected void onDestroy() { super.onDestroy(); YsUnionSdk.getInstance().onDestroy(activity); } @Override protected void onRestart() { super.onRestart(); YsUnionSdk.getInstance().onRestart(activity); } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); YsUnionSdk.getInstance().onWindowFocusChanged(activity, hasFocus); }</code></pre> <p><strong>详细,请参考DEMO示例!<br /> 详细,请参考DEMO示例!<br /> 详细,请参考DEMO示例!</strong></p> <p>FQA:</p> <ol> <li>由于目前渠道审核制度严格,请务必在我方弹出隐私协议窗口之后在获取相关设备信息(OAID、IMEI、AndroidID等)</li> <li>请务必在我方SDK初始化成功之后,方可操作其他接口操作、否则会产生不可预料的闪退等问题;</li> </ol>

页面列表

ITEM_HTML