游戏sdk接入教程:360渠道SDK接入

官方文档及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包

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

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

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

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


至于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;

   }

 

调用支付接口:

注意:

1、 必选参数不能为空不能为 0,否则支付失败。

2、 参数名,以 ProtocolKeys 中定义的常量为准。

3、 请务必对 case 01-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运行定额支付流程;

        *金额数为0360SDK运行不定额支付流程。

        * @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 运行定额支

//付流程; 金 额数为 0360SDK 运行不定额支付流程。                                                                

       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 状态码:支付成功,-1 支付取消,支付失败,-2 支付进行中。                

// 请务必对 case 01-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();            

}        

}

};

 

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

数据提交时机:

1、玩家进入游戏区服时调用该接口。

2、角色创建时调用该接口。

3、角色升级时调用该接口。

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 生命周期接口:

//游戏 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
联系邮箱:[email protected]
项目地址:https://github.com/typesdk


猜你喜欢

转载自blog.csdn.net/kasimshi/article/details/73497903