官方文檔及SDK的下載地址爲:http://dev.360.cn/wiki/index/id/73html
在接入以前,需先在360後臺建立遊戲,獲取一些接入參數。java
客戶端所須要參數包括:APPID、APPKEY、PRIVATEKEY 三個值填寫在 AndroidManifest 文件中,不能使用@string 引用;禁止把 AppSecret 保存在手機客戶端,AndroidManifest 中存放的是 Private Key,而非 App-Secret。android
Private Key 的算法爲:QHOPENSDK_PRIVATEKEY = MD5(appSecret + "#" + appKey),格式爲 32 位小寫。git
準備工做作爲,正式開始接入,首先確定是把所須要的資源如JAR包之類的複製到個人工程中去。github
我這邊的接入環境是Eclipseweb
打開咱們下載好解壓出來的文檔目錄找到所須要依賴的JAR包算法
紅框所示就是咱們Eclipse所須要的資源文件了。apache
把assets內的文件複製到咱們本身工程中的assets目錄內。json
把libs內的文件複製到咱們本身工程中的libs目錄內。api
下圖中紅框內的文件夾按本身所須要複製
至於demo工程如何建立在上一篇的接入文檔中有詳細教程,請至:
http://www.cnblogs.com/laohaizei/p/6724250.html
複製完成以後,咱們的demo目錄應該是多了這些目錄
至此,咱們已經把全部須要的東西都複製到了咱們的demo工程中。
首先咱們打開咱們工程的AndroidManifest.xml文件。
而後複製如下代碼
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.demo" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" android:targetSdkVersion="18" /> <supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" /> <!-- 親加sdk所需權限 --> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.SET_WALLPAPER_HINTS" /> <uses-permission android:name="android.permission.SET_WALLPAPER" /> <uses-permission android:name="android.permission.BATTERY_STATS" /> <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.RESTART_PACKAGES" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.READ_SMS" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RECORD_AUDIO" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.CHANGE_CONFIGURATION" /> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <uses-permission android:name="android.permission.WAKE_LOCK" /> <!-- 添加360SDK必須要的權限。begin --> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_SMS" /> <!-- payment --> <uses-permission android:name="android.permission.GET_TASKS" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.RESTART_PACKAGES" /> <uses-permission android:name="android.webkit.permission.PLUGIN" /> <!-- 浮窗 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" /> <uses-permission android:name="android.permission.VIBRATE" /> <!-- 微信分享相關 --> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <!-- qiku start --> <!-- 系統帳戶操做權限 --> <uses-permission android:name="android.permission.GET_ACCOUNTS" /> <uses-permission android:name="android.permission.MANAGE_ACCOUNTS" /> <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" /> <uses-permission android:name="android.permission.USE_CREDENTIALS" /> <!-- 系統設置操做權限 --> <uses-permission android:name="android.permission.WRITE_SETTINGS" /> <uses-permission android:name="android.permission.READ_SETTINGS" /> <!-- qiku end --> <!-- QDAS打點SDK所需權限 --> <uses-permission android:name="android.permission.READ_LOGS" /> <!-- 添加360SDK必須要的權限。end --> <application android:name="com.qihoo.gamecenter.sdk.matrix.QihooApplication" android:allowBackup="false" android:icon="@drawable/demo_icon" android:label="@string/demo_app_name" > <activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- 添加360SDK必需的activity:com.qihoopay.insdk.activity.ContainerActivity --> <activity android:name="com.qihoo.gamecenter.sdk.activity.ContainerActivity" android:configChanges="fontScale|orientation|keyboardHidden|locale|navigation|screenSize|uiMode|layoutDirection" android:exported="true" android:theme="@android:style/Theme.Translucent.NoTitleBar" > <!-- 支付寶簽約後自動跳轉到sdk配置 --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> <category android:name="android.intent.category.BROWSABLE" /> <!-- android host的值必須爲遊戲的包名 --> <data android:host="com.example.demo" /> <!-- android scheme的值必須不能變 --> <data android:scheme="qihooonlinepay" /> </intent-filter> </activity> <!-- payment activities begin --> <!-- 添加360SDK必需的activity:com.qihoopp.qcoinpay.QcoinActivity --> <activity android:name="com.qihoopp.qcoinpay.QcoinActivity" android:configChanges="fontScale|orientation|keyboardHidden|locale|navigation|screenSize|uiMode" android:theme="@android:style/Theme.Translucent.NoTitleBar" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" > </activity> <!-- alipay sdk begin --> <activity android:name="com.alipay.sdk.app.H5PayActivity" android:screenOrientation="portrait" > </activity> <!-- alipay sdk end --> <!-- 微信支付界面 --> <activity android:name="com.iapppay.pay.channel.weixinpay.WeixinWapPayActivity" android:configChanges="screenSize|orientation|keyboard|navigation|layoutDirection" android:theme="@android:style/Theme.Translucent" /> <activity android:name="com.junnet.heepay.ui.activity.WelcomeActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:screenOrientation="behind" android:theme="@android:style/Theme.Dialog" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" /> <activity android:name="com.junnet.heepay.ui.activity.WechatPaymentActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:excludeFromRecents="true" android:screenOrientation="behind" android:theme="@android:style/Theme.Dialog" android:windowSoftInputMode="stateAlwaysHidden|adjustResize" /> <activity android:name="com.ipaynow.plugin.activity.PayMethodActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:exported="false" android:screenOrientation="behind" android:theme="@android:style/Theme.Dialog" /> <activity android:name="com.ipaynow.plugin.inner_plugin.wechat_plugin.activity.WeChatNotifyActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:screenOrientation="behind" android:theme="@android:style/Theme.NoDisplay" /> <!-- 如下兩個Activity是SDK插件化使用的代理Activity --> <activity android:name="com.qihoo.sdkplugging.host.HostProxyActivity" android:configChanges="fontScale|orientation|keyboardHidden|locale|navigation|screenSize|uiMode|layoutDirection" android:label="360SDK" android:theme="@android:style/Theme.Translucent.NoTitleBar" > <intent-filter> <action android:name="com.qihoo.sdkplugging.host.proxy.activity.VIEW" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <!-- payment activities end --> <meta-data android:name="QHOPENSDK_APPKEY" android:value="@app_key@" > </meta-data> <meta-data android:name="QHOPENSDK_PRIVATEKEY" android:value="@private_key@" > </meta-data> <meta-data android:name="QHOPENSDK_APPID" android:value="@app_id@" > </meta-data> <!-- 以下是360遊戲實時推送SDK必要聲明,不可修改 --> <receiver android:name="com.qihoo.psdk.local.QBootReceiver" android:permission="android.permission.RECEIVE_BOOT_COMPLETED" > <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> </intent-filter> <intent-filter> <action android:name="android.net.conn.CONNECTIVITY_CHANGE" /> </intent-filter> </receiver> <activity android:name="com.qihoo.psdk.app.QStatActivity" android:launchMode="singleInstance" android:theme="@android:style/Theme.Translucent.NoTitleBar" > </activity> <service android:name="com.qihoo.psdk.remote.QRemoteService" android:exported="true" android:process=":QRemote" > <intent-filter> <action android:name="com.qihoo.psdk.service.action.remote" /> </intent-filter> </service> <service android:name="com.qihoo.psdk.local.QLocalService" android:exported="true" android:process=":QLocal" > <intent-filter> <action android:name="com.qihoo.psdk.service.action.local" /> </intent-filter> </service> <!-- 推送SDK end --> <!-- 微信SDK --> <!-- 微信相關的activity,若是遊戲接入微信分享須要在遊戲工程內實現這個activity,請直接使用demo中的代碼實現,並放在遊戲的工程的對應路徑下。 --> <activity android:name=".wxapi.WXEntryActivity" android:exported="true" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <!-- 從微信開放平臺申請的appid,遊戲須要去申請本身的appid --> <meta-data android:name="QHOPENSDK_WEIXIN_APPID" android:value="@wx_app_id@" > </meta-data> <!-- 注意:此處的微信 appid 申請只與微信分享有關,微信支付功能無需 appid 便可使用 --> <!-- 微信SDK end --> <!-- UpdateLib start --> <activity android:name="com.qihoo.updatesdk.lib.UpdateTipDialogActivity" android:configChanges="keyboardHidden|orientation|screenSize" android:exported="false" android:screenOrientation="portrait" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <service android:name="com.qihoo.appstore.updatelib.CheckUpdateService" android:exported="false" /> <!-- UpdateLib end --> <!-- gameunion plugin start --> <activity android:name="com.qihoo.gameunionforsdk.SimpleWebView" android:configChanges="fontScale|orientation|keyboardHidden|locale|navigation|screenSize|uiMode|layoutDirection" android:theme="@android:style/Theme.Translucent.NoTitleBar" /> <!-- gameunion plugin end --> <!-- 默認參數,不須要修改,直接複製就行 --> <meta-data android:name="DC_APPKEY" android:value="02522a2b2726fb0a03bb19f2d8d9524d" /> </application> </manifest>
以上是須要添加在AndroidManifest.xml中的。(@xxx@部分請注意替換修改,具體有:@app_key@、@private_key@、@app_id@、@wx_app_id@)
而後到咱們demo工程的AndroidManifest.xml全選替換粘貼
這樣AndroidManifest.xml修改好了。
作完以上步驟,接下來,咱們開始接入SDK的接口。
首先打開咱們的MainActivity.java
打開的MainActivity.java應該是這個樣子的
而後把下面的代碼複製進去,注意別把第一行的代碼覆蓋了。
import java.util.HashMap; import org.json.JSONException; import org.json.JSONObject; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; import android.os.Bundle; import android.text.TextUtils; import android.util.Log; import com.qihoo.gamecenter.sdk.activity.ContainerActivity; import com.qihoo.gamecenter.sdk.common.IDispatcherCallback; import com.qihoo.gamecenter.sdk.matrix.Matrix; import com.qihoo.gamecenter.sdk.protocols.CPCallBackMgr.MatrixCallBack; import com.qihoo.gamecenter.sdk.protocols.ProtocolConfigs; import com.qihoo.gamecenter.sdk.protocols.ProtocolKeys; public class MainActivity extends Activity { final static String TAG = "demo"; boolean isInit = false; Activity appActivity = MainActivity.this; Context appContext = this; public boolean isLoginFinished = false; public boolean isInitFinished = false; private boolean mIsInOffline = false; private boolean isLandScape = true; private boolean isShowClose = false; // 是否顯示關閉按鈕 private boolean isSupportOffline = false; // 可選參數,是否支持離線模式,默認值爲false private boolean isShowSwitchButton = true; // 可選參數,是否在自動登陸的過程當中顯示切換帳號按鈕 private boolean isHideWellcome = false; // 可選參數,是否隱藏歡迎界面 private boolean isShowDlgOnFailedAutoLogin = true; // 可選參數,靜默自動登陸失敗後是否顯示登陸窗口,默認不顯示 private boolean isAutoLoginHideUI = false; // 可選參數,自動登陸過程當中是否不展現任何UI,默認展現。 private boolean isDebugSocialShare = true; // 測試參數,發佈時要去掉 protected String mAccessToken = null; // private ProgressDialog mProgress; // AccessToken是否有效 protected static boolean isAccessTokenValid = true; // QT是否有效 protected static boolean isQTValid = true; @Override protected void onCreate(Bundle savedInstanceState) { // TODO Auto-generated method stub super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } @Override protected void onPause() { // TODO Auto-generated method stub super.onPause(); Matrix.onPause(appActivity); } @Override protected void onRestart() { // TODO Auto-generated method stub super.onRestart(); Matrix.onRestart(appActivity); } @Override protected void onResume() { // TODO Auto-generated method stub super.onResume(); Matrix.onResume(appActivity); } @Override protected void onStart() { // TODO Auto-generated method stub super.onStart(); Matrix.onStart(appActivity); } @Override protected void onStop() { // TODO Auto-generated method stub super.onStop(); Matrix.onStop(appActivity); } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); Matrix.destroy(this); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { // TODO Auto-generated method stub super.onActivityResult(requestCode, resultCode, data); Matrix.onActivityResult(appActivity, requestCode, resultCode, data); } @Override protected void onNewIntent(Intent intent) { // TODO Auto-generated method stub super.onNewIntent(intent); Matrix.onNewIntent(appActivity, intent); } private void init() { // TODO Auto-generated method stub MatrixCallBack mSDKCallback = new MatrixCallBack() { @Override public void execute(Context context, int functionCode, String functionParams) { // TODO Auto-generated method stub if (functionCode == ProtocolConfigs.FUNC_CODE_SWITCH_ACCOUNT) { // 調用 sdk 的切換賬號接口 doSdkSwitchAccount(getLandscape(context)); } else if (functionCode == ProtocolConfigs.FUNC_CODE_INITSUCCESS) { // 這裏返回成功以後才能調用 SDK 其它接口 TypeSDKLogger.d( // "initSDK success"); isInit = true; } } }; // 調用其餘SDK接口以前必須先調用init Matrix.init(appActivity, mSDKCallback); } protected boolean getLandscape(Context context) { if (context == null) { return false; } boolean landscape = (context.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE); return landscape; } /** * 使用360SDK的切換帳號接口 * * @param isLandScape * 是否橫屏顯示登陸界面 */ protected void doSdkSwitchAccount(boolean isLandScape) { Intent intent = getSwitchAccountIntent(isLandScape); IDispatcherCallback callback = mAccountSwitchCallback; if (isSupportOffline) { callback = mAccountSwitchSupportOfflineCB; } Matrix.invokeActivity(appActivity, intent, callback); } /*** * 生成調用360SDK切換帳號接口的Intent * * @param isLandScape * 是否橫屏 * @param isBgTransparent * 是否背景透明 * @param clientId * 即AppKey * @return Intent */ private Intent getSwitchAccountIntent(boolean isLandScape) { Intent intent = new Intent(appActivity, ContainerActivity.class); // 界面相關參數,360SDK界面是否以橫屏顯示。 intent.putExtra(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape); // 必需參數,使用360SDK的切換帳號模塊。 intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_SWITCH_ACCOUNT); // 是否顯示關閉按鈕 intent.putExtra(ProtocolKeys.IS_LOGIN_SHOW_CLOSE_ICON, isShowClose); // 可選參數,是否支持離線模式,默認值爲false intent.putExtra(ProtocolKeys.IS_SUPPORT_OFFLINE, isSupportOffline); // 可選參數,是否在自動登陸的過程當中顯示切換帳號按鈕 intent.putExtra(ProtocolKeys.IS_SHOW_AUTOLOGIN_SWITCH, isShowSwitchButton); // 可選參數,是否隱藏歡迎界面 intent.putExtra(ProtocolKeys.IS_HIDE_WELLCOME, isHideWellcome); // 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑 // intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE, // getUiBackgroundPicPath()); // 可選參數,指定assets中的圖片路徑,做爲背景圖 // intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS, // getUiBackgroundPathInAssets()); // -- 如下參數僅僅針對自動登陸過程的控制 // 可選參數,自動登陸過程當中是否不展現任何UI,默認展現。 intent.putExtra(ProtocolKeys.IS_AUTOLOGIN_NOUI, isAutoLoginHideUI); // 可選參數,靜默自動登陸失敗後是否顯示登陸窗口,默認不顯示 intent.putExtra(ProtocolKeys.IS_SHOW_LOGINDLG_ONFAILED_AUTOLOGIN, isShowDlgOnFailedAutoLogin); // 測試參數,發佈時要去掉 intent.putExtra(ProtocolKeys.IS_SOCIAL_SHARE_DEBUG, isDebugSocialShare); return intent; } // 切換帳號的回調 private IDispatcherCallback mAccountSwitchCallback = new IDispatcherCallback() { @Override public void onFinished(String data) { // press back if (isCancelLogin(data)) { return; } // 顯示一下登陸結果 // Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show(); // TypeSDKLogger.d( "mAccountSwitchCallback, data is " + data); // 解析User info // QihooUserInfo info = parseUserInfoFromLoginResult(data); // 解析access_token mAccessToken = parseAccessTokenFromLoginResult(data); } }; // 支持離線模式的切換帳號的回調 private IDispatcherCallback mAccountSwitchSupportOfflineCB = new IDispatcherCallback() { @Override public void onFinished(String data) { // press back if (isCancelLogin(data)) { return; } // 顯示一下登陸結果 // Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show(); // TypeSDKLogger.d( "mAccountSwitchSupportOfflineCB, data is " + data); // 解析User info // 解析access_token mAccessToken = parseAccessTokenFromLoginResult(data); } }; private void login() { mIsInOffline = false; Intent intent = getLoginIntent(isLandScape); IDispatcherCallback callback = mLoginCallback; if (isSupportOffline) { callback = mLoginCallbackSupportOffline; } Matrix.execute(appActivity, intent, callback); } /** * 生成調用360SDK登陸接口的Intent * * @param isLandScape * 是否橫屏 * @return intent */ private Intent getLoginIntent(boolean isLandScape) { Intent intent = new Intent(appActivity, ContainerActivity.class); // 界面相關參數,360SDK界面是否以橫屏顯示。 intent.putExtra(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape); // 必需參數,使用360SDK的登陸模塊。 intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_LOGIN); // 是否顯示關閉按鈕 intent.putExtra(ProtocolKeys.IS_LOGIN_SHOW_CLOSE_ICON, isShowClose); // 可選參數,是否支持離線模式,默認值爲false intent.putExtra(ProtocolKeys.IS_SUPPORT_OFFLINE, isSupportOffline); // 可選參數,是否在自動登陸的過程當中顯示切換帳號按鈕 intent.putExtra(ProtocolKeys.IS_SHOW_AUTOLOGIN_SWITCH, isShowSwitchButton); // 可選參數,是否隱藏歡迎界面 intent.putExtra(ProtocolKeys.IS_HIDE_WELLCOME, isHideWellcome); // 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑 // intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE, // getUiBackgroundPicPath()); // 可選參數,指定assets中的圖片路徑,做爲背景圖 // intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS, // getUiBackgroundPathInAssets()); // -- 如下參數僅僅針對自動登陸過程的控制 // 可選參數,自動登陸過程當中是否不展現任何UI,默認展現。 intent.putExtra(ProtocolKeys.IS_AUTOLOGIN_NOUI, isAutoLoginHideUI); // 可選參數,靜默自動登陸失敗後是否顯示登陸窗口,默認不顯示 intent.putExtra(ProtocolKeys.IS_SHOW_LOGINDLG_ONFAILED_AUTOLOGIN, isShowDlgOnFailedAutoLogin); // 測試參數,發佈時要去掉 intent.putExtra(ProtocolKeys.IS_SOCIAL_SHARE_DEBUG, isDebugSocialShare); return intent; } // 登陸、註冊的回調 private IDispatcherCallback mLoginCallback = new IDispatcherCallback() { @Override public void onFinished(String data) { // press back if (isCancelLogin(data)) { // doSdkLogin(true); return; } // 顯示一下登陸結果 Log.d(TAG, "login callback data:" + data); mIsInOffline = false; // 解析access_token mAccessToken = parseAccessTokenFromLoginResult(data); } }; private IDispatcherCallback mLoginCallbackSupportOffline = new IDispatcherCallback() { @Override public void onFinished(String data) { if (isCancelLogin(data)) { return; } Log.d(TAG, "mLoginCallbackSupportOffline, data is " + data); try { JSONObject joRes = new JSONObject(data); JSONObject joData = joRes.getJSONObject("data"); String mode = joData.optString("mode", ""); if (!TextUtils.isEmpty(mode) && mode.equals("offline")) { // Toast.makeText(appActivity, // "login success in offline mode", // Toast.LENGTH_SHORT).show(); mIsInOffline = true; // 顯示一下登陸結果 // Toast.makeText(appActivity, data, // Toast.LENGTH_LONG).show(); //TypeSDKLogger.e( "token:" + mAccessToken); // 登陸結果直接返回的userinfo中沒有qid,須要去應用的服務器獲取用access_token獲取一下帶qid的用戶信息 //getUserInfo(mQihooUserInfo); } else { mLoginCallback.onFinished(data); } } catch (Exception e) { Log.e(TAG, "mLoginCallbackSupportOffline exception", e); } } }; private void pay() { String price = "100"; // 支付基礎參數 QihooPayInfo payInfo = getQihooPay( price,//_in_pay.GetData(AttName.REAL_PRICE) "商品名", "玩家名", "玩家ID", "服務器ID", "訂單號", "回調地址", "360用戶ID"); Intent intent = getPayIntent(isLandScape, payInfo); // 必需參數,使用360SDK的支付模塊。 intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_PAY); // 啓動接口 Matrix.invokeActivity(appActivity, intent, mPayCallback); } /*** * 生成調用360SDK支付接口的Intent * * @param isLandScape * @param pay * @return Intent */ protected Intent getPayIntent(boolean isLandScape, QihooPayInfo pay) { Bundle bundle = new Bundle(); // 界面相關參數,360SDK界面是否以橫屏顯示。 bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape); // *** 如下非界面相關參數 *** // 設置QihooPay中的參數。 // 必需參數,用戶access token,要使用注意過時和刷新問題,最大64字符。 bundle.putString(ProtocolKeys.ACCESS_TOKEN, pay.getAccessToken()); // 必需參數,360帳號id,整數。 bundle.putString(ProtocolKeys.QIHOO_USER_ID, pay.getQihooUserId()); // 必需參數,所購買商品金額, 以分爲單位。金額大於等於100分,360SDK運行定額支付流程; 金額數爲0,360SDK運行不定額支付流程。 bundle.putString(ProtocolKeys.AMOUNT, pay.getMoneyAmount()); // 必需參數,人民幣與遊戲充值幣的默認比例,例如2,表明1元人民幣能夠兌換2個遊戲幣,整數。 bundle.putString(ProtocolKeys.RATE, pay.getExchangeRate()); // 必需參數,所購買商品名稱,應用指定,建議中文,最大10箇中文字。 bundle.putString(ProtocolKeys.PRODUCT_NAME, pay.getProductName()); // 必需參數,購買商品的商品id,應用指定,最大16字符。 bundle.putString(ProtocolKeys.PRODUCT_ID, pay.getProductId()); // 必需參數,應用方提供的支付結果通知uri,最大255字符。360服務器將把支付接口回調給該uri,具體協議請查看文檔中,支付結果通知接口–應用服務器提供接口。 bundle.putString(ProtocolKeys.NOTIFY_URI, pay.getNotifyUri()); // 必需參數,遊戲或應用名稱,最大16中文字。 bundle.putString(ProtocolKeys.APP_NAME, pay.getAppName()); // 必需參數,應用內的用戶名,如遊戲角色名。 若應用內綁定360帳號和應用帳號,則可用360用戶名,最大16中文字。(充值不分區服, // 充到統一的用戶帳戶,各區服角色都可使用)。 bundle.putString(ProtocolKeys.APP_USER_NAME, pay.getAppUserName()); // 必需參數,應用內的用戶id。 // 若應用內綁定360帳號和應用帳號,充值不分區服,充到統一的用戶帳戶,各區服角色都可使用,則可用360用戶ID最大32字符。 bundle.putString(ProtocolKeys.APP_USER_ID, pay.getAppUserId()); // 可選參數,應用擴展信息1,原樣返回,最大255字符。 bundle.putString(ProtocolKeys.APP_EXT_1, pay.getAppExt1()); // 可選參數,應用擴展信息2,原樣返回,最大255字符。 bundle.putString(ProtocolKeys.APP_EXT_2, pay.getAppExt2()); // 可選參數,應用訂單號,應用內必須惟一,最大32字符。 bundle.putString(ProtocolKeys.APP_ORDER_ID, pay.getAppOrderId()); // 必需參數,使用360SDK的支付模塊。 bundle.putInt(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_PAY); Intent intent = new Intent(appActivity, ContainerActivity.class); intent.putExtras(bundle); return intent; } /*** * @param moneyAmount * 金額數,使用者能夠自由設定數額。金額數爲100的整數倍,360SDK運行定額支付流程; * 金額數爲0,360SDK運行不定額支付流程。 * @return QihooPay */ private QihooPayInfo getQihooPay(String moneyAmount, String itemName, String userName, String roleId, String productId, String billNumber, String pauBackUrl, String userId) { // String qihooUserId = (mQihooUserInfo != null) ? // mQihooUserInfo.getId() : null; // 建立QihooPay QihooPayInfo qihooPay = new QihooPayInfo(); qihooPay.setQihooUserId(userId); qihooPay.setMoneyAmount(moneyAmount); qihooPay.setAccessToken(mAccessToken); qihooPay.setExchangeRate("1"); qihooPay.setProductName(itemName); qihooPay.setProductId(productId); qihooPay.setNotifyUri(pauBackUrl); qihooPay.setAppName("123"); qihooPay.setAppUserName(userName); qihooPay.setAppUserId(roleId); // 可選參數 qihooPay.setAppExt1("ext1"); qihooPay.setAppExt2("ext2"); qihooPay.setAppOrderId(billNumber); return qihooPay; } // 支付的回調 protected IDispatcherCallback mPayCallback = new IDispatcherCallback() { @Override public void onFinished(String data) { Log.d(TAG, "mPayCallback, data is " + data); if (TextUtils.isEmpty(data)) { return; } boolean isCallbackParseOk = false; JSONObject jsonRes; try { jsonRes = new JSONObject(data); // error_code 狀態碼: 0 支付成功, -1 支付取消, 1 支付失敗, -2 支付進行中, // 4010201和4009911 登陸狀態已失效,引導用戶從新登陸 // error_msg 狀態描述 int errorCode = jsonRes.optInt("error_code"); isCallbackParseOk = true; switch (errorCode) { case 0: Log.d(TAG, "支付結果回調成功"); break; case 1: Log.d(TAG, "支付失敗"); break; case -1: Log.d(TAG, "支付取消"); break; case -2: isAccessTokenValid = true; isQTValid = true; // String errorMsg = jsonRes.optString("error_msg"); // String text = // appActivity.getString(R.string.pay_callback_toast, // errorCode, errorMsg); // Toast.makeText(appActivity, text, // Toast.LENGTH_SHORT).show(); break; case 4010201: // acess_token失效 isAccessTokenValid = false; // Toast.makeText(appActivity, // R.string.access_token_invalid, // Toast.LENGTH_SHORT).show(); break; case 4009911: // QT失效 isQTValid = false; // Toast.makeText(appActivity, R.string.qt_invalid, // Toast.LENGTH_SHORT).show(); break; default: break; } } catch (JSONException e) { e.printStackTrace(); } // 用於測試數據格式是否異常。 if (!isCallbackParseOk) { // Toast.makeText(appActivity, // appActivity.getResources().getString(R.string.data_format_error), // Toast.LENGTH_LONG).show(); } } }; private void sendUserInfo(String type) { HashMap eventParams=new HashMap(); //----------------------------參數設置說明-------------------- //如下列出的五項只是做爲參考,請按照上述表格中的參數說明進行補充添加 //僅按 demo 樣例上傳沒法經過審覈!請務必仔細閱讀上述表格! eventParams.put("zoneid",1);//當前角色所在遊戲區服 id eventParams.put("zonename","123");//當前角色所在遊戲區服名稱 eventParams.put("roleid","321");//當前角色 id eventParams.put("rolename","111");//當前角色名稱 eventParams.put("professionid",0); eventParams.put("profession","無"); eventParams.put("gender","無"); eventParams.put("professionroleid",0); eventParams.put("professionrolena me","無"); eventParams.put("rolelevel","1"); eventParams.put("power",0); eventParams.put("vip",0); eventParams.put("balance",0); eventParams.put("partyid",0); eventParams.put("partyname","無"); eventParams.put("partyroleid",0); eventParams.put("partyrolename","無"); eventParams.put("friendlist","無"); eventParams.put("ranking","無"); eventParams.put("type",type);//角色信息接口觸發的場景 //---------------------------------------------------------- Matrix.statEventInfo(appContext, eventParams); } private void logout() { Intent intent = getLogoutIntent(); Matrix.execute(appActivity, intent, new IDispatcherCallback() { @Override public void onFinished(String data) { Log.d(TAG, "logout_success"); // Toast.makeText(appActivity, data, Toast.LENGTH_SHORT).show(); // System.out.println(data); } }); } private Intent getLogoutIntent() { /* * 必須參數: function_code : 必須參數,表示調用SDK接口執行的功能 */ Intent intent = new Intent(); intent.putExtra(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_LOGOUT); return intent; } private void exit() { Bundle bundle = new Bundle(); // 界面相關參數,360SDK界面是否以橫屏顯示。 bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape); // 必需參數,使用360SDK的退出模塊。 bundle.putInt(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_QUIT); // 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑 bundle.putString(ProtocolKeys.UI_BACKGROUND_PICTRUE, ""); Intent intent = new Intent(appActivity, ContainerActivity.class); intent.putExtras(bundle); Matrix.invokeActivity(appActivity, intent, mQuitCallback); } // 退出的回調 private IDispatcherCallback mQuitCallback = new IDispatcherCallback() { @Override public void onFinished(String data) { // TypeSDKLogger.d( "mQuitCallback, data is " + data); JSONObject json; try { json = new JSONObject(data); int which = json.optInt("which", -1); // String label = json.optString("label"); // Toast.makeText(appActivity, // "按鈕標識:" + which + ",按鈕描述:" + label, Toast.LENGTH_LONG) // .show(); switch (which) { case 0: // 用戶關閉退出界面 Log.d(TAG, "用戶關閉退出界面"); return; case 1: //進入論壇 Log.d(TAG, "exit_success"); System.exit(0); break; case 2://退出遊戲 Log.d(TAG, "exit_success"); System.exit(0); break; default: Log.d(TAG, "exit which:" + which); return; } } catch (Exception e) { e.printStackTrace(); } } }; private boolean isCancelLogin(String data) { try { JSONObject joData = new JSONObject(data); int errno = joData.optInt("errno", -1); if (-1 == errno) { // Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show(); return true; } } catch (Exception e) { } return false; } private String parseAccessTokenFromLoginResult(String loginRes) { try { JSONObject joRes = new JSONObject(loginRes); JSONObject joData = joRes.getJSONObject("data"); return joData.getString("access_token"); } catch (Exception e) { e.printStackTrace(); } return null; } }
再而後,咱們須要新建立一個類:
以下圖,咱們在com.xxx這裏右鍵
名字輸入:QihooPayInfo
、
這樣就會在這邊多出一個類文件,咱們打開他
把下面的代碼複製到下圖標記處
代碼:
// 必需參數,用戶access token,要使用注意過時和刷新問題,最大64字符。 private String accessToken; // 必需參數,360帳號id,整數。 private String qihooUserId; // 必需參數,應用app key。 private String appKey; // 必需參數,值爲md5(app_secret +「#」+ // app_key)全小寫,用於簽名的密鑰不能把app_secret寫到應用客戶端程序裏所以使用這樣一個特殊的KEY,應算出值直接寫在app中,而不是寫md5的計算過程。 private String privateKey; // 必需參數,所購買商品金額,以分爲單位。金額大於等於100分,360SDK運行定額支付流程; 金額數爲0,360SDK運行不定額支付流程。 private String moneyAmount; // 必需參數,人民幣與遊戲充值幣的默認比例,例如2,表明1元人民幣能夠兌換2個遊戲幣,整數。 private String exchangeRate; // 必需參數,所購買商品名稱,應用指定,建議中文,最大10箇中文字。 private String productName; // 必需參數,購買商品的商品id,應用指定,最大16字符。 private String productId; // 必需參數,應用方提供的支付結果通知uri,最大255字符。360服務器將把支付接口回調給該uri,具體協議請查看文檔中,支付結果通知接口–應用服務器提供接口。 private String notifyUri; // 必需參數,遊戲或應用名稱,最大16中文字。 private String appName; // 必需參數,應用內的用戶名,如遊戲角色名。 若應用內綁定360帳號和應用帳號,則可用360用戶名,最大16中文字。(充值不分區服, // 充到統一的用戶帳戶,各區服角色都可使用)。 private String appUserName; // 必需參數,應用內的用戶id。 若應用內綁定360帳號和應用帳號, 充值不分區服, 充到統一的用戶帳戶, 各區服角色都可使用, // 則可用360用戶ID。最大32字符。 private String appUserId; // 可選參數,應用擴展信息1,原樣返回,最大255字符。 private String appExt1; // 可選參數,應用擴展信息2,原樣返回,最大255字符。 private String appExt2; // 可選參數,應用訂單號,應用內必須惟一,最大32字符。 private String appOrderId; // 可選參數,支付類型定製 private String[] payTypes; public String[] getPayTypes() { return payTypes; } public void setPayTypes(String[] payTypes) { this.payTypes = payTypes; } public String getAccessToken() { return accessToken; } public void setAccessToken(String accessToken) { this.accessToken = accessToken; } public String getQihooUserId() { return qihooUserId; } public void setQihooUserId(String qihooUserId) { this.qihooUserId = qihooUserId; } public String getAppKey() { return appKey; } public void setAppKey(String appKey) { this.appKey = appKey; } public String getPrivateKey() { return privateKey; } public void setPrivateKey(String privateKey) { this.privateKey = privateKey; } public String getMoneyAmount() { return moneyAmount; } public void setMoneyAmount(String moneyAmount) { this.moneyAmount = moneyAmount; } public String getAppName() { return appName; } public void setAppName(String appName) { this.appName = appName; } public String getAppUserName() { return appUserName; } public void setAppUserName(String appUserName) { this.appUserName = appUserName; } public String getAppUserId() { return appUserId; } public void setAppUserId(String appUserId) { this.appUserId = appUserId; } public String getProductName() { return productName; } public void setProductName(String productName) { this.productName = productName; } public String getProductId() { return productId; } public void setProductId(String productId) { this.productId = productId; } public String getNotifyUri() { return notifyUri; } public void setNotifyUri(String notifyUri) { this.notifyUri = notifyUri; } public String getExchangeRate() { return exchangeRate; } public void setExchangeRate(String exchangeRate) { this.exchangeRate = exchangeRate; } public String getAppExt1() { return appExt1; } public void setAppExt1(String appExt1) { this.appExt1 = appExt1; } public String getAppExt2() { return appExt2; } public void setAppExt2(String appExt2) { this.appExt2 = appExt2; } public String getAppOrderId() { return appOrderId; } public void setAppOrderId(String appOrderId) { this.appOrderId = appOrderId; }
至此咱們就把全部360上線所需的接口完成了,添加UI並添加相應事件調用相應接口後,就是一個最簡單的demo了
若是想要了解具體的接口做用,和相應參數的說明,請繼續閱讀如下內容,或查看官方文檔
第一步初始化:
在Activity onCreate中調用360的初始化接口:(必須在UI線程調用)
private void init() {
// TODO Auto-generated method stub
MatrixCallBack mSDKCallback = new MatrixCallBack() {
@Override
public void execute(Context context, int functionCode, String
functionParams) {
// TODO Auto-generated method stub
if (functionCode == ProtocolConfigs.FUNC_CODE_SWITCH_ACCOUNT) {
// 調用 sdk 的切換賬號接口
doSdkSwitchAccount(getLandscape(context));
}else if (functionCode == ProtocolConfigs.FUNC_CODE_INITSUCCESS) {
//這裏返回成功以後才能調用 SDK 其它接口 TypeSDKLogger.d( "initSDK success");
isInit = true;
}
}
};
// 調用其餘SDK接口以前必須先調用init
Matrix.init(appActivity,mSDKCallback);
}
調用登陸接口:
/**
* 使用 360SDK 的登陸接口, 生成 intent 參數
*
* @param isLandScape 是否橫屏顯示登陸界面
*/
private Intent getLoginIntent(boolean isLandScape) {
Intent intent = new Intent(this, ContainerActivity.class);
// 必需參數,使用 360SDK 的登陸模塊
intent.putExtra(ProtocolKeys.FUNCTION_CODE,
ProtocolConfigs.FUNC_CODE_LOGIN);
// 可選參數,360SDK 界面是否以橫屏顯示,默認爲 true,橫屏
intent.putExtra(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE,
isLandScape);
//可選參數,是否顯示關閉按鈕,默認不顯示
intent.putExtra(ProtocolKeys.IS_LOGIN_SHOW_CLOSE_ICON,
getCheckBoxBoolean(R.id.isShowClose));
// 可選參數,是否支持離線模式,默認值爲 false
intent.putExtra(ProtocolKeys.IS_SUPPORT_OFFLINE,
getCheckBoxBoolean(R.id.isSupportOffline));
// 可選參數,是否在自動登陸的過程當中顯示切換帳號按鈕,默認爲 false
intent.putExtra(ProtocolKeys.IS_SHOW_AUTOLOGIN_SWITCH,
getCheckBoxBoolean(R.id.isShowSwitchButton));
// 可選參數,是否隱藏歡迎界面
intent.putExtra(ProtocolKeys.IS_HIDE_WELLCOME,
getCheckBoxBoolean(R.id.isHideWellcome));
/*
* 指定界面背景(可選參數):
* 1.ProtocolKeys.UI_BACKGROUND_PICTRUE 使用的系統路徑,如/sdcard/1.png
* 2.ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS 使用的 assest 中的圖片
* 資源,
* 如傳入 bg.png 字符串,就會在 assets 目錄下加載這個指定的文件
* 3.圖片大小不要超過 5M,尺寸不要超過 1280x720,後綴只能是 jpg、jpeg 或 png
*/
// 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑
intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE,
getUiBackgroundPicPath());
// 可選參數,指定 assets 中的圖片路徑,做爲背景圖
intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS,
getUiBackgroundPathInAssets());
// 可選參數,是否須要用戶輸入激活碼,用於遊戲內測階段。
// 若是不需激活碼相關邏輯,客戶傳 false 或者不傳入該參數。
intent.putExtra(ProtocolKeys.NEED_ACTIVATION_CODE,
getCheckBoxBoolean(R.id.isNeedActivationCode));
//-- 如下參數僅僅針對自動登陸過程的控制
// 可選參數,自動登陸過程當中是否不展現任何 UI,默認展現。
intent.putExtra(ProtocolKeys.IS_AUTOLOGIN_NOUI,
getCheckBoxBoolean(R.id.isAutoLoginHideUI));
// 可選參數,靜默自動登陸失敗後是否顯示登陸窗口,默認不顯示
intent.putExtra(ProtocolKeys.IS_SHOW_LOGINDLG_ONFAILED_AUTOLOGIN,
getCheckBoxBoolean(R.id.isShowDlgOnFailedAutoLogin));
// 社交分享測試參數,發佈時要去掉,具體說明見分享接口
// intent.putExtra(ProtocolKeys.IS_SOCIAL_SHARE_DEBUG,
// getCheckBoxBoolean(R.id.isDebugSocialShare));
return intent;
}
// 調用接口
protected void doSdkLogin(boolean isLandScape) {
mIsInOffline = false;
Intent intent = getLoginIntent(isLandScape);
IDispatcherCallback callback = mLoginCallback;
if (getCheckBoxBoolean(R.id.isSupportOffline)) {
callback = mLoginCallbackSupportOffline; //離線模式
}
Matrix.execute(this, intent, callback);
}
// 登陸接口回調(不支持離線模式)
// 登陸、註冊的回調
privateIDispatcherCallback mLoginCallback = newIDispatcherCallback() {
@Override
publicvoid onFinished(String data) {
// press back
if (isCancelLogin(data)) {
return;
}
// 顯示一下登陸結果
Toast.makeText(SdkUserBaseActivity.this, data,
Toast.LENGTH_LONG).show();
mIsInOffline = false;
mQihooUserInfo = null;
// 解析 access_token
mAccessToken = parseAccessTokenFromLoginResult(data);
if (!TextUtils.isEmpty(mAccessToken)) {
// 須要去應用的服務器獲取用 access_token 獲取一下用戶信息
getUserInfo();
} else {
Toast.makeText(SdkUserBaseActivity.this, "get access_token
failed!", Toast.LENGTH_LONG).show();
}
}
};
// 登陸結果回調(支持離線模式)
private IDispatcherCallback mLoginCallbackSupportOffline
= new IDispatcherCallback() {
@Override
public void onFinished(String data) {
if (isCancelLogin(data)) {
return;
}
Log.d(TAG, "mLoginCallbackSupportOffline, data is " + data);
try {
JSONObject joRes = new JSONObject(data);
JSONObject joData = joRes.getJSONObject("data");
String mode = joData.optString("mode", "");
if (!TextUtils.isEmpty(mode) && mode.equals("offline")) 、
{
Toast.makeText(SdkUserBaseActivity.this,
"login success in offline mode",
Toast.LENGTH_SHORT).show();
mIsInOffline = true;
// 顯示一下登陸結果
Toast.makeText(SdkUserBaseActivity.this, data,
Toast.LENGTH_LONG).show();
} else {
mLoginCallback.onFinished(data);
}
} catch (Exception e) {
Log.e(TAG, "mLoginCallbackSupportOffline exception", e);
}
}
};
private boolean isCancelLogin(String data) {
try {
JSONObject joData = new JSONObject(data);
int errno = joData.optInt("errno", -1);
if (-1 == errno) {
// Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show();
return true;
}
} catch (Exception e) {
}
return false;
}
private String parseAccessTokenFromLoginResult(String loginRes) {
try {
JSONObject joRes = new JSONObject(loginRes);
JSONObject joData = joRes.getJSONObject("data");
return joData.getString("access_token");
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
調用支付接口:
注意:
一、 必選參數不能爲空, 不能爲 0,不然支付失敗。
二、 參數名,以 ProtocolKeys 中定義的常量爲準。
三、 請務必對 case 0、一、-1 加入處理語句,若是爲空的會致使遊戲崩潰。
/**
* 使用 360SDK 的支付接口
*
* @param isLandScape 是否橫屏顯示支付界面
* @param isFixed 是否認額支付
* @param functioncode 標示支付模塊類型。
*/
protected void doSdkPay(QihooUserInfo usrinfo, boolean isLandScape,int functionCode) {
if(!isAccessTokenValid) {
Toast.makeText(SdkUserBaseActivity.this, R.string.access_token_invalid,
Toast.LENGTH_SHORT).show();
return;
}
if(!isQTValid) {
Toast.makeText(SdkUserBaseActivity.this, R.string.qt_invalid,
Toast.LENGTH_SHORT).show();
return;
}
boolean isFixed = getCheckBoxBoolean(R.id.isPayFixed);
// 支付基礎參數
QihooPayInfo payInfo = getQihooPay(
price,//_in_pay.GetData(AttName.REAL_PRICE)
_in_pay.GetData(AttName.ITEM_NAME).isEmpty()?"商品
":_in_pay.GetData(AttName.ITEM_NAME),
userInfo.GetData(AttName.ROLE_NAME).isEmpty() ? "玩家" :
userInfo.GetData(AttName.ROLE_NAME),
userInfo.GetData(AttName.ROLE_ID).isEmpty()?"1":
userInfo.GetData(AttName.ROLE_ID),
_in_pay.GetData(AttName.ITEM_SERVER_ID).isEmpty()?"1":
_in_pay.GetData(AttName.ITEM_SERVER_ID),
_in_pay.GetData(AttName.BILL_NUMBER),
platform.GetData(AttName.PAY_CALL_BACK_URL),
userInfo.GetData(AttName.USER_ID));
Intent intent = getPayIntent(isLandScape, isFixed, functionCode);
// 必需參數,使用 360SDK 的支付模塊:CP 能夠根據需求選擇使用 帶有收銀臺的支付模
// 塊 或者 直接 調用微信支付模塊或者直接調用支付寶支付模塊。
// functionCode 對應三種類型的支付模塊:
// ProtocolConfigs.FUNC_CODE_PAY;//支付模塊。(有收銀臺,顯示多種支付方式) // ProtocolConfigs.FUNC_CODE_WEIXIN_PAY;//微信支付模塊。
//(無收銀臺,直接用微信進行支付)
//ProtocolConfigs.FUNC_CODE_ALI_PAY;
//支付寶支付模塊。(無收銀臺,直接用支付寶進行支付)
intent.putExtra(ProtocolKeys.FUNCTION_CODE, functionCode);
// 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑
intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE, "");
Matrix.invokeActivity(this, intent, mPayCallback);
}
/**
* @param moneyAmount
*金額數,使用者能夠自由設定數額。金額數爲100的整數倍,360SDK運行定額支付流程;
*金額數爲0,360SDK運行不定額支付流程。
* @return QihooPay
*/
private QihooPayInfo getQihooPay(String moneyAmount, String itemName,
String userName, String roleId, String productId,
String billNumber, String pauBackUrl, String userId) {
// String qihooUserId = (mQihooUserInfo != null) ?
// mQihooUserInfo.getId() : null;
// 建立QihooPay
QihooPayInfo qihooPay = new QihooPayInfo();
qihooPay.setQihooUserId(userId);
qihooPay.setMoneyAmount(moneyAmount);
qihooPay.setAccessToken(mAccessToken);
qihooPay.setExchangeRate("1");
qihooPay.setProductName(itemName);
qihooPay.setProductId(productId);
qihooPay.setNotifyUri(pauBackUrl);
qihooPay.setAppName(platform.GetData(AttName.CP_ID));
qihooPay.setAppUserName(userName);
qihooPay.setAppUserId(roleId);
// 可選參數
qihooPay.setAppExt1("ext1");
qihooPay.setAppExt2("ext2");
qihooPay.setAppOrderId(billNumber);
return qihooPay;
}
/**
* 生成調用 360SDK 支付接口基礎參數的 Intent
*
* @param isLandScape 是否橫屏顯示登陸界面
* @param isFixed 是否認額支付
*
* @return Intent
*/
protected Intent getPayIntent(boolean isLandScape, boolean isFixed) {
Bundle bundle = new Bundle();
QihooPayInfo pay = getQihooPayInfo(isFixed);
// 界面相關參數,360SDK 界面是否以橫屏顯示。
bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape);
// 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑
bundle.putString(ProtocolKeys.UI_BACKGROUND_PICTRUE, "");
// *** 如下非界面相關參數 ***
// 設置 QihooPay 中的參數。
// 必需參數,用戶 access token,要使用注意過時和刷新問題,最大 64 字符。 bundle.putString(ProtocolKeys.ACCESS_TOKEN, pay.getAccessToken());
// 必需參數,360 帳號 id。
bundle.putString(ProtocolKeys.QIHOO_USER_ID, pay.getQihooUserId());
//必需參數,所購買商品金額, 以分爲單位。金額大於等於 100 分,360SDK 運行定額支
//付流程; 金 額數爲 0,360SDK 運行不定額支付流程。
bundle.putString(ProtocolKeys.AMOUNT, pay.getMoneyAmount());
// 必需參數,所購買商品名稱,應用指定,建議中文,最大 10 箇中文字。
bundle.putString(ProtocolKeys.PRODUCT_NAME, pay.getProductName());
// 必需參數,購買商品的商品 id,應用指定,最大 16 字符。
bundle.putString(ProtocolKeys.PRODUCT_ID, pay.getProductId());
// 必需參數,應用方提供的支付結果通知 uri,最大 255 字符。360 服務器將把支付接口
//回調給該 uri, 具體協議請查看文檔中,支付結果通知接口–應用服務器提供接口。
bundle.putString(ProtocolKeys.NOTIFY_URI, pay.getNotifyUri());
// 必需參數,遊戲或應用名稱,最大 16 中文字。
bundle.putString(ProtocolKeys.APP_NAME, pay.getAppName());
// 必需參數,應用內的用戶名,如遊戲角色名。 若應用內綁定 360 帳號和應用帳號,則
//可用 360 用戶 名,最大 16 中文字。(充值不分區服,充到統一的用戶帳戶,各區服角
//色都可使用)。
bundle.putString(ProtocolKeys.APP_USER_NAME, pay.getAppUserName());
// 必需參數,應用內的用戶 id。 // 若應用內綁定 360 帳號和應用帳號,充值
//不分區服,充到統一的用戶帳戶,各區服角色都可使用, 則可用 360 用戶 ID 最大 32 //字符。
bundle.putString(ProtocolKeys.APP_USER_ID, pay.getAppUserId());
// 必需參數,應用訂單號,應用內必須惟一,最大 32 字符。
bundle.putString(ProtocolKeys.APP_ORDER_ID, pay.getAppOrderId());
// 可選參數,應用擴展信息 1,原樣返回,最大 255 字符。
bundle.putString(ProtocolKeys.APP_EXT_1, pay.getAppExt1());
// 可選參數,應用擴展信息 2,原樣返回,最大 255 字符。
bundle.putString(ProtocolKeys.APP_EXT_2, pay.getAppExt2());
Intent intent = new Intent(this, ContainerActivity.class);
intent.putExtras(bundle);
return intent;
}
/**
* 支付的回調
*/
protected IDispatcherCallback mPayCallback = new IDispatcherCallback() {
@Override
public void onFinished(String data) {
Log.d(TAG, "mPayCallback, data is " + data);
if(TextUtils.isEmpty(data)) {
return;
}
boolean isCallbackParseOk = false;
JSONObject jsonRes;
try {
jsonRes = new JSONObject(data);
// error_code 狀態碼:0 支付成功,-1 支付取消,1 支付失敗,-2 支付進行中。
// 請務必對 case 0、一、-1 加入處理語句,若是爲空會致使遊戲崩潰 // error_msg 狀態描述
int errorCode = jsonRes.optInt("error_code");
isCallbackParseOk = true;
switch (errorCode) {
case 0:
case 1:
case -1:
case -2: {
isAccessTokenValid = true;
String errorMsg = jsonRes.optString("error_msg");
String text = getString(R.string.pay_callback_toast, errorCode, errorMsg);
Toast.makeText(SdkUserBaseActivity.this, text, Toast.LENGTH_SHORT).show();
}
break;
case 4010201:
isAccessTokenValid = false;
Toast.makeText(SdkUserBaseActivity.this, R.string.access_token_invalid,
Toast.LENGTH_SHORT).show();
break;
case 4009911:
//QT 失效
isQTValid = false;
Toast.makeText(SdkUserBaseActivity.this, R.string.qt_invalid,
Toast.LENGTH_SHORT).show();
break;
default:
break;
}
} catch (JSONException e) {
e.printStackTrace();
}
// 用於測試數據格式是否異常。
if (!isCallbackParseOk) {
Toast.makeText(SdkUserBaseActivity.this, getString(R.string.data_format_error),
Toast.LENGTH_LONG).show();
}
}
};
接入提交遊戲角色數據信息:(可選客戶端接入仍是服務端接入,如下只展現客戶端接入示例)
數據提交時機:
一、玩家進入遊戲區服時調用該接口。
二、角色建立時調用該接口。
三、角色升級時調用該接口。
四、角色退出遊戲時調用該接口。
/**
角色信息採集接口
*/
protected void doSdkGetUserInfoByCP() {
HashMap eventParams=new HashMap();
//----------------------------參數設置說明--------------------
//如下列出的五項只是做爲參考,請按照上述表格中的參數說明進行補充添加
eventParams.put("zoneid",1);//當前角色所在遊戲區服 id
eventParams.put("zonename","刀塔傳奇 1 區");//當前角色所在遊戲區服名稱 eventParams.put("roleid","12345678");//當前角色 id
eventParams.put("rolename","三國風吹來的魚");//當前角色名稱 eventParams.put("type","levelUp");//角色信息接口觸發的場景
//----------------------------------------------------------
Matrix.statEventInfo(getApplicationContext(), eventParams);
}
參數說明:
接入切換帳號接口:
/**
* 使用 360SDK 的切換帳號接口
*
* @param isLandScape 是否橫屏顯示登陸界面
*/
protected void doSdkSwitchAccount(boolean isLandScape) {
Intent intent = getSwitchAccountIntent(isLandScape);
if (isSupportOffline) {
callback = mAccountSwitchSupportOfflineCB;//離線模式
}
Matrix.invokeActivity(this, intent, mAccountSwitchCallback);
}
/***
* 生成調用360SDK切換帳號接口的Intent
*
* @param isLandScape
* 是否橫屏
* @param isBgTransparent
* 是否背景透明
* @param clientId
* 即AppKey
* @return Intent
*/
private Intent getSwitchAccountIntent(boolean isLandScape) {
Intent intent = new Intent(appActivity, ContainerActivity.class);
// 界面相關參數,360SDK界面是否以橫屏顯示。
intent.putExtra(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE,
isLandScape);
// 必需參數,使用360SDK的切換帳號模塊。
intent.putExtra(ProtocolKeys.FUNCTION_CODE,
ProtocolConfigs.FUNC_CODE_SWITCH_ACCOUNT);
// 是否顯示關閉按鈕
intent.putExtra(ProtocolKeys.IS_LOGIN_SHOW_CLOSE_ICON, isShowClose);
// 可選參數,是否支持離線模式,默認值爲false
intent.putExtra(ProtocolKeys.IS_SUPPORT_OFFLINE, isSupportOffline);
// 可選參數,是否在自動登陸的過程當中顯示切換帳號按鈕
intent.putExtra(ProtocolKeys.IS_SHOW_AUTOLOGIN_SWITCH,
isShowSwitchButton);
// 可選參數,是否隱藏歡迎界面
intent.putExtra(ProtocolKeys.IS_HIDE_WELLCOME, isHideWellcome);
// 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑
// intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTRUE,
// getUiBackgroundPicPath());
// 可選參數,指定assets中的圖片路徑,做爲背景圖
// intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS,
// getUiBackgroundPathInAssets());
// -- 如下參數僅僅針對自動登陸過程的控制
// 可選參數,自動登陸過程當中是否不展現任何UI,默認展現。
intent.putExtra(ProtocolKeys.IS_AUTOLOGIN_NOUI, isAutoLoginHideUI);
// 可選參數,靜默自動登陸失敗後是否顯示登陸窗口,默認不顯示
intent.putExtra(ProtocolKeys.IS_SHOW_LOGINDLG_ONFAILED_AUTOLOGIN,
isShowDlgOnFailedAutoLogin);
// 測試參數,發佈時要去掉
intent.putExtra(ProtocolKeys.IS_SOCIAL_SHARE_DEBUG, isDebugSocialShare);
return intent;
}
// 切換帳號的回調
private IDispatcherCallback mAccountSwitchCallback = new IDispatcherCallback() {
@Override
public void onFinished(String data) {
// press back
if (isCancelLogin(data)) {
return;
}
// 顯示一下登陸結果
// Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show();
// TypeSDKLogger.d( "mAccountSwitchCallback, data is " + data);
// 解析access_token
mAccessToken = parseAccessTokenFromLoginResult(data);
}
};
// 支持離線模式的切換帳號的回調
private IDispatcherCallback mAccountSwitchSupportOfflineCB = new IDispatcherCallback() {
@Override
public void onFinished(String data) {
// press back
if (isCancelLogin(data)) {
return;
}
// 顯示一下登陸結果
// Toast.makeText(appActivity, data, Toast.LENGTH_LONG).show();
// TypeSDKLogger.d( "mAccountSwitchSupportOfflineCB, data is " + data);
// 解析access_token
mAccessToken = parseAccessTokenFromLoginResult(data);
}
};
parseAccessTokenFromLoginResult (String data) 此函數登陸時就有用到,解析TOKEN
接入退出接口:
/**
* 使用 360SDK 的退出接口
*
* @param isLandScape 是否橫屏顯示支付界面
*/
protected void doSdkQuit(boolean isLandScape) {
Bundle bundle = new Bundle();
// 界面相關參數,360SDK 界面是否以橫屏顯示。
bundle.putBoolean(ProtocolKeys.IS_SCREEN_ORIENTATION_LANDSCAPE, isLandScape);
// 可選參數,登陸界面的背景圖片路徑,必須是本地圖片路徑
bundle.putString(ProtocolKeys.UI_BACKGROUND_PICTRUE, "");
// 必需參數,使用 360SDK 的退出模塊。
bundle.putInt(ProtocolKeys.FUNCTION_CODE, ProtocolConfigs.FUNC_CODE_QUIT);
Intent intent = new Intent(this, ContainerActivity.class);
intent.putExtras(bundle);
Matrix.invokeActivity(this, intent, mQuitCallback);
}
// 退出的回調
private IDispatcherCallback mQuitCallback = new IDispatcherCallback() {
@Override
public void onFinished(String data) {
// TODO your job
}
};
接入銷燬接口:
@Override
protected void onDestroy() {
super.onDestroy();
Matrix.destroy(this);
}
遊戲 activity 生命週期接口:
//遊戲 Activity 必接 生命週期接口
public static void onStart(Activity activity)
//遊戲 Activity 必接生命週期接口
public static void onResume(Activity activity)
//遊戲 Activity 必接生命週期接口
public static void onPause(Activity activity)
//遊戲 Activity 必接生命週期接口
public static void onStop(Activity activity)
//遊戲 Activity 必接生命週期接口
public static void onReStart(Activity activity)
//遊戲 Activity 必接生命週期接口
public static void onActivityResult (Activity activity,int requestCode, int resultCode, Intent data)
//遊戲 Activity 必接生命週期接口
public static void onNewIntent (Activity activity,Intent intent)
代碼混淆要求
若是遊戲發佈時採用proguard進行代碼混淆,請在proguard配置文件加入如下代碼,以免對SDK進行混淆,不然會形成SDK部分功能不正常。
-keep class a.a.a.** { *; }
-keep class cn.pp.** { *; }
-keep class com.alipay.** {*;}
-keep class com.qihoo.** {*;}
-keep class com.qihoo360.** { *; }
-keep class com.qihoopp.** { *; }
-keep class com.yeepay.safekeyboard.** { *; }
-keep class com.amap.** {*;}
-keep class com.aps.** {*;}
-keep class com.iapppay.** {*;}
-keep class com.ipaynow.** {*;}
-keep class com.junnet.heepay.** {*;}
-keep class com.tencent.mm.** {*;}
-keep class com.ta.utdid2.** {*;}
-keep class com.ut.device.** {*;}
-keep class com.qihoo.sdkplugging.host.** {*;}
-keep public class com.qihoo.gamecenter.sdk.matrix.PluggingHostProxy {*;}
-dontwarn cn.pp.**
-dontwarn com.alipay.android.app.**
-dontwarn com.qihoo.**
-dontwarn com.qihoo360.**
-dontwarn com.qihoopp.**
-dontwarn com.yeepay.safekeyboard.**
-dontwarn com.amap.**
-dontwarn org.apache.http.conn.ssl.SSLSocketFactory
若是想了解更多,請聯繫咱們或關注官網
瞭解更多:www.typesdk.com問題解答:1771930259聯繫郵箱:qianyuzhou@typesdk.com項目地址:https://github.com/typesdk