官方文档及SDK的下载地址为:http://dev.360.cn/wiki/index/id/73

 

在接入之前,需先在360后台创建游戏,获取一些接入参数。

 

客户端所需要参数包括:APPID、APPKEY、PRIVATEKEY 三个值填写在 AndroidManifest 文件中,不能使用@string 引用;禁止把 AppSecret 保存在手机客户端,AndroidManifest 中存放的是 Private Key,而非 App-Secret。

Private Key 的算法为:QHOPENSDK_PRIVATEKEY = MD5(appSecret + "#" + appKey),格式为 32 位小写。

 

准备工作做为,正式开始接入,首先肯定是把所需要的资源如JAR包之类的复制到我的工程中去。

我这边的接入环境是Eclipse

 

打开我们下载好解压出来的文档目录找到所需要依赖的JAR包


sdk接入java的示例 sdk接入流程_sdk接入java的示例

红框所示就是我们Eclipse所需要的资源文件了。

把assets内的文件复制到我们自己工程中的assets目录内。

把libs内的文件复制到我们自己工程中的libs目录内。

下图中红框内的文件夹按自己所需要复制

sdk接入java的示例 sdk接入流程_sdk接入java的示例_02

至于demo工程如何创建在上一篇的接入文档中有详细教程,请至:




sdk接入java的示例 sdk接入流程_xml_03


复制完成之后,我们的demo目录应该是多了这些目录

至此,我们已经把所有需要的东西都复制到了我们的demo工程中。

 

首先我们打开我们工程的AndroidManifest.xml文件。



sdk接入java的示例 sdk接入流程_xml_04


然后复制以下代码


<?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应该是这个样子的

sdk接入java的示例 sdk接入流程_sdk接入java的示例_05

然后把下面的代码复制进去,注意别把第一行的代码覆盖了。

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这里右键

sdk接入java的示例 sdk接入流程_文件复制_06

名字输入:QihooPayInfo

sdk接入java的示例 sdk接入流程_文件复制_07

这样就会在这边多出一个类文件,我们打开他

sdk接入java的示例 sdk接入流程_sdk接入java的示例_08

把下面的代码复制到下图标记处

sdk接入java的示例 sdk接入流程_android_09

代码:


// 必需参数,用户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
TODO
       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);

 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());

 intent.putExtra(ProtocolKeys.UI_BACKGROUND_PICTURE_IN_ASSERTS,  
 getUiBackgroundPathInAssets());


 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、-1 加入处理语句,如果为空的会导致游戏崩溃。

/**     
 360SDK 的支付接口     
 *     
     
     
     
 */
 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),
" :
 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 可以根据需求选择使用 带有收银台的支付模
        
        
         //  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     

*     
     
     
 *     
 * @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);                
0 支付成功,-1 支付取消,1 支付失败,-2 支付进行中。                
 case 0、1、-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:                        
                        
 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();            
 }        
 }
 };

接入提交游戏角色数据信息:(可选客户端接入还是服务端接入,以下只展示客户端接入示例)

数据提交时机:




4、角色退出游戏时调用该接口。

/**
 角色信息采集接口 
 */
 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 生命周期接口:


public static void onStart(Activity activity) 

 public static void onResume(Activity activity) 

 public static void onPause(Activity activity) 

 public static void onStop(Activity activity) 

 public static void onReStart(Activity activity) 

 public static void onActivityResult (Activity activity,int requestCode, int resultCode, Intent data)

 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