FinClip为企业提供小程序生态圈技术产品,开发者可在FinClip小程序开发帮助中心找到相关FinClip小程序指引

# Android 集成

集成样例代码

我们提供了 DEMO 工程,开发者可以在Github(国外) (opens new window)Gitee(国内) (opens new window) 获取集成样例代码。

# 1. 获取凭据

请注意

集成 SDK 需要先在 FinClip 平台中创建应用绑定小程序,获得每个应用专属的SDK KEYSDK SECRET后,随后就可以在集成 SDK 时填写对应的参数。打开小程序时 SDK 会自动初始化,并校验SDK KEYSDK SECRETBundleID(Application ID)是否正确。

您可以 【点击这里】 查看如何获取所需要的SDK KEYSDK SECRET。请务必确认集成 SDK 时填写的参数正确,否则会导致小程序无法打开。

# 2. 导入SDK

# 2.1 通过Gradle依赖

# 2.1.1 在工程的build.gradle中需要配置的内容

在工程的build.gradle中添加 maven 仓库的地址:

maven {
    url "https://gradle.finogeeks.club/repository/applet/"
    credentials {
		username "applet"
		password "123321"
	}
}

由于 SDK 中部分代码使用了 Kotlin 来编写,因此需要工程的build.gradle中添加 Kotlin 的 gradle 插件:

classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.3.61"

工程的build.gradle的完整配置如下:

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

allprojects {
    repositories {
        google()
        jcenter()
        maven {
            url "https://gradle.finogeeks.club/repository/applet/"
            credentials {
                username "applet"
                password "123321"
            }
        }
    }
}

task clean(type: Delete) {
    delete rootProject.buildDir
}

# 2.1.2 在gradle中依赖SDK

gradle文件的dependencies中添加对finapplet的依赖:

implementation 'com.finogeeks.lib:finapplet:x.y.z' // x.y.z须替换为具体的版本号

注意

  1. SDK 中的动态库是被加固过的,被加固过的动态库在编译打包时不能被压缩,否则加载的时候会报错。
  2. finapplet 2.42.5(不含) 之前的版本依赖的是sdkcore(com.finogeeks.finochat.sdk:sdkcore)。
  3. finapplet 2.42.5-2.43.3 版本依赖的是finclipcore(com.finogeeks.finclip.sdk:finclipcore)。
  4. finapplet 2.43.5(含) 以及之后的版本依赖的是sdkcore(com.finogeeks.finclip.sdk:sdkcore)。

因此需要在 App module 下的build.gradle中增加doNotStrip配置:

packagingOptions {
    // libsdkcore.so是被加固过的,不能被压缩,否则加载动态库时会报错
    //finapplet 2.42.5之前以及2.43.3之后的版本,使用这个
    doNotStrip "*/x86/libsdkcore.so"
    doNotStrip "*/x86_64/libsdkcore.so"
    doNotStrip "*/armeabi/libsdkcore.so"
    doNotStrip "*/armeabi-v7a/libsdkcore.so"
    doNotStrip "*/arm64-v8a/libsdkcore.so"
    
    //finapplet 2.42.5--2.43.3版本,使用这个
    //doNotStrip "*/x86/libfinclipcore.so"
    //doNotStrip "*/x86_64/libfinclipcore.so"
    //doNotStrip "*/armeabi/libfinclipcore.so"
    //doNotStrip "*/armeabi-v7a/libfinclipcore.so"
    //doNotStrip "*/arm64-v8a/libfinclipcore.so"
}

完整的配置如下:

apply plugin: 'com.android.application'

android {
    buildToolsVersion '28.0.3'
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.finogeeks.finappletdemo"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    packagingOptions {
        // libsdkcore.so是被加固过的,不能被压缩,否则加载动态库时会报错
        doNotStrip "*/x86/libsdkcore.so"
        doNotStrip "*/x86_64/libsdkcore.so"
        doNotStrip "*/armeabi/libsdkcore.so"
        doNotStrip "*/armeabi-v7a/libsdkcore.so"
        doNotStrip "*/arm64-v8a/libsdkcore.so"
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'com.finogeeks.lib:finapplet:x.y.z' // x.y.z须替换为具体的版本号
}

# 2.2 通过aar依赖

若通过Gradle依赖可以略过本条。

通过aar文件进行依赖需要自行配置其它第三方库的依赖,以下对各SDK涉及的第三方库进行说明。

# 2.2.1 FinclipCore / SdkCore

没有依赖任何第三方库,但是要根据不同版本的finapplet做一下设置调整。

注意:

  1. SDK 中的动态库是被加固过的,被加固过的动态库在编译打包时不能被压缩,否则加载的时候会报错。
  2. finapplet 2.42.5(不含) 之前的版本依赖的是sdkcore(com.finogeeks.finochat.sdk:sdkcore)。
  3. finapplet 2.42.5-2.43.3 版本依赖的是finclipcore(com.finogeeks.finclip.sdk:finclipcore)。
  4. finapplet 2.43.5(含) 以及之后的版本依赖的是sdkcore(com.finogeeks.finclip.sdk:sdkcore)。

# 2.2.2 核心SDK(finapplet)

// appcompat-v7
implementation "com.android.support:appcompat-v7:23.0.0"

// support-v4
implementation "com.android.support:support-v4:23.0.0"

// Recyclerview
implementation "com.android.support:recyclerview-v7:23.2.0"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// Gson
implementation "com.google.code.gson:gson:2.9.0"

// zxing
implementation "com.google.zxing:core:3.3.0"
// zxing android-core (核心SDK 2.41.1之前需要)
implementation "com.google.zxing:android-core:3.3.0"

// 以下根据版本3选1
// SdkCore (核心SDK 2.42.5(不含)版本之前需要)
implementation "com.finogeeks.finochat.sdk:sdkcore:x.y.z"
// FinclipCore (核心SDK 2.42.5版本-2.43.3版本需要)
implementation "com.finogeeks.finclip.sdk:finclipcore:x.y.z"
// 新版SdkCore (核心SDK 2.43.5(含)版本起需要)
implementation "com.finogeeks.finclip.sdk:sdkcore:x.y.z"

注意

x.y.z须替换为下载的aar压缩包解压目录内对应sdk文件名称标明的版本号。

# 2.2.3 扩展SDK(plugins)

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// beacon
implementation "org.altbeacon:android-beacon-library:2.13.1"

# 2.2.4 WebRTC SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// Recyclerview
implementation "com.android.support:recyclerview-v7:23.2.0"

// constraintlayout
implementation "com.android.support.constraint:constraint-layout:1.1.3""

// appcompat
implementation "com.android.support:appcompat-v7:23.0.0"

// WebRTC
implementation "org.webrtc:google-webrtc:1.0.32006"

# 2.2.5 Map SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// support_v4
implementation "com.android.support:support-v4:26.1.0"

// Recyclerview
implementation "com.android.support:recyclerview-v7:26.1.0"

// constraintlayout
implementation "com.android.support.constraint:constraint-layout:1.1.3"

// AMap
compileOnly "com.amap.api:3dmap:8.0.0"
compileOnly "com.amap.api:location:5.5.1"
compileOnly "com.amap.api:search:7.9.0"

// gms
compileOnly "com.google.android.gms:play-services-location:16.0.0"
compileOnly "com.google.android.gms:play-services-maps:16.1.0"

// Baidu
compileOnly "com.baidu.lbsyun:BaiduMapSDK_Map:7.4.0"
compileOnly "com.baidu.lbsyun:BaiduMapSDK_Location:9.1.8"
compileOnly "com.baidu.lbsyun:BaiduMapSDK_Search:7.4.0"

# 2.2.6 Contact SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

# 2.2.7 Clipboard SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

# 2.2.8 Wechat SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// WeChat
implementation "com.tencent.mm.opensdk:wechat-sdk-android:6.8.0"

# 2.2.9 Media SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// ijk
compileOnly 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-armv7a:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-armv5:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-arm64:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-x86:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-x86_64:0.8.8'
compileOnly 'tv.danmaku.ijk.media:ijkplayer-exo:0.8.8'

# 2.2.10 Share SDK

// cardview
implementation "com.android.support:cardview-v7:23.0.0"

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// QrCode
implementation "cn.bingoogolapple:bga-qrcode-zxing:1.3.7"

// WeChat
compileOnly "com.tencent.mm.opensdk:wechat-sdk-android:6.8.0"

// Coroutines
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9"

# 2.2.11 Cast SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

// Cling library required
implementation "org.fourthline.cling:cling-core:2.1.1"
implementation "org.fourthline.cling:cling-support:2.1.1"
// Logger
implementation "com.orhanobut:logger:2.2.0"

implementation "org.eclipse.jetty:jetty-server:8.1.21.v20160908"
implementation "org.eclipse.jetty:jetty-servlet:8.1.21.v20160908"
implementation "org.eclipse.jetty:jetty-client:8.1.21.v20160908"
implementation "org.nanohttpd:nanohttpd:2.3.1"

# 2.2.12 Live SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

# 2.2.13 XLog SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

# 2.2.14 Calendar SDK

// finapplet
compileOnly "com.finogeeks.lib:finapplet:2.35.1"

// Kotlin
implementation "org.jetbrains.kotlin:kotlin-stdlib:1.3.61"

# 2.2.15 依赖关系说明

  1. 核心SDK依赖SDK Core;
  2. 各其它SDK依赖核心SDK,各自无相互依赖关系;
  3. 各SDK中使用compileOnly依赖的第三方库为可选依赖(除了核心SDK),若想要使用第三方库提供的能力,则您需要自行依赖对应库。

# 2.3 配置混淆规则

集成 SDK 之后,为了避免 SDK 中部分不能被混淆的代码被混淆,需要在工程的混淆规则配置文件中增加以下配置:

-keep class com.finogeeks.** {*;}

# 2.4 SDK涉及到的敏感权限

如果您集成所有的 SDK,那么涉及到的敏感权限包括:存储、摄像头、录音、读取手机状态、位置、蓝牙、通讯录。这些权限,基本都是调用相应的api和组件时才会触发。

权限
权限名称
存储读取 READ_EXTERNAL_STORAGE
存储写入 WRITE_EXTERNAL_STORAGE
摄像头 CAMERA
录音 RECORD_AUDIO
读取手机状态 READ_PHONE_STATE
位置 LOCATION
蓝牙 BLUETOOTH

其中各个SDK中涉及的权限如下:

核心SDK(finapplet)涉及的敏感权限:

权限 相关接口、组件
存储读写 chooseFile、chooseImage、chooseVideo、chooseMedia、saveImageToPhotosAlbum、saveVideoToPhotosAlbum、Video组件截屏、MediaViewer保存图片、MediaViewer保存视频、WebView组件下载文件、WebView组件文件选择器
摄像头 scanCode、Camera组件相关api、chooseImage、chooseVideo、chooseMedia、WebView组件文件选择器
录制音频 Camera组件、chooseVideo、chooseMedia
获取手机信息 getSuperviseInfo

扩展SDK(mop_plugins)涉及到的敏感权限:

权限 相关接口、组件
获取位置信息 getLocation
录制音频 startRecord、recorderManager

MapSDK(mapsdk)涉及到的敏感权限:

权限 相关接口、组件
获取位置信息 chooseLocation、getLocation、openLocation、choosePoi、Map组件

蓝牙SDK(bluetooth)涉及到的敏感权限:

权限 相关接口、组件
蓝牙 蓝牙-通用、蓝牙-低功耗中心设备、蓝牙-低功耗外围设备、蓝牙-信标一些列api;

声网SDK(agora)涉及到的敏感权限:

权限 相关接口、组件
录制音频 live-pusher,live-player组件
摄像头 live-pusher,live-player组件

WebRTCSDK(webrtc)涉及到的敏感权限:

权限 相关接口、组件
摄像头 webrtc-video组件
录制音频 webrtc-video组件

# 3. SDK初始化

我们强烈建议在Application中对SDK进行初始化,初始化SDK需要传入的各项参数如下(sdk初始化只需要调用一次,应避免重复调用):

# 3.1 小程序框架的配置信息

2.13.102版本开始支持配置多个服务器信息,可以同时打开不同环境中的小程序。配置参数如下:

// 服务器信息集合
List<FinStoreConfig> storeConfigs = new ArrayList<>();

// 服务器1的信息
FinStoreConfig storeConfig1 = new FinStoreConfig(
        "SDK Key信息",   // SDK Key
        "SDK Secret信息",   // SDK Secret
        "服务器1的地址",   // 服务器地址
        "服务器1的数据上报服务器地址",   // 数据上报服务器地址
        "/api/v1/mop/",   // 服务器接口请求路由前缀
        "",
        "加密方式"   // 加密方式,国密:SM,md5: MD5(推荐)
);
storeConfigs.add(storeConfig1);

// 服务器2的信息
FinStoreConfig storeConfig2 = new FinStoreConfig(
        "SDK Key信息",   // SDK Key
        "SDK Secret信息",   // SDK Secret
        "服务器2的地址",   // 服务器地址
        "服务器2的数据上报服务器地址",   // 数据上报服务器地址
        "/api/v1/mop/",   // 服务器接口请求路由前缀
        "",
        "加密方式"   // 加密方式,国密:SM,md5: MD5(推荐)
);
storeConfigs.add(storeConfig2);

FinAppConfig config = new FinAppConfig.Builder()
        .setFinStoreConfigs(storeConfigs) // 服务器信息集合
        .build();

# 3.2 设置SDK初始化状态回调

实现FinCallback接口,用于监听SDK初始化状态:

// SDK初始化结果回调,用于接收SDK初始化状态
FinCallback<Object> callback = new FinCallback<Object>() {
    @Override
    public void onSuccess(Object result) {
        // SDK初始化成功
    }

    @Override
    public void onError(int code, String error) {
        // SDK初始化失败
        Toast.makeText(AppletApplication.this, "SDK初始化失败", Toast.LENGTH_SHORT).show();
    }

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

    }
};

# 3.3 初始化SDK

调用初始化接口初始化SDK:

FinAppClient.INSTANCE.init(this, config, callback);

# 3.4 SDK初始化多进程处理

SDK采用多进程机制实现,每个小程序运行在独立的进程中,即一个小程序对应一个进程,在初始化SDK时,要特别注意的一点是:小程序进程在创建的时候不需要执行任何初始化操作,即使是小程序SDK的初始化,也不需要在小程序进程中执行

例如:应用使用了一些第三方库,这些库需要在应用启动时先初始化,那么在Application中执行初始化时,只有当前进程为宿主进程时才需要初始化这些第三方库,小程序进程是不需要初始化这些库的。

因此,在初始化SDK之前,一定要判断当前进程是哪一个进程,如果是小程序进程,就不进行任何操作了:

if (FinAppClient.INSTANCE.isFinAppProcess(this)) {
    return;
}

以上即为初始化SDK的整个流程。完整代码如下:

package com.example.finogeeks.appletdemo;

import android.os.Process;
import android.support.multidex.MultiDexApplication;
import android.text.TextUtils;
import android.widget.Toast;

import com.example.finogeeks.appletdemo.api.ApiOpenPage;
import com.example.finogeeks.appletdemo.api.ApiOpenPageForResult;
import com.example.finogeeks.appletdemo.api.DrawModule;
import com.example.finogeeks.appletdemo.util.ProcessUtilKt;
import com.finogeeks.lib.applet.client.FinAppClient;
import com.finogeeks.lib.applet.client.FinAppConfig;
import com.finogeeks.lib.applet.interfaces.FinCallback;

/**
 * 应用的{@link android.app.Application}
 */
public class AppletApplication extends MultiDexApplication {
    
    @Override
    public void onCreate() {
        super.onCreate();

        if (FinAppClient.INSTANCE.isFinAppProcess(this)) {
            // 小程序进程不执行任何初始化操作
            return;
        }
        
        // 服务器信息集合
		List<FinStoreConfig> storeConfigs = new ArrayList<>();

		// 服务器1的信息
		FinStoreConfig storeConfig1 = new FinStoreConfig(
        		"SDK Key信息",   // SDK Key
        		"SDK Secret信息",   // SDK Secret
        		"服务器1的地址",   // 服务器地址
        		"服务器1的数据上报服务器地址",   // 数据上报服务器地址
        		"/api/v1/mop/",   // 服务器接口请求路由前缀
        		"",
        		"加密方式",   // 加密方式,国密:SM,md5: MD5(推荐)
                false
		);
		storeConfigs.add(storeConfig1);

		// 服务器2的信息
		FinStoreConfig storeConfig2 = new FinStoreConfig(
        		"SDK Key信息",   // SDK Key
        		"SDK Secret信息",   // SDK Secret
        		"服务器2的地址",   // 服务器地址
        		"服务器2的数据上报服务器地址",   // 数据上报服务器地址
        		"/api/v1/mop/",   // 服务器接口请求路由前缀
        		"",
        		"加密方式",   // 加密方式,国密:SM,md5: MD5(推荐)
                false
		);
		storeConfigs.add(storeConfig2);

		FinAppConfig config = new FinAppConfig.Builder()
        		.setFinStoreConfigs(storeConfigs) // 服务器信息集合
        		.build();

        FinAppClient.INSTANCE.init(this, config, new FinCallback<Object>() {
            @Override
            public void onSuccess(Object result) {
            }

            @Override
            public void onError(int code, String error) {
                Toast.makeText(AppletApplication.this, "SDK初始化失败", Toast.LENGTH_SHORT).show();
            }

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

            }
        });
    }
}

# 3.5 使用TBS X5 WebView

SDK 默认使用系统 WebView 加载小程序,同时也支持使用 TBS X5 WebView 加载小程序。使用 TBS X5 内核可以实现部分原生组件的同层渲染,目前支持通过 TBS X5 内核进行同层渲染的原生组件有:

  • video
  • live-player
  • live-pusher
  • map
  • input
  • textarea

启用 TBS X5 WebView 的方法:

在 APP 工程中依赖 TBS SDK,如下:

implementation 'com.tencent.tbs:tbssdk:44275' // 建议使用比较新的版本

依赖 TBS SDK 之后,SDK 内部使用的 WebView 将自动切换为 X5 WebView。SDK 初始化过程中会对 TBS SDK 进行初始化,待 X5 内核加载成功之后,即可使用 X5 内核提供的各种能力。

由于腾讯下发 X5 内核文件有概率受网络状况影响,可能导致 X5 内核下载缓慢或失败,所以 SDK 也支持从自己的服务器下载 X5 内核文件,实现方式如下:

  1. 下载 TBS X5 内核文件:

    armeabi 架构 X5 内核文件下载地址 (opens new window)

    arm64-v8a 架构 X5 内核文件下载地址 (opens new window)

  2. 将下载好的 X5 内核文件上传到自己的服务器,并对上传到服务器后的内核文件重命名:

    armeabi 架构 X5 内核文件重命名为:armeabi_release.tbs

    arm64-v8a 架构 X5 内核文件重命名为:arm64-v8a_release.tbs

    重命名是为了便于 SDK 内部拼接完整的内核文件下载地址。

  3. 设置 SDK 初始化配置参数:

    FinAppConfig finAppConfig = new FinAppConfig.Builder()
            // 是否从本地加载 TBS X5 内核,需要设置为 true
            .setUseLocalTbsCore(true)
            // 下载 TBS X5 内核文件的服务器地址
            // 注意:
            // 1. 须替换为自己服务器的地址
            // 2. 这里的地址并非完整的服务器文件地址
            // SDK 内部会根据此处配置的地址,结合手机 CPU 架构类型,
            // 在后面继续拼接对应的 X5 内核文件名称,从而构成完整的地址
            // 完整地址示例:
            // https://xxx.yyy.zzz/sdk/x5/latest/armeabi_release.tbs
            // https://xxx.yyy.zzz/sdk/x5/latest/arm64-v8a_release.tbs
            .setTbsCoreUrl("https://xxx.yyy.zzz/sdk/x5/latest/")
            .build();
    

经过以上步骤,SDK 初始化的时候就能够从自己的服务器下载 X5 内核文件了。

# 3.6 使用WebView打洞方案实现同层渲染

2.43.7(包含2.43.7) 版本以后支持

新增轻量级的同层渲染方案,通过 WebView 打洞的方式实现同层渲染,支持的原生组件有:

  • live-player
  • live-pusher

一、该方案无需引入X5以及其他第三方库,直接使用finapple库就支持。

implementation 'com.finogeeks.lib:finapplet:2.43.7' // x.y.z须替换为具体的版本号最低2.43.7

二、设置SDK初始化配置参数:

FinAppConfig finAppConfig = new FinAppConfig.Builder()
        // 其他配置设置
        // 需要设置为 true ,此设置优先级最高。
        // 优先级高于X5同层渲染,开启了就不会使用X5了,即使配置了X5。
        .setEnableHoleRender(true)
        .build();

三、注意事项: 实现原理: 把原生组件对应的View放在webvieW的底层,然后设置webvieW的背景透明,这样就能模拟同层渲染(原生View就不会覆盖webview上面的HTML元素)。

  1. 该方案比较轻量级,仅仅支持组件在固定位置或者全屏的情况;如果页面会滚动的话,原生组件不会跟着滚动位置;
  2. 框架内部会把支持组件的父级元素的背景设置为透明(不是透明的话,底层原生View会被覆盖看不见,参见实现原理);
  3. 如果要在组件上面放置元素,请使用HTML元素,不要再使用cover-view;

# 4. SDK使用示例

# 4.1 启动小程序

在平台中上架小程序之后,我们就可以通过调用SDK中启动小程序的接口来打开小程序了。启动小程序的代码如下:

// 构建request
RemoteFinAppletRequest request = new RemoteFinAppletRequest(apiServer, appId);
// 或使用以下方式省略服务器环境地址的配置,默认将使用SDK初始化时配置的第一个服务器环境地址
RemoteFinAppletRequest request = IFinAppletRequest.Companion.fromAppId(appId);
// 打开小程序
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, request, callback);

如果启动小程序时需要携带启动参数,则可以调用支持传递启动参数的接口,如下:

Map<String, String> params = new HashMap<>();
// path为小程序页面路径
params.put("path", "/pages/index/index");
// query为启动参数,内容为"key1=value1&key2=value2 ..."的形式
params.put("query", "aaa=test&bbb=123");
// 给request配置参数
request.setStartParams(params);
FinAppClient.INSTANCE.getAppletApiManager().startApplet(context, request, callback);

# 4.2 自定义小程序接口

实现小程序自定义接口需要创建一个继承自AbsApi的类,并在创建的子类中重写父类的方法(最主要的是apis()方法和invoke()方法)。

下面以在小程序里面打开一个原生页面为例来演示如何实现并注册小程序自定义接口:

  1. 首先,创建ApiOpenPage类,继承自AbsApi
  2. 然后,在ApiOpenPage中重写apis()方法用于返回所有可调用的API的名称。我们可以在apis()返回的数组中添加多个API的名称,当前示例只添加了一个openPage
  3. 最后,在ApiOpenPage中重写invoke()方法用于实现对应的逻辑。当前示例实现了一个简单的页面跳转,即如果在小程序中调用了openPage这个接口,那么就会在原生这边启动一个Activity。
package com.example.finogeeks.appletdemo.api;

import android.content.Context;
import android.content.Intent;
import android.text.TextUtils;

import com.example.finogeeks.appletdemo.SecondActivity;
import com.finogeeks.lib.applet.api.AbsApi;
import com.finogeeks.lib.applet.interfaces.ICallback;

import org.json.JSONObject;

/**
 * 自定义小程序接口,实现简单的页面跳转功能
 */
public class ApiOpenPage extends AbsApi {

    private Context mContext;

    public ApiOpenPage(Context context) {
        mContext = context;
    }

    /**
     * 返回可调用的api名称的数组
     *
     * @return 可调用的api名称的数组
     */
    @Override
    public String[] apis() {
        return new String[]{"openPage"};
    }

    /**
     * 接收到对应的API调用时,会触发此方法,在此方法中实现API的业务逻辑
     *
     * @param event    事件名称,即API名称
     * @param param    事件参数
     * @param callback 回调接口,用于执行完业务逻辑之后把结果回调给小程序
     */
    @Override
    public void invoke(String event, JSONObject param, ICallback callback) {
        if ("openPage".equals(event)) {
            String url = param.optString("url");
            if (!TextUtils.isEmpty(url)) {
                Intent intent = new Intent();
                intent.setClass(mContext, SecondActivity.class);
                mContext.startActivity(intent);
                callback.onSuccess(null);
            } else {
                callback.onFail();
            }
        }
    }
}

实现自定义小程序接口之后,还需要两个步骤才能在小程序调用接口:

  1. 将自定义的小程序接口注册到SDK中。通过调用IExtensionApiManager接口的registerApi方法实现接口注册:
FinAppClient.INSTANCE.getExtensionApiManager().registerApi(new ApiOpenPage(context));
  1. 在小程序工程中增加自定义接口配置。在小程序工程的根目录创建FinClipConf.js文件,在FinClipConf.js中配置对应的自定义接口,配置如下:
module.exports = {
  	extApi:[
    	{
      		name: 'openPage', // 扩展接口名
      		params: { // 扩展接口参数,可以只列必须的参数
        		url: ''
      		}
    	}
  	]
}

# 4.3 原生和小程序网页之间进行交互

小程序加载网页时,如果网页要调用原生的功能,则需要将原生代码以自定义JSSDK接口的形式注册到SDK内部。自定义JSSDK接口的实现方式和自定义小程序接口一样,即继承AbsApi并重写父类方法。

不同的地方在于接口注册时调用的是IExtensionWebApiManagerregisterApi方法,而不是IExtensionApiManager中的方法:

FinAppClient.INSTANCE.getExtensionWebApiManager().registerApi(new WebApi(context));

同时,SDK也支持原生调用网页中的JavaScript代码,调用方式如下:

FinAppClient.INSTANCE.getAppletApiManager().callJS("appId", "funcName", "funParams", 1)
        .subscribeOn(Schedulers.io())
        .observeOn(AndroidSchedulers.mainThread())
        .subscribe(
                result -> Toast.makeText(context, "callJS successfully : " + result, Toast.LENGTH_SHORT).show(),
                throwable -> Toast.makeText(context, "callJS failed : " + throwable.getLocalizedMessage(), Toast.LENGTH_SHORT).show()
        );

# 5. 扩展SDK

以上内容都是围绕finapplet这个核心SDK来阐述的,其实除了核心SDK之外,我们还提供了扩展SDK,扩展SDK是一个依赖核心SDK的库,里面提供了核心SDK中所没有的各种小程序API。

之所以提供扩展SDK,是因为既要保证核心SDK足够轻量,又要保证小程序API足够丰富。核心SDK负责建立起运行小程序的基础框架并提供一小部分最不可获取的API,在权限方面仅保留了存储、相机、地理位置等基本权限,体积仅1MB多一点,扩展SDK则是作为核心SDK的补充而存在的,里面API将不断丰富和完善。

获取扩展 SDK

您可登录 资源下载中心 (opens new window) 下载 Android SDK 文件,扩展 SDK 也处于在所下载的压缩包中。

如果希望使用扩展SDK中的API,在gradle中依赖扩展SDK库即可:

implementation 'com.finogeeks.mop:plugins:x.y.z' //x.y.z须替换为具体的版本号

# 6. MapSDK

MapSDK支持Map组件及位置API。 其依赖于核心SDK,做为地图位置功能的补充。 其中提供的地图、定位能力依赖于第三方地图、定位SDK。支持高德地图|高德定位百度地图|百度定位腾讯地图|腾讯定位谷歌地图|谷歌定位四种组合情况使用。

注意

1.高德、百度、腾讯、谷歌方案对位置API的支持情况请查看「开发-API-位置」。 2.高德地图SDK最多允许app同时有10个map视图对象,当超过10个map视图对象时,新的地图内容会显示黑屏。所以,当使用高德地图来实现map组件(即依赖高德地图扩展SDK)时,需要小程序在页面的onHide()里移除销毁map,然后在onShow()里创建地图和添加地图内容。

# 6.1 集成

  1. 在gradle中依赖MapSDK库:
implementation 'com.finogeeks.mop:map:x.y.z' // x.y.z须替换为具体的版本号
  1. 由于MapSDK实现的地图、定位能力依赖于第三方地图、定位SDK,因此,还需要宿主APP集成第三方地图、定位SDK,并完成API_KEY、Service注册等。

注意

请选择以下第三方SDK提供方中的一个进行集成。
如需了解第三方SDK详细集成说明,请参考第三方SDK官方集成文档。

依赖第三方SDK库:(请选其一)

// 高德(建议不低于以下版本,否则可能出现类/方法错误问题)
implementation 'com.amap.api:3dmap:8.0.0' // 可以替换为您需要的版本号
implementation 'com.amap.api:location:5.5.1' // 可以替换为您需要的版本号
implementation 'com.amap.api:search:7.9.0' // 可以替换为您需要的版本号
// 百度(建议不低于以下版本,否则可能出现类/方法错误问题)
implementation 'com.baidu.lbsyun:BaiduMapSDK_Map:7.4.0' // 可以替换为您需要的版本号
implementation 'com.baidu.lbsyun:BaiduMapSDK_Location:9.1.8' // 可以替换为您需要的版本号
implementation 'com.baidu.lbsyun:BaiduMapSDK_Search:7.4.0' // 可以替换为您需要的版本号
// 腾讯(建议不低于以下版本,否则可能出现类/方法错误问题)
implementation 'com.tencent.map:tencent-map-vector-sdk:4.5.9' // 可以替换为您需要的版本号
implementation 'com.tencent.map.geolocation:TencentLocationSdk-openplatform:7.4.9' // 可以替换为您需要的版本号
// 谷歌
implementation 'com.google.android.gms:play-services-maps:16.1.0' // 可以替换为您需要的版本号(建议使用此版本,不支持此以上版本)
implementation 'com.google.android.gms:play-services-location:16.0.0' // 可以替换为您需要的版本号(建议使用此版本,不支持此以上版本)

AndroidManifest.xml注册第三方SDK的API_KEY及Service:(根据您依赖的第三方SDK选其一)

// 高德
<meta-data
    android:name="com.amap.api.v2.apikey"
    android:value="您申请的ApiKey" />

<service android:name="com.amap.api.location.APSService" />
// 百度
<meta-data
    android:name="com.baidu.lbsapi.API_KEY"
    android:value="您申请的ApiKey" />

<service
    android:name="com.baidu.location.f"
    android:enabled="true"
    android:process=":remote" />
// 腾讯
<meta-data
    android:name="TencentMapSDK"
    android:value="您申请的ApiKey" />
// 谷歌
<meta-data
    android:name="com.google.android.geo.API_KEY"
    android:value="您申请的ApiKey" />

build.gradle中配置第三方SDK支持的SO库架构:

android {
    defaultConfig {
        ndk {
            // 设置支持的SO库架构(您可以根据需要,选择一个或多个平台的so)
            abiFilters "armeabi", "armeabi-v7a", "arm64-v8a", "x86","x86_64"
        }
    }
}

# 6.2 配置

  1. 设置隐私政策(可选):

高德、百度、腾讯相关SDK在高于特定版本时需要设置同意隐私政策才能正常使用功能。
具体版本请参照设置接口方法注释。

接口定义如下:

public class MapSDKInitializer {
    /**
     * 设置高德地图隐私政策。
     * 自高德地图SDK v8.1.0版本起增加。
     *
     * @param isContains 隐私权政策是否包含高德开平隐私权政策。true为包含
     * @param isShow     隐私权政策是否弹窗展示告知用户。true为展示
     * @param isAgree    是否同意隐私政策
     */
    public static void setAMapPrivacy(Context context, boolean isContains, boolean isShow, boolean isAgree)

    /**
     * 设置高德定位隐私政策。
     * 自高德定位SDK v5.6.0版本起增加。
     *
     * @param isContains 隐私权政策是否包含高德开平隐私权政策。true为包含
     * @param isShow     隐私权政策是否弹窗展示告知用户。true为展示
     * @param isAgree    是否同意隐私政策
     */
    public static void setAMapLocationPrivacy(Context context, boolean isContains, boolean isShow, boolean isAgree)

    /**
     * 设置百度地图隐私政策。
     * 自百度地图SDK v7.5.0版本起增加。
     *
     * @param isAgree 是否同意隐私政策
     */
    public static void setBaiduMapAgreePrivacy(Context context, boolean isAgree)

    /**
     * 设置百度定位隐私政策。
     * 自百度定位SDK v9.2.9版本起增加。
     *
     * @param isAgree 是否同意隐私政策
     */
    public static void setBaiduLocationAgreePrivacy(Context context, boolean isAgree)

    /**
     * 设置腾讯地图隐私政策。
     * 自腾讯地图SDK v4.5.6版本起增加。
     *
     * @param isAgree 是否同意隐私政策
     */
    public static void setTencentMapAgreePrivacy(Context context, Boolean isAgree)

    /**
     * 设置腾讯定位隐私政策。
     * 自腾讯定位 v7.4.6版本起增加。
     *
     * @param isAgree 是否同意隐私政策
     */
    public static void setTencentLocationAgreePrivacy(Context context, Boolean isAgree)
}
  1. 设置腾讯地图secretKey(可选):

接口定义如下:

public class MapSDKInitializer {
    /**
     * 设置腾讯地图WebService API secretKey。
     * 用于chooseLocation、choosePoi检索poi接口。
     *
     * @param secretKey 加密串。如果不需要secretKey则无需调用此方法,或者secretKey传null
     */
    public static void setTencentSecretKey(Context context, String secretKey)
}
  1. 设置百度地图坐标系(可选):

百度地图允许设置地图坐标系为BD09LL或GCJ02。

接口定义如下:

public class MapSDKInitializer {
    public enum CoordType {
        GCJ02,
        BD09LL
    }

    /**
     * 设置百度地图坐标系。
     * 自百度地图SDK 4.3.0版本起增加。
     *
     * @param coordType 坐标系类型。BD09LL或GCJ02
     */
    public static void setBaiduMapCoordType(Context context, CoordType coordType)
}
  1. 设置Map组件及位置相关API使用的地图类型(可选):

接口定义如下:

public class MapSDKInitializer {
    /**
     * 使用的地图类型
     */
    public enum UsingMap {
        /**
         * 自动。根据集成的地图、定位SDK自动选择。默认值。
         * 同时集成多种类型的地图、定位SDK时,优先顺序为 高德 -> 百度 -> 腾讯 -> 谷歌。
         */
        AUTO,

        /**
         * 高德
         */
        AMAP,

        /**
         * 百度
         */
        BAIDU,

        /**
         * 腾讯
         */
        TENCENT,

        /**
         * 谷歌
         */
        GOOGLE
    }

    /**
     * 设置Map组件及位置相关API使用的地图类型。
     * <p>
     * APP同时集成多种类型的地图、定位SDK时,可以使用此方法设置使用指定的地图、定位SDK实现Map组件及位置相关API功能。
     * APP只集成一种类型地图、定位SDK时,不需要设置此方法。
     *
     * @param usingMap 指定使用的地图类型
     */
    public static void setUsingMap(Context context, UsingMap usingMap)
}

# 7. 蓝牙SDK

使用蓝牙接口需要单独集成蓝牙SDK,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:bluetooth:x.y.z'

# 8. 声网SDK

使用声网相关的接口需要单独集成声网SDK,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:agora:x.y.z'

若您使用导入aar的方式接入声网SDK,需要额外添加声网依赖:

implementation 'io.agora.rtc:full-sdk:3.5.0'

# 9. WebRTCSDK

使用WebRTC相关的接口需要单独集成WebRTCSDK,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:webrtc:x.y.z'

若您使用导入aar的方式接入WebRTCSDK,需要额外添加WebRTC依赖:

implementation 'org.webrtc:google-webrtc:1.0.32006'

# 10. 联系人SDK

使用联系人相关的接口需要单独集成联系人SDK,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:contact:x.y.z'

# 11. 剪贴板SDK

使用剪贴板相关的接口需要单独集成剪贴板SDK,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:clipboard:x.y.z'

# 12. WeChatSDK

微信SDK的快捷接入,提供调起微信通过微信小程序获得登录、用户信息、手机号、支付的能力。

请注意

集成 WeChatSDK 需要先在微信开放平台申请AppID,这里填写的是移动应用下的AppID, 一般情况是wx开头,注意不是微信小程序的AppId,也不是微信小程序原始ID(gh开头),这些ID很容易搞混。

集成方式:

implementation 'com.finogeeks.mop:wechat:x.y.z'

并在项目的build.gradle文件中(如app/build.gradle)添加您在微信开放平台申请的移动应用APPID:

android {
    // ..其它配置省略
    defaultConfig {
    // ..其它配置省略
    resValue "string", "wechat_sdk_app_id", "您的微信开放平台移动应用下AppID"  
    }
}

注意

使用WeChatSDK须保证与您当前正在使用的核心SDK的版本一致,并且在2.37.13或以上。

注意

由于WeChatSDK需要覆盖IAppletHandler中的open-type相关的方法,具体为chooseAvatarcontactfeedbackgetPhoneNumberlaunchAppshareAppMessage六个方法。

因此若您实现了IAppletHandler并实现了以上六个方法,WeChatSDK将会接管getPhoneNumber,剩余的五个方法请按以下方式迁移,若您未实现IAppletHandler或没有用到以上六个方法,可以忽略此处。

  1. 实现IWeChatOpenTypeHandler接口:

    class MyWeChatAppletOpenTypeHandler : IWeChatOpenTypeHandler {
        override fun chooseAvatar(callback: IAppletHandler.IAppletCallback) {
           // 您的实现逻辑
        }
    
        override fun contact(json: JSONObject): Boolean {
           // 您的实现逻辑
        }
    
        override fun feedback(bundle: Bundle): Boolean {
           // 您的实现逻辑
        }
    
        override fun launchApp(appParameter: String?): Boolean {
           // 您的实现逻辑
        }
    
        override fun shareAppMessage(
            appInfo: String,
            bitmap: Bitmap?,
            callback: IAppletHandler.IAppletCallback
        ) {
           // 您的实现逻辑
        }
    }
    
  2. 在核心SDK初始化成功后,设置您的实现类。(注意,同核心SDK一样,务必保证是在主进程中设置):

    WeChatOpenTypeClient.instance.iWeChatOpenTypeHandler = MyWeChatAppletOpenTypeHandler()
    

注意

为了避免微信OpenSDK相关回调类冲突问题,WeChatSDK 从 2.39.11 版本开始,不再自动生成微信回调接收类 WXEntryActivity,请自行根据微信官方文档 Android接入指南 (opens new window) ,自行创建 WXEntryActivity ,并加入 WeChatSDK 回调处理方法,示例如下:

class WXEntryActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FinWeChatWXEntry.handleWeChatIntent(this, intent)
        // 您的其它业务处理逻辑
        finish()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        FinWeChatWXEntry.handleWeChatIntent(this, intent)
        // 您的其它业务处理逻辑
        finish()
    }
}

# 13. Media SDK

2.38.0版本以后支持

video组件的边下边播需要集成此SDK才能实现。

集成方式:

android {
    packagingOptions {
        doNotStrip "*/arm64-v8a/libijkffmpeg.so"
        doNotStrip "*/arm64-v8a/libijkplayer.so"
        doNotStrip "*/arm64-v8a/libijksdl.so"

        doNotStrip "*/armeabi/libijkffmpeg.so"
        doNotStrip "*/armeabi/libijkplayer.so"
        doNotStrip "*/armeabi/libijksdl.so"

        doNotStrip "*/armeabi-v7a/libijkffmpeg.so"
        doNotStrip "*/armeabi-v7a/libijkplayer.so"
        doNotStrip "*/armeabi-v7a/libijksdl.so"

        doNotStrip "*/x86/libijkffmpeg.so"
        doNotStrip "*/x86/libijkplayer.so"
        doNotStrip "*/x86/libijksdl.so"

        doNotStrip "*/x86_64/libijkffmpeg.so"
        doNotStrip "*/x86_64/libijkplayer.so"
        doNotStrip "*/x86_64/libijksdl.so"
    }
}


dependencies {
    implementation 'com.finogeeks.mop:media:x.y.z' // x.y.z须替换为具体的版本号
    implementation 'tv.danmaku.ijk.media:ijkplayer-java:0.8.8'
}

在proguard-rules.pro文件中添加混淆规则:

# Media SDK
-keep public class com.finogeeks.finclip.plugins.media.player.ijk.FinIjkMediaPlayerFactory {
    public <init>();
}
-keep class com.finogeeks.finclip.plugins.media.player.ijk.IjkMediaPlayerOptionsApplier {
    public static <fields>;
    public static <methods>;
}
-keep class com.finogeeks.finclip.plugins.media.player.ijk.IjkMediaPlayerOptionsApplier$Applier {*;}
-keep class com.finogeeks.finclip.plugins.media.player.ijk.IjkMediaPlayerOptionsApplier$Options {*;}

#ijkplayer
-keep class tv.danmaku.ijk.media.player.** {*;}
-keep class tv.danmaku.ijk.media.player.IjkMediaPlayer{*;}
-keep class tv.danmaku.ijk.media.player.ffmpeg.FFmpegApi{*;}

# 14. Share SDK

集成分享小程序功能,接管”更多“菜单面板中的”分享“按钮功能(核心SDK版本 ≥ 2.39.11)。

“分享”按钮默认为隐藏,需要自行配置为显示,详情请参考:设置小程序更多菜单

如需自行接管“分享”按钮点击事件,请参考:IShareAppletHandler

如需要自定义分享落地页的链接、分享链接中的apk下载地址,请参考:ShareSDKDelegate

集成方式:

implementation 'com.finogeeks.mop:share:x.y.z'

注意

使用ShareSDK须保证与您当前正在使用的核心SDK的版本一致,并且在2.39.11或以上。

# 14.1 微信分享

若需要开启微信分享功能,需要集成微信官方opensdk:

implementation 'com.tencent.mm.opensdk:wechat-sdk-android:6.8.0'

并在项目的build.gradle文件中(如app/build.gradle)添加您在微信开放平台申请的移动应用APPID:

android {
    // ..其它配置省略
    defaultConfig {
    // ..其它配置省略
    resValue "string", "wechat_sdk_app_id", "您的微信开放平台移动应用下AppID"  
    }
}

注意

集成 ShareSDK 并使用其中的微信相关分享能力,需要先在微信开放平台申请AppID,这里填写的是移动应用下的AppID, 一般情况是wx开头,注意不是微信小程序的AppId,也不是微信小程序原始ID(gh开头),这些ID很容易搞混。

注意

为了避免微信OpenSDK相关回调类冲突问题,ShareSDK 不会自动生成微信回调接收类 WXEntryActivity,请自行根据微信官方文档 Android接入指南 (opens new window) ,自行创建 WXEntryActivity ,并加入 ShareSDK 回调处理方法,示例如下:

class WXEntryActivity : Activity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        FinShareWXEntry.handleWeChatIntent(this, intent)
        // 您的其它业务处理逻辑
        finish()
    }

    override fun onNewIntent(intent: Intent?) {
        super.onNewIntent(intent)
        setIntent(intent)
        FinShareWXEntry.handleWeChatIntent(this, intent)
        // 您的其它业务处理逻辑
        finish()
    }
}

# 15. CastSDK

2.38.1版本以后支持

投屏SDK的快捷接入,提供调起播放视频的时候,可以投屏到其他支持相关协议(DLNA)的投屏设备(例如:电视)。

集成方式:

implementation 'com.finogeeks.mop:cast:x.y.z'

1、在要接入的工程的根目录 build.gradle 文件中添加如下配置:

 allprojects {
	repositories {
		
        maven { url 'http://4thline.org/m2' }
		maven { url 'https://jitpack.io' }
	}
}

2、在要接入的工程的目录 app/build.gradle 文件中添加如下配置:

 packagingOptions {
        
        exclude 'META-INF/beans.xml'

    }

# 16. LiveSDK

2.41.1 版本以后支持

直播SDK的快捷接入,提供直播推流、拉流、播放的能力。

集成方式:

implementation 'com.finogeeks.mop:live:x.y.z'

注意

直播SDK 不可和 WebRTC 以及 AgoraSDK一起使用

注意

在你要接入的工程中进行如下配置

        FinAppConfig.UIConfig uiConfig = new FinAppConfig.UIConfig();
        uiConfig.setUseNativeLiveComponent(true); // 此配置别遗漏

        FinAppConfig config = new FinAppConfig.Builder()
        // 省略其他配置
        .setUiConfig(uiConfig) // 记得要把uiConfig设置进去
        .build();

        FinAppClient.INSTANCE.init(this, config, new FinCallback<Object>() {
            @Override
            public void onSuccess(Object result) {
                // 初始化成功,可以开始使用直播组件
                // 这个也不要遗漏
                 AnyRtcLiverSDK.INSTANCE.install();
            }

            @Override
           public void onError(int code, String error) {
           }

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

            }
        });

# 17. XLogSDK

2.40.5 版本开始,核心SDK中将不再包含XLog,即不再包含将日志持久化存储在本地的功能。

若有持久化日志的需求,可以选择集成XLogSDK,并开启对应的配置项。

集成方式:

implementation 'com.finogeeks.mop:xlog:x.y.z'

相关配置:

FinAppConfig finAppConfig = new FinAppConfig.Builder()
        // 开启日志,默认是false
        .setEnableLog(true)
        // 开启XLogSDK的控制台日志,默认是true
        .setEnableXLogConsole(true)
        // 设置日志等级,默认是XLogLevel.LEVEL_NONE
        .setLogLevel(XLogLevel.LEVEL_VERBOSE)
        // 自定义XLogSDK的日志文件目录,默认为 /data/data/${packageName}/files/fino_log
        .setXLogDir(logDir)
        // 自定义XLogSDK的日志文件最大留存时间,最小1天,默认为10天
        .setLogMaxAliveSec(2 * 24 * 60 * 60)
        // 其它配置项省略
        .build();
FinAppClient.INSTANCE.init(application, finAppConfig, callback);

注意,若不集成XLogSDK,以上配置项中 setEnableXLogConsole、setXLogDir、setLogMaxAliveSec将无效,但 setEnableLog 和 setLogLevel 依然生效,仅会输出在控制台中而不会持久化日志。

日志导出:

/**
 * 导出日志
 *
 * @param context
 * @param appId 导出指定小程序id的日志,若传空则导出主进程的日志
 * @param date 导出指定日期的日志文件,若传空则导出主进程或指定小程序的所有日志
 * @param exportDir 导出到指定目录
 */
FinAppClient.INSTANCE.exportLogFile(context, appId, date, exportDir);

使用示例

导出主进程的所有日志:

boolean result = FinAppClient.INSTANCE.exportLogFile(context, null, null, exportDir);

导出主进程的指定日期日志:

boolean result = FinAppClient.INSTANCE.exportLogFile(context, null, date, exportDir);

导出指定小程序的所有日志:

boolean result = FinAppClient.INSTANCE.exportLogFile(context, appId, null, exportDir);

导出指定小程序的指定日期日志:

boolean result = FinAppClient.INSTANCE.exportLogFile(context, appId, date, exportDir);

注意:导出前请确保指定的导出位置exportDir有写入权限,否则可能会导出日志失败。

# 18. CalendarSDK

使用日历相关接口需要单独集成日历SDK,需要核心SDK版本高于2.40.13,集成后接口即可生效,无需配置。

集成方式:

implementation 'com.finogeeks.mop:calendar:x.y.z'

# 19. 常见错误码

# 小程序异常场景

小程序异常场景 状态码 错误信息
小程序不存在 FS_APP_ID_NOT_FOUND 小程序不存在 :
请检查 AppID
小程序已下架 FS_SERVICE_UNAVAILABLE 小程序不可用 :
小程序已下架,相关服务暂不可用
小程序过期 FS_APP_PAY_EXPIRE 小程序不可用 :
小程序已过有效期,相关服务暂不可用
小程序禁用 FS_APP_IS_FORBIDDEN 小程序不可用 :
小程序被禁用,相关服务暂不可用
应用不存在 FS_BIND_NOT_FOUND 服务不可用:
当前应用未在平台备案,请检查 SDK 初始化配置信息
应用已经停止合作 FS_COOPERATION_TERMINATED 小程序不可用 :
当前应用已经停止合作
小程序未与应用关联 FS_APP_NOT_ASS_BIND 小程序不可用 :
小程序与本应用的关联关系没有生效,请检查关联关系
bundleId禁用 FS_BIND_IS_FORBIDDEN 小程序不可用 :
BundleID 被禁用,相关服务暂不可用
应用已过期 FS_BIND_PAY_EXPIRE 小程序不可用 :
当前应用已过期
机构被冻结 FS_ORGAN_STATUS_INVALID 小程序不可用 :
小程序所属企业账号状态异常,请登录平台处理
非法license FS_LICENSE_INVALID_ERR 小程序不可用 :
您当前的 license 异常,请联系管理员处理
根据 Appid 请求小程序版本详情时,无法匹配到时报错 FS_APP_SEQUENCE_NOT_FOUND 小程序打开失败 :
小程序版本错误
根据SDK KEY 获取应用时找不到,就报错 FS_SIGNATURE_SDKKEY_INVAILD 小程序不可用 :
SDK Key 出错,请联系管理员处理
获取域名失败 FS_GET_DOMAIN_INFO_ERROR 服务不可用 :
获取域名失败,相关服务不可用
应用禁用 - 小程序不可用 :
当前合作应用已被禁用
流量额度已经耗尽,无法打开小程序(无论是调用次数或者代码包下载流量不足,都属于资源不足) OVER_FRQ_LIMIT 服务不可用 :
抱歉,由于资源不足,相关服务暂不可用

# Android 初始化或启动小程序阶段常见的错误码

报错阶段 状态码 错误信息
未知错误 9999 未知错误
初始化SDK 10000 未初始化SDK或者appKey不合法
初始化SDK或者打开小程序 10001 参数不合法
打开小程序 10002 域名校验失败
打开小程序 10003 网络未连接
打开小程序 11000 服务器接口请求失败
打开小程序 11001 服务器返回数据异常
打开小程序 11003 下载地址异常,无法下载
打开小程序 12002 service 文件未找到
打开小程序 13000 没有体验权限
打开小程序 13001 体验版已取消
打开小程序 13002 ide临时二维码过期
打开小程序 10002 未配置指定服务器的环境信息
打开小程序 12000 基础库解压失败
打开小程序 12000 小程序解压失败
打开小程序 13004 sdk加密接口数据解密失败
打开小程序 11001 获取基础库详情失败
打开小程序 11004 小程序文件md5校验失败
打开小程序 11004 服务器异常,下载失败
打开小程序 12002 找不到service文件
打开小程序 15003 设备类型暂不支持
打开小程序 15004 当前可用设备数量已达上限
打开小程序 15005 找不到小程序
打开小程序 15006 页面不存在
© 2022 FinClip with ❤