# 1.1 申请账号

注册申请凡泰极客开发者账号,申请AppId,AppKey,详细请咨询相关对接人

# 1.2 配置仓库地址

在项目的顶层build.gradle中配置如下

buildscript {
    repositories {
        google()
        jcenter()
    }
    dependencies {
        classpath "com.android.tools.build:gradle:3.5.1"
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.50"
    }
}

allprojects {
    repositories {
        google()
        jcenter()
        maven { url "https://dl.bintray.com/thelasterstar/maven/" }
        maven { url "https://dl.bintray.com/drummer-aidan/maven" }
        maven { url "https://jitpack.io" }
        maven {
            url "https://gradle.finogeeks.club/repository/finogeeks/"
            credentials {
                username "gradle"
                password "ftjk@@123321"
            }
        }
    }
}

# 1.3 添加依赖库

FinoChat Android sdk可以直接通过gradle添加依赖集成:

dependencies {
	//finochatsdk 版本号替换为自己要使用的版本
	implementation “com.finogeeks.finochat.sdk:finochatsdk:latest.release”
}

# 1.4 金易联接入

金易联分为两个端,一个是用于客户发起咨询的客户端,另一个是用于员工服务客户,处理工单的员工端,可以统一于一个项目中,也可以分开为两个项目,我们提供的demo是合在一个项目里的。可自行选择;

# 1.5 sdk初始化

在Applicaion里的onCreate()里进行初始化操作,示例如下。

public class FinoChatApplication extends MultiDexApplication {

    private static final String LOG_TAG = "FinoChatApplication";

    @Override
    public void onCreate() {
        super.onCreate();

        String processName = processName();
        if (TextUtils.isEmpty(processName)) {
            return;
        }

        if (processName.contains(":FinApp")) {
            // 小程序进程不需要初始化FinChat SDK相关的内容
            return;
        }

        if (!BuildConfig.DEBUG) {
            // Bugly
            CrashReport.initCrashReport(getApplicationContext(), "c13f0687d7", BuildConfig.DEBUG);
            CrashReport.setAppVersion(getApplicationContext(), BuildConfig.VERSION_NAME);
            CrashReport.setAppChannel(this, BuildConfig.FLAVOR);
        }

        if (BuildConfig.DEBUG) {
            SpiderMan.init(this);
        }

        SharedPreferences p = getSharedPreferences("ext", MODE_PRIVATE);

        FinoChatOption options = new FinoChatOption();
        options.setLogLevel(android.util.Log.VERBOSE);
        options.setAppKey(BuildConfig.KEY);
        options.setAppType(BuildConfig.AppType);
        String url = p.getString("apiUrl", "");
        assert url != null;
        if (url.isEmpty()) {
            options.setApiURL(BuildConfig.API);
        } else {
            options.setApiURL(url);
        }
        options.setAppId("3");
        options.setApiPrefix("/api/v1");

        // 主题配置
        LinkedHashMap<String, Integer> themeMap = new LinkedHashMap<>(11);
        themeMap.put("深邃蓝", R.style.Theme_Blue);
        themeMap.put("皇家蓝", R.style.Theme_White);
        themeMap.put("喜庆红", R.style.Theme_Red);
        themeMap.put("热情红", R.style.Theme_ICBC_Red);
        themeMap.put("高雅金", R.style.Theme_ICBC_GOLD);
        themeMap.put("午夜蓝", R.style.Theme_CGWS);
        themeMap.put("天空蓝", R.style.Theme_FCS);
        themeMap.put("大红", R.style.Theme_JSB);
        themeMap.put("热带橘", R.style.Theme_GDRC_ORGANGE);
        themeMap.put("钻石蓝", R.style.Theme_OCT);
        themeMap.put("玻璃蓝", R.style.Theme_TAMP);
        options.setThemeMap(themeMap);

        // 通知栏图标
        options.getNotification().notificationIcon = R.drawable.notification;
        options.getNotification().notificationForeground = false;

        options.setAppDebug(BuildConfig.DEBUG);
        options.setSdkVersion(com.finogeeks.finochat.BuildConfig.VERSION_NAME);

        // 运行时配置
        options.setAppletApiURL(options.getApiURL());
        options.setAppletApiPrefix(BuildConfig.APPLET_API_PREFIX);
        options.setAppletAppKey(BuildConfig.APPLET_KEY);
        options.setAppletAppSecret(BuildConfig.APPLET_SECRET);

        // 配置微信分享参数
        FinoChatOption.ShareParams shareParams = new FinoChatOption.ShareParams();
        shareParams.wechatAppId = BuildConfig.WECHAT_APPID;
        shareParams.miniProgramId = BuildConfig.MINIPROGRAM_ID;
        options.setShareParams(shareParams);

        // 金易联小程序配置
        FinoChatOption.IShareWxAppletCallback shareJgj = () -> {
            String fcid = ServiceFactory.getInstance().getSessionManager().getCurrentSession().getMyUserId();

            String id = "gh_281bc08c5aee";
            String name = "凡泰金易联";

            if (options.getApiURL().equals("https://swan.finogeeks.com")) {

                // 我们自己
                if (fcid.contains(":000000")) {
                    id = "gh_f69f0fba0dd7";
                    name = "金易联Pro";
                }

                // SAAS个人体验
                if (fcid.contains(":666666")) {
                    id = "gh_281bc08c5aee";
                    name = "凡泰金易联";
                }

            } else {

                if (fcid.contains(":000000")) {
                    id = "gh_bafa60b51951";
                    name = "金易联测试号Zero";
                }

                if (fcid.contains(":666666")) {
                    id = "gh_15edcb9a59f4";
                    name = "金易联测试号";
                }
            }

            if (options.getApiURL().equals("https://tamp.fdep.cn") && fcid.contains(":111111")) {
                id = "gh_fb3c9a5fc5ac";
                name = "盈米测试号zero";
            }

            FinoChatOption.ShareAppletParams shareAppletParams = new FinoChatOption.ShareAppletParams();
            shareAppletParams.miniProgramId = id;
            shareAppletParams.path = "pages/login/index";
            shareAppletParams.title = name;
            shareAppletParams.name = name;
            shareAppletParams.description = "您身边的服务专家";
            shareAppletParams.type = BuildConfig.ENV_VERSION;
            shareAppletParams.shareType = "SWAN_IM";
            return shareAppletParams;
        };
        Map<String, FinoChatOption.IShareWxAppletCallback> applets = new HashMap<>();
        applets.put("金易联在线", shareJgj);
        options.swan.shareAppletParams = applets;

        // 邀请配置
        options.swan.inviteCallback = () -> {

            // 一创邀请配置示例
            FinoChatOption.InviteParams inviteParams = new FinoChatOption.InviteParams();
            Employee employee = new Gson().fromJson(Preferences.INSTANCE.getEmployee(), Employee.class);
            if (options.getApiURL().equals("https://digit.95358.com")) {
                inviteParams.loginUrl = String.format("https://www.95358.com/fcscoauth/oauth/authorize?client_id=IF08-06411&redirect_uri=%s/webapps/pages/authorize&response_type=token&scope=api_info", options.getApiURLTrimmed());
                inviteParams.openAccountUrl = String.format("https://kh.fcsc.com/fcsc/acct4/index.html?bn=%s&bi=%s", employee.getGroupNumber(), employee.getAccount());
            }

            if (options.getApiURL().equals("https://digittest.95358.com")) {
                inviteParams.loginUrl = String.format("https://wxnewtest.fcsc.com/fcscoauth/oauth/authorize?client_id=IF08-0641&redirect_uri=%s/webapps/pages/authorize&response_type=token&scope=api_info", options.getApiURLTrimmed());
                inviteParams.openAccountUrl = String.format("https://tctest.fcsc.com:9008/fcsc/acct4/index.html?bn=%s&bi=%s", employee.getGroupNumber(), employee.getAccount());
            }

            if (options.getApiURL().equals("https://swan.finogeeks.club")) {
                inviteParams.loginUrl = String.format("https://wxnewtest.fcsc.com/fcscoauth/oauth/authorize?client_id=IF08-0641&redirect_uri=%s/webapps/pages/authorize&response_type=token&scope=api_info", options.getApiURLTrimmed());
                inviteParams.openAccountUrl = String.format("https://tctest.fcsc.com:9008/fcsc/acct4/index.html?bn=%s&bi=%s", employee.getGroupNumber(), employee.getAccount());
            }

            return inviteParams;
        };

        options.getSettings().isSaas = p.getBoolean("isSaas", true);

        FinoChatClient.getInstance().initFinoChatSession(this, options, new FinoCallBack<Void>() {
            @Override
            public void onSuccess(Void result) {
                Log.i(LOG_TAG, "init success");
            }

            @Override
            public void onProgress(int progress, String status) {
            }

            @Override
            public void onError(int code, String message) {
                Log.e(LOG_TAG, "code:" + code + message);
                if (code != FinoError.NO_HISTORY_TOKEN_FOUND) {
                    new Handler(Looper.getMainLooper())
                            .post(() -> ToastsKt.toast(FinoChatApplication.this, "code:" + code + ",message:" + message));
                }
            }
        });

        // 监听登出操作
        FinoChatClient.getInstance().getNotificationManager().addObserver(INotificationManager.EVENT_LOGOUT, (s, map) -> {
            Intent i = getPackageManager().getLaunchIntentForPackage(getPackageName());
            if (i != null) {
                i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
                        | Intent.FLAG_ACTIVITY_CLEAR_TASK
                        | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
                startActivity(i);
            }
        });
    }

    private String processName() {
        ActivityManager activityManager = ((ActivityManager) getSystemService(Context.ACTIVITY_SERVICE));
        if (activityManager == null) {
            return null;
        }
        List<ActivityManager.RunningAppProcessInfo> runningAppProcessInfoList = activityManager.getRunningAppProcesses();
        for (ActivityManager.RunningAppProcessInfo processInfo : runningAppProcessInfoList) {
            if (processInfo.pid == Process.myPid()) {
                return processInfo.processName;
            }
        }
        return null;
    }
}

# 1.6 主题配置示例

1.在styles.xml里自定义主题

    <style name="Theme_ICBC_GOLD">
        <item name="TP_color_normal">#A6844F</item>//主题色普通态

        <item name="TP_color_pressed">#584529</item>//主题色点击态

        <item name="TP_color_disable">#D2C1A7</item>//主题色不可点击态

        <item name="Bubble_Host_solid_color">#FFF5E7</item>//本方气泡填充

        <item name="Bubble_Host_stroke_color">#E4DACA</item>//本方气泡描边

        <item name="Bubble_Guest_solid_color">#FFFFFF</item>//对方气泡填充

        <item name="Bubble_Guest_stroke_color">#CFCFCF</item>//对方气泡描边

        <item name="button_solid_normal">#A6844F</item>//Btn普通态填充

        <item name="button_solid_pressed">#584529</item>//Btn点击态填充

        <item name="button_solid_disable">#D2C1A7</item>//Btn不可点击填充


        <item name="NAV_color">#FAFAFA</item>//Toolbar背景色

        <item name="NAV_TP_color_normal">#A6844F</item>//Toolbar切图/文字普通态(包括调用系统的返回箭头)

        <item name="NAV_TP_color_pressed">#584529</item>//Toolbar切图/文字点击态(包括调用系统的返回箭头)

        <item name="NAV_TP_color_disable">#D2C1A7</item>//Toolbar切图/文字不可点击态(包括调用系统的返回箭头)

        <item name="NAV_title_color">#333333</item>//Toolbar标题文字颜色

        <item name="NAV_line">#B0B0B0</item>//Toolbar分割线颜色


        <item name="switch_solid_enable_off">#FFFFFF</item>//开关可操作_关闭

        <item name="switch_solid_enable_on">#A6844F</item>//开关可操作_打开

        <item name="switch_solid_disable_off">#FFFFFF</item>//开关不可操作_关闭

        <item name="switch_solid_disable_on">#D2C1A7</item>//开关不可操作_打开
    </style>

2.代码配置;

       Map themeMap = new LinkedHashMap();
       themeMap.put("热情红", R.style.Theme_ICBC_Red);
       themeMap.put("高雅金", R.style.Theme_ICBC_GOLD);
       options.setThemeMap(themeMap);

# 1.7 员工端接入

迁移AndroidX, gradle.properties配置如下:

android.useAndroidX=true
android.enableJetifier=true

build.gradle配置示例如下:

其中API为配置的服务器地址,AppType为“STAFF”表示为员工端。KEY是由凡泰签发给app的相关开关配置。
import java.util.concurrent.TimeUnit

apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'


/**
 * 以git tag的数量作为其版本号
 * @return tag的数量
 */
def getAppVersionCode() {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'git', 'tag', '--list'
        standardOutput = stdout
    }
    return stdout.toString().split("\n").size()
}
/**
 * 从git tag中获取应用的版本名称
 * @return git tag的名称
 */
def getAppVersionName() {
    def stdout = new ByteArrayOutputStream()
    exec {
        commandLine 'git', 'describe', '--abbrev=0', '--tags'
        standardOutput = stdout
    }
    return stdout.toString().replaceAll("[\\t\\n\\r]", "")
}

static def getApplicationIdPrefix() {
    return "com.finogeeks.finchat.swanapp"
}

android {
    compileSdkVersion rootProject.ext.android.compileSdkVersion
    buildToolsVersion rootProject.ext.android.buildToolsVersion
    defaultConfig {
        applicationId "com.finogeeks.finochatapp"
        minSdkVersion rootProject.ext.android.minSdkVersion
        targetSdkVersion rootProject.ext.android.targetSdkVersion
        versionCode getAppVersionCode()
        versionName getAppVersionName()
        multiDexEnabled true
        vectorDrawables.useSupportLibrary = true
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
        ndk {
            abiFilters "armeabi", "armeabi-v7a"
        }

    }

    buildTypes {

        debug {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            multiDexKeepProguard file('multidex-config.pro')
            ndk {
                abiFilters "armeabi", "x86", "armeabi-v7a"
            }
        }

        release {
            minifyEnabled true
            shrinkResources true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            multiDexKeepProguard file('multidex-config.pro')
            ndk {
                abiFilters "armeabi", "armeabi-v7a"
            }
        }
    }

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    repositories {
        flatDir {
            dirs 'libs'
        }
    }

    packagingOptions {
        doNotStrip '*/mips/*.so'
        doNotStrip '*/mips64/*.so'
        exclude 'META-INF/proguard/androidx-annotations.pro'
    }

    dexOptions {
        preDexLibraries = false
        keepRuntimeAnnotatedClasses false
    }

    lintOptions {
        checkReleaseBuilds false
        // Or, if you prefer, you can continue to check for errors in release builds,
        // but continue the build even when errors are found:
        abortOnError false
    }

    kapt {
        arguments {
            arg("AROUTER_MODULE_NAME", project.getName())
        }
    }

    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            def name = "FinSwanApp_${defaultConfig.versionName}_${variant.productFlavors[0].name}_${variant.buildType.name}.apk"
            output.outputFileName = new File(name)
        }
    }

    flavorDimensions "default"
    productFlavors {

        cloudemptest {
            dimension "default"
            applicationId getApplicationIdPrefix() + ".cloud.emp"
            resValue "string", "app_name", "金易联"
            buildConfigField "String", "API", "\"https://swan.finogeeks.club\""
            buildConfigField "String", "KEY", "\"T5tEkTEGvTiVohZkNRT/R8/8oVGzI0Gd29rjO44VTx5CrRFY2soA3Ep6BxbYfMX/cVOlJ8h8XaDBtDsquyGxc4klthnkauL6J92Tg6+jzFNCP2jdsUfDhp9JuxNH2x/+iSW2GeRq4von3ZODr6PMU+qB67pGOR01B3BG0PWHCaqQ\""
            buildConfigField "String", "AppType", "\"STAFF\""

            buildConfigField "String", "WECHAT_APPID", "\"wx3bfb3f78b4ade165\""
            buildConfigField "String", "MINIPROGRAM_ID", "\"gh_281bc08c5aee\""
            buildConfigField "String", "ENV_VERSION", "\"trial\""
            buildConfigField "boolean", "isSettings", "true"

            buildConfigField "String", "APPLET_KEY", "\"22LyZEib0gLTQdU3MUauAbsrrFOVuk+udZug3+/S3PTCc+OHSdLY1KLqZZl47eQ7AA==\""
            buildConfigField "String", "APPLET_SECRET", "\"f4cbec94a01a28b5\""
            buildConfigField "String", "APPLET_API_PREFIX", "\"/api/v1/mop\""

            resValue "string", "app_scheme", "jfbempcloud"
            resValue "drawable", "app_icon", "@mipmap/ic_launcher"

            manifestPlaceholders = [amap_api_key: "48f1cf8d36e72f8bf036242bfd61ebc0",
                                    app_icon    : "@mipmap/ic_launcher"]
        }
    }
}

configurations.all {
    // 变化模块的缓存过期时间
    resolutionStrategy.cacheChangingModulesFor 0, TimeUnit.SECONDS
    // 动态版本的缓存过期时间
    resolutionStrategy.cacheDynamicVersionsFor 0, TimeUnit.SECONDS
}

dependencies {

    def deps = rootProject.ext.dependencies

    implementation fileTree(dir: 'libs', include: ['*.jar'])

    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'

    androidTestImplementation 'com.android.support.test:runner:1.0.1'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1'

    implementation "androidx.multidex:multidex:2.0.0"

    implementation 'com.tencent.bugly:crashreport:2.6.6'
    implementation 'pl.droidsonroids.gif:android-gif-drawable:1.2.8'

    implementation(deps.finochatsdk)

    implementation "me.leolin:ShortcutBadger:1.1.21@aar"

    implementation("com.simple:spiderman:1.1.1") {
        exclude group: "com.android.support"
    }

    implementation('com.romandanylyk:pageindicatorview:1.0.2') {
        exclude group: "com.android.support"
    }
}

repositories {
    mavenCentral()
}

页面组装

客户端页面包括,会话页面、工作页面、通讯录页面和我的页面,通过Fragment的形式以供组装。 ``` FinoChatClient.getInstance().chatUIManager().conversationFragment(), ARouter.getInstance().navigation(CustomerService.class).workFragment(), FinoChatClient.getInstance().chatUIManager().contactFragment(), ARouter.getInstance().navigation(CustomerService.class).employeeFragment() ```

# 1.8 客户端接入

build.gradle配置示例如下:

其中API为配置的服务器地址,AppType为“RETAIL”表示为客户端。KEY是由凡泰签发给app的相关开关配置。
        cloudcus {
            dimension "default"
            applicationId getApplicationIdPrefix() + ".cloud.cus"
            resValue "string", "app_name", "金易联"
            buildConfigField "String", "API", "\"https://mini.finogeeks.club\""
            buildConfigField "String", "KEY", "\"3Z7dQqy0+YqVigRWkVribyJU22ARzISXW6/h6Ys0sBxde0SYn1ea2hbtccCLupvgxpc8BHezyaia4e9+fxQp9PvAn7WIbV+cHWKbbl0sRIyJJbYZ5Gri+ifdk4Ovo8xTn+oF7giS4Trj9l0Mk57V1IklthnkauL6J92Tg6+jzFNUMfyp3K+TupjFkmtnkYmQoA==\""
            buildConfigField "String", "AppType", "\"RETAIL\""

            buildConfigField "String", "WECHAT_APPID", "\"wx3bfb3f78b4ade165\""
            buildConfigField "String", "ENV_VERSION", "\"release\""

            resValue "string", "app_scheme", "jfbcustcloud"
            resValue "drawable", "app_icon", "@mipmap/ic_launcher_cus"

            manifestPlaceholders = [amap_api_key: "72156b499ee055768f29fd857a494af6",
                                    app_icon    : "@mipmap/ic_launcher_cus"]

        }

页面组装

客户端页面包括,会话页面和我的页面,通过Fragment的形式以供组装:
// 会话页面
FinoChatClient.getInstance().chatUIManager().conversationFragment(),
// 我的页面
ARouter.getInstance().navigation(CustomerService.class).retailFragment()

别注意

客户端的登录分为三级,分别是游客,手机账号和交易账号登录,我们一般会在闪屏页做一次匿名登录以完成sdk的初始化
// 登录游客账号
FinoChatClient.getInstance().accountManager().login(RetailAccountHelper.Companion.getAndroidId(this.getApplicationContext()), RetailAccountHelper.Companion.getDeviceIdPassword(), RetailAccountHelper.Companion.getACCOUNT_LEVEL_DEVICE(), new FinoCallBack<Map<String, Object>>() {
    @Override
    public void onSuccess(Map<String, Object> result) {

    }

    @Override
    public void onError(int progress, String status) {
    }

    @Override
    public void onProgress(int code, String message) {
    }
});
// 手机账号登录:
RetailAccountHelper.loginAcitivityLevel = RetailAccountHelper.ACCOUNT_LEVEL_PHONE
FinoChatClient.getInstance().accountManager().login(username, password, RetailAccountHelper.ACCOUNT_LEVEL_PHONE, object : FinoCallBack<Map<String, Any>> {
                            //回调
                            override fun onSuccess(result: Map<String, Any>?) {
                                RetailAccountHelper.reloadLauncherActivity()
                            }

                            override fun onProgress(progress: Int, status: String) {
                                context?.startActivity<SplashActivity>()
                            }

                            override fun onError(code: Int, message: String) {

                            }
                        })
// 交易账号登录
FinoChatClient.getInstance().accountManager().login(username, password, RetailAccountHelper.ACCOUNT_LEVEL_TRADE, object : FinoCallBack<Map<String, Any>> {
            //回调
            override fun onSuccess(result: Map<String, Any>) {

                val oldRoomId = intent?.getStringExtra("oldRoomId")
                if (oldRoomId != null) {
                RetailAccountHelper.startOrderRoomAutoOldRoomId = oldRoomId

                    RetailAccountHelper.isHomeActivityComplete = false

                    // 转移工单
                    if (RetailAccountHelper.isTranspose())
                        RetailAccountHelper.transposeOrderRetail(oldRoomId)
                }

                RetailAccountHelper.reloadLauncherActivity()
            }

            override fun onProgress(progress: Int, status: String) {
                startActivity(Intent(this@TradingAccountLoginAcitivity, SplashActivity::class.java))
            }

            override fun onError(code: Int, message: String) {
                //Toast.makeText(this@TradingAccountLoginAcitivity, message, Toast.LENGTH_LONG).show()
                loginGuest(this@TradingAccountLoginAcitivity)
            }
        })

# 1.9 第三方推送

ServiceFactory.getInstance().getThirdPartyPusher().push(this, "pushKey", null);

# 1.10 swan相关接口

ISwanManager manger = ServiceFactory.getInstance().getSwanManager()

public interface ISwanManager extends IProvider {

    /**
     * 根据id获取员工信息
     * @param id 员工id
     */
    void fetchUserInfo(@NonNull String id, ApiCallback<ResponseBody> callback);

    /**
     * 根据id获取员工详情
     * @param id 员工id
     */
    void fetchUserDetail(@NonNull String id, ApiCallback<ResponseBody> callback);

    /**
     * 工单列表界面
     * @param orderGroup 1为抢单,2为派单
     */
    void orderActivity(Context context, int orderGroup);

    /**
     * 抢单列表数据
     *
     * @param id   员工id
     * @param page 从1开始
     * @param size 每页大小
     */
    void fetchRushOrders(String id, int page, int size, ApiCallback<ResponseBody> callback);

    /**
     * 派单列表数据
     *
     * @param id   员工id
     * @param page 从1开始
     * @param size 每页大小
     */
    void fetchDispatchOrders(String id, int page, int size, ApiCallback<ResponseBody> callback);

    /**
     * 文件盘界面
     */
    void netDiskActivity(Context context);

    /**
     * 共享盘界面
     * @param sharedDiskPermission 需要根据员工信息来计算
     */
    void shareDiskActivity(Context context, Boolean sharedDiskPermission);

    /**
     * 营销海报界面
     */
    void posterActivity(Context context);

    /**
     * 未读信息聚合
     */
    void unreadSummary(ApiCallback<ResponseBody> callback);

    /**
     * 二维码
     */
    void qrCode(String queryString, ApiCallback<String> callback);

    /**
     * 个人信息界面
     */
    void personalActivity(Context context);

    /**
     * 通知界面
     */
    void noticeActivity(Context context);

    /**
     * 工单记录界面
     */
    void orderRecordActivity(Context context);

    /**
     * 工单记录
     * @param id   员工id
     * @param page 从1开始
     * @param size 每页大小
     */
    void orderRecord(String id, int page, int size, ApiCallback<ResponseBody> callback);

    /**
     * 营销线索
     */
    void fetchMarketingClues(ApiCallback<ResponseBody> callback);

    /**
     * 转发助手列表
     * @param page 从1开始
     * @param size 每页大小
     */
    void fetchFeeds(int page, int size, ApiCallback<ResponseBody> callback);

    /**
     * 转发文章到工作室
     *
     * @param id 文章id
     */
    void forwardArticle(String id, ApiCallback<ResponseBody> callback);

    /**
     * 获取抢派单开关
     */
    void fetchOrderNotice(ApiCallback<ResponseBody> callback);

    /**
     * 修改抢派单开关
     */
    void updateOrderNotice(boolean rush, boolean dispatch, ApiCallback<Boolean> callback);

    /**
     * 注入绘图api
     * @param activity,
     */
    void injectDrawApi(Activity activity);
}

# 1.11 小程序跳转示例

    val appId = "adviser_zone"
    val path = "/pages/visitor/visitor-detail"
    val queryString = "fcid=$mUserId&name=$displayName&avatar=${ImageLoaders.userAvatarLoader().getUrl(mUserId)}"
    val encodedQueryString = URLEncoder.encode(queryString, "utf-8")
    Common.startApplet(this, appId, path, encodedQueryString)

# 1.12 工单推送监听

    FinoChatClient.getInstance().getNotificationManager().addObserver(INotificationManager.EVENT_ORDER, (s, map) -> {

    });

# 1.13 未读消息监听

    FinoChatClient.getInstance().badgeManager.addBadgeCountUpdateListener(object : IBadgeManager.OnBadgeCountUpdateListener {
        override fun onBadgeCountUpdate(badgeManager: IBadgeManager) {
            tab_message.badgeCount = badgeManager.unReadMessageCount
        }
    })

更多详情请参考demo工程demo (opens new window) 更多接口信息请参考api doc (opens new window)