# Android 集成

集成样例代码

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

# 1. 获取凭据

请注意

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

# 2. 导入SDK

# 2.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.2 在gradle中依赖SDK

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

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

注意

SDK 中的动态库是被加固过的,被加固过的动态库在编译打包时不能被压缩,否则加载的时候会报错。

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

packagingOptions {
      // libsdkcore.so、libfin-yuvutil.so是被加固过的,不能被压缩,否则加载动态库时会报错
      doNotStrip "*/x86/libsdkcore.so"
      doNotStrip "*/x86_64/libsdkcore.so"
      doNotStrip "*/armeabi/libsdkcore.so"
      doNotStrip "*/armeabi-v7a/libsdkcore.so"
      doNotStrip "*/arm64-v8a/libsdkcore.so"
      
      doNotStrip "*/x86/libfin-yuvutil.so"
      doNotStrip "*/x86_64/libfin-yuvutil.so"
      doNotStrip "*/armeabi/libfin-yuvutil.so"
      doNotStrip "*/armeabi-v7a/libfin-yuvutil.so"
      doNotStrip "*/arm64-v8a/libfin-yuvutil.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、libfin-yuvutil.so是被加固过的,不能被压缩,否则加载动态库时会报错
        doNotStrip "*/x86/libsdkcore.so"
        doNotStrip "*/x86_64/libsdkcore.so"
        doNotStrip "*/armeabi/libsdkcore.so"
        doNotStrip "*/armeabi-v7a/libsdkcore.so"
        doNotStrip "*/arm64-v8a/libsdkcore.so"

        doNotStrip "*/x86/libfin-yuvutil.so"
        doNotStrip "*/x86_64/libfin-yuvutil.so"
        doNotStrip "*/armeabi/libfin-yuvutil.so"
        doNotStrip "*/armeabi-v7a/libfin-yuvutil.so"
        doNotStrip "*/arm64-v8a/libfin-yuvutil.so"
    }
}

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

# 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)涉及的敏感权限:

权限 相关接口、组件
存储读写 chooseMessageFile、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版本之前,SDK 仅支持配置一个服务器信息,只能打开单个环境中的小程序。配置参数如下:

FinAppConfig config = new FinAppConfig.Builder()
        .setSdkKey("SDK Key信息")   // SDK Key
        .setSdkSecret("SDK Secret信息")   // SDK Secret
        .setApiUrl("服务器地址")   // 服务器地址
        .setEncryptionType("加密方式")   // 加密方式,国密:SM,md5: MD5(推荐)
        .build();

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) {

            }
        });
    }
}

# 4. SDK使用示例

# 4.1 启动小程序

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

FinAppClient.INSTANCE.getAppletApiManager().startApplet(this, "5e0dc1f574193e00010d73c1");

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

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");
FinAppClient.INSTANCE.getAppletApiManager().startApplet(this, "5e0dc1f574193e00010d73c1", params);

# 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)
}

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

注意

为了避免微信SDK相关回调类冲突问题,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)。

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

如需自行接管“分享”按钮点击事件,请参考:回调方法 (opens new window)

请注意

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

集成方式:

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

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

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

注意

使用ShareSDK必须保证核心SDK版本在2.39.11或以上。

注意

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

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