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

# 代理方法

小程序中部分业务是抽象定义的,这些抽象的业务通过接口的形式暴露给了外部,外部可以自行实现具体的业务逻辑。

# 概览

  • IAppletHandler:最早的代理,内部包含button的open-type代理方法、更多面板等代理方法,将要弃用。
  • IAppletProcessHandler:小程序右上角的胶囊中"更多"按钮点击的代理。
  • AppletLoadingCallback:小程序loading页面自定义弹框的代理。
  • AppletOpenCallback:小程序打开完成的代理。
  • IAppletLifecycleObserver:小程序生命周期事件代理
  • IAppletOpenTypeHandler:小程序中button组件的open-type事件的代理
  • IShareAppletHandler:小程序分享按钮被点击的代理
  • IAppJsonHandler:获取小程序appJson的代理
  • AboutAppletHandler:自定义小程序关于页面的代理
  • IUserInfoHandler:异步获取用户信息的代理
  • IUserProfileHandler:异步实现getUserProfile的代理
  • ShareSDKDelegate:分享小程序至外部的代理
  • ShortcutHandler:更多菜单“添加到桌面”事件的代理
  • IAuthRequestHandler:小程序授权弹框触发前置代理
  • IAuthResultHandler:小程序授权结果的代理
  • IAuthInfoHandler:自定义授权弹框的标题和提示的代理
  • IScopeSettingHandler:自定义设置页面的代理
  • ScopeDialogCustomHandler:自定义授权弹框内容的代理
  • IScopeStatusChangeHandler:小程序设置页授权状态改变的代理
  • IFinWatermarkFactory:小程序页面水印覆盖层的实现代理
  • IAppletConfigFactory:指定小程序进行部分特殊配置的代理

# 1. IAppletHandler

部分抽象业务被定义在IAppletHandler中,应用可以通过调用IAppletApiManagersetAppletHandlerIAppletHandler的实例传给SDK,当业务被触发时,SDK将通过IAppletHandler对应的方法回调给外部,执行外部实现的具体的业务逻辑。

/**
 * 小程序抽象业务回调接口,SDK将这些抽象的业务通过接口的形式暴露给外部,由外部具体实现
 */
interface IAppletHandler {

    interface IAppletCallback {

        /**
         * 成功回调
         */
        fun onSuccess(result: JSONObject? = null)

        /**
         * 失败回调
         */
        fun onFailure()

        /**
         * 取消回调
         */
        fun onCancel()
    }

    /**
     * 转发小程序
     *
     * @param appInfo 小程序信息,是一串json,包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。
     * [appInfo]的内容格式如下:
     * {
     *      "appTitle": "凡泰小程序",
     *      "appAvatar": "https:\/\/www.finogeeks.club\/statics\/images\/swan_mini\/swan_logo.png",
     *      "appId": "5df36b3f687c5c00013e9fd1",
     *      "appType": "trial",
     *      "userId": "finogeeks",
     *      "cryptInfo": "SFODj9IW1ENO8OA0El8P79aMuxB1DJvfKenZd7hrnemVCNcJ+Uj9PzkRkf/Pu5nMz0cGjj0Ne4fcchBRCmJO+As0XFqMrOclsqrXaogsaUPq2jJKCCao03vI8rkHilrWxSDdzopz1ifJCgFC9d6v29m9jU29wTxlHsQUtKsk/wz0BROa+aDGWh0rKvUEPgo8mB+40/zZFNsRZ0PjsQsi7GdLg8p4igKyRYtRgOxUq37wgDU4Ymn/yeXvOv7KrzUT",
     *      "params": {
     *           "title": "apt-test-tweet-接口测试发布的动态!@#¥%……&*(",
     *           "desc": "您身边的服务专家",
     *           "imageUrl": "finfile:\/\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png",
     *           "path": "pages\/tweet\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654",
     *           "appInfo": {
     *               "weixin": {
     *                   "path": "\/studio\/pages\/tweet\/tweet-detail",
     *                   "query": {
     *                       "fcid": "@staff_staff1:000000.finogeeks.com",
     *                       "timelineId": "db0c2098-031e-41c4-b9c6-87a5bbcf681d"
     *                    }
     *               }
     *           }
     *       }
     * }
     * [appInfo]中各字段的说明:
     * appId 小程序ID
     * appTitle 小程序名称
     * appAvatar 小程序头像
     * appType 小程序类型,其中trial表示体验版,temporary表示临时版,review表示审核版,release表示线上版,development表示开发版
     * userId 用户ID
     * cryptInfo 小程序加密信息
     * params 附带的其它参数,由小程序自己透传
     *     
     * @param bitmap 小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址,那么小程序封面图片
     * 就取[appInfo].params.imageUrl对应的图片,否则小程序的封面图片取[bitmap]。
     */
    fun shareAppMessage(appInfo: String, bitmap: Bitmap?, callback: IAppletCallback)

    /**
     * 获取用户信息
     *
     * @return 用户信息[Map]
     */
    fun getUserInfo(): Map<String, String>
  
  	/**
     * 获取用户手机号
     * 通过回调以json格式返回信息,一般格式如下:
     * {"phone": "xxxxxxxxxxx"}
     */
  	override fun getPhoneNumber(callback: IAppletHandler.IAppletCallback) {
        callback.onSuccess(JSONObject().put("phone", "xxxxxxxxxxx"))
    }

  	/**
     * 从小程序页面回到宿主app页面事件,由宿主app实现此操作;
     * @return 如果正确处理该事件返回true,否则返回false.
     */
    override fun launchApp(appParameter: String?): Boolean {
        return false
    }

  	/**
     * 打开"意见反馈"页面,由宿主app接管实现;
     * @return 如果宿主app接管此事件返回true,否则返回false,同时打开默认意见反馈页面。
     */
    override fun feedback(bundle: Bundle): Boolean {
        return false
    }

  	/**
     * 获取用户头像,通过回调返回信息,由SDK透传给小程序
     */
    override fun chooseAvatar(callback: IAppletHandler.IAppletCallback) {
        callback.onFailure()
    }

  	/**
     * 打开客服会话,由宿主app实现具体操作
     * @param json 由小程序透传给宿主app的数据
     * @return 成功打开会话返回true,否则返回false
     */
    override fun contact(json: JSONObject): Boolean {
        return false
    }
    
    /**
     * 获取注册的"更多"菜单项
     *
     * @param appId 小程序ID
     * @return 注册的"更多"菜单项
     */
    fun getRegisteredMoreMenuItems(appId: String): List<MoreMenuItem>?

    /**
     * 注册的"更多"菜单项被点击
     *
     * @param appId 小程序ID
     * @param path 小程序页面路径
     * @param menuItemId 被点击的菜单条目的ID
     * @param appInfo 小程序信息,是一串json,包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。
     * [appInfo]的内容格式如下:
     * {
     *      "appTitle": "凡泰小程序",
     *      "appAvatar": "https:\/\/www.finogeeks.club\/statics\/images\/swan_mini\/swan_logo.png",
     *      "appId": "5df36b3f687c5c00013e9fd1",
     *      "appType": "trial",     
     *      "userId": "finogeeks",
     *      "cryptInfo": "SFODj9IW1ENO8OA0El8P79aMuxB1DJvfKenZd7hrnemVCNcJ+Uj9PzkRkf/Pu5nMz0cGjj0Ne4fcchBRCmJO+As0XFqMrOclsqrXaogsaUPq2jJKCCao03vI8rkHilrWxSDdzopz1ifJCgFC9d6v29m9jU29wTxlHsQUtKsk/wz0BROa+aDGWh0rKvUEPgo8mB+40/zZFNsRZ0PjsQsi7GdLg8p4igKyRYtRgOxUq37wgDU4Ymn/yeXvOv7KrzUT",
     *      "params": {
     *           "title": "apt-test-tweet-接口测试发布的动态!@#¥%……&*(",
     *           "desc": "您身边的服务专家",
     *           "imageUrl": "finfile:\/\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png",
     *           "path": "pages\/tweet\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654",
     *           "appInfo": {
     *               "weixin": {
     *                   "path": "\/studio\/pages\/tweet\/tweet-detail",
     *                   "query": {
     *                       "fcid": "@staff_staff1:000000.finogeeks.com",
     *                       "timelineId": "db0c2098-031e-41c4-b9c6-87a5bbcf681d"
     *                    }
     *               }
     *           }
     *       }
     * }
     * [appInfo]中各字段的说明:
     * appId 小程序ID
     * appTitle 小程序名称
     * appAvatar 小程序头像
     * appType 小程序类型,其中trial表示体验版,temporary表示临时版,review表示审核版,release表示线上版,development表示开发版
     * userId 用户ID
     * cryptInfo 小程序加密信息
     * params 附带的其它参数,由小程序自己透传
     *
     * @param bitmap 小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址,那么小程序封面图片
     * 就取[appInfo].params.imageUrl对应的图片,否则小程序的封面图片取[bitmap]。
     */
    fun onRegisteredMoreMenuItemClicked(appId: String, path: String, menuItemId: String, appInfo: String?, bitmap: Bitmap?, callback: IAppletCallback)
    
    /**
     * 获取灰度发布配置参数
     *
     * @param appId 小程序ID
     * @return 灰度发布配置参数
     */
    fun getGrayAppletVersionConfigs(appId: String): List<GrayAppletVersionConfig>?
    
    /**
     * 小程序导航栏中的"关闭"按钮被点击
     *
     * @param appId 小程序ID
     */
    fun onNavigationBarCloseButtonClicked(appId: String)
}

# API

/**
 * 设置[IAppletHandler]的实现类
 *
 * @param appletHandler [IAppletHandler]的实现类
 */
fun setAppletHandler(appletHandler: IAppletHandler)

# 调用示例

    注意

    • FinAppClient类需要在主进程使用。
    • 对于异步回调的方法(参数带有callback),请务必保证无论业务逻辑成功与否都使用callback进行回调,否则小程序端会无法收到调用结果。

    # 2. IAppletProcessHandler

    用于拦截和处理小程序导航栏"更多"按钮点击事件。当代理方法返回true时,SDK不会展示更多面板,需要自定义实现更多面板。

    interface IAppletProcessHandler {
    
        /**
         * 小程序导航栏中的"更多"按钮被点击
         *
         * @param appId 小程序ID
         * @return 返回true表示自行处理按钮点击事件,不需要执行默认操作(弹出菜单)。返回false表示需要执行默认操作
         */
        fun onNavigationBarMoreButtonClicked(context: Context, appId: String): Boolean
    }
    

    示例代码

      # 3 AppletLoadingCallback

      注意

      • FinAppProcessClient类需要在小程序进程使用。请使用FinAppClient.INSTANCE.isFinAppProcess()方法判断是否处于小程序进程

      • AppletLoadingCallback中的代理方法会在小程序进程执行。

      宿主app可以自定义小程序loading页面的内容。适用的场景:宿主app在每次启动小程序时,添加一个弹框提示进入第三方应用内部等,或者添加隐私协议之类的等。

      SDK会根据代理方法中的是否需要自定义视图来确定是否要在loading页触发展示自定义内容的代理,当展示自定义内容时,需要宿主app在合适的时机调用callback里的onComplete小程序才会继续执行。

      举例:每次进入小程序时,在loading页展示一个弹框,告知现在将要进入第三方应用,有允许、拒绝两个按钮。当点击允许,则调用callback的onComplete();当点击拒绝,则关闭小程序。

      interface AppletLoadingCallback {
      
          /**
           * @param finAppInfo 小程序信息
           * 根据返回值,是否在loading页显示自定义内容
           */
          fun shouldShowCustomContent(finAppInfo: FinAppInfo): Boolean
      
          /**
           * 展示自定义的UI的接口
           * @param finAppInfo 小程序信息
           * @param activity 用于加载当前自定义页面的activity
           */
          fun showCustomContent(
              finAppInfo: FinAppInfo,
              activity: Activity,
              callback: AppletCustomContentHandler
          ) {
          }
      
      }
      

      代码示例:

      if (FinAppClient.isFinAppProcess(application)) {
        FinAppProcessClient.appletLoadingCallback =
          object : FinAppProcessClient.AppletLoadingCallback {
            override fun showCustomContent(
              finAppInfo: FinAppInfo,
              activity: Activity,
              handler: FinAppProcessClient.AppletCustomContentHandler
            ) {
              //使用acvitiy来承载当前的自定义页面
              val builder: AlertDialog.Builder = AlertDialog.Builder(activity)
              //如果不继续加载,则调用hanler.onComplete方法并将resume参数设置为false
              builder.setNegativeButton(R.string.cancel) { dialogInterface: DialogInterface, i: Int ->
                handler.onComplete(finAppInfo.appId, false, activity)
              }
              //如果继续加载,则调用hanler.onComplete方法并将resume参数设置为true
              builder.setPositiveButton(R.string.confirm) { dialogInterface: DialogInterface, i: Int ->
                handler.onComplete(finAppInfo.appId, true, activity)
              }
              builder.setMessage("appId : ${finAppInfo.appId}  appTitle : ${finAppInfo.appTitle}")
              builder.create().show();
            }
      
            override fun shouldShowCustomContent(finAppInfo: FinAppInfo): Boolean {
              return true;
            }
          }
      }
      

      # 4. AppletOpenCallback

      小程序打开完成的代理

      interface AppletOpenCallback {
          // 小程序打开完成的代理方法
          fun onAppletOpen(activity: Activity, appId: String, finAppInfo: FinAppInfo)
      }
      

      代码示例

        注意

        • FinAppProcessClient类需要在小程序进程使用。

          请使用FinAppClient.INSTANCE.isFinAppProcess()方法判断是否处于小程序进程

        • IAppletProcessHandler接口方法在小程序进程执行。

        # 5. IAppletLifecycleObserver

        宿主app如果需要监听小程序的生命周期,可以调用IAppletApiManagersetAppletLifecycleObserver接口把IAppletLifecycleObserver的实例传给SDK,当小程序的生命周期发生变化时,SDK会通过IAppletLifecycleCallback对应的方法回调给外部。

        /**
         * 小程序生命周期回调新接口
         */
        interface IAppletLifecycleObserver {
        
          /**
          小程序打开完成的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onOpen(appId: String?)
        
          /**
          小程序关闭完成的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onClose(appId: String?)
        
          /**
          小程序初始化完成,首页加载出来的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onInitCompletion(appId: String)
        
          /**
          小程序进入活跃状态的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onActive(appId: String?)
        
          /**
          小程序进入非活跃状态的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onInActive(appid: String?)
        
          /**
          小程序出错的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onOpenFailure(appId: String)
        
          /**
          小程序被销毁的事件
          @param appletInfo 小程序info
          @param error 错误对象
           */
          fun onDestroy(appId: String?)
        }
        
        /**
         * 设置[IAppletLifecycleObserver]
         *
         * @param appletLifecycleObserver [IAppletLifecycleObserver]对象
         */
        fun setAppletLifecycleObserver(appletLifecycleObserver: IAppletLifecycleObserver)
        

        示例代码:

          # 6. IAppletOpenTypeHandler

          2.37.13版本开始,IAppletHandler中拆分出来的专门用于open-type类型事件的代理,包含getPhoneNumberchooseAvatarlaunchAppcontactshareAppMessagefeedback

          /**
           * 将 [IAppletHandler] 中有关 open-type 的方法抽离出来进行单独处理,
           *
           * 若设置了 [IAppletOpenTypeHandler],则 [IAppletHandler] 中有关 open-type 的方法将不会响应。
           */
          interface IAppletOpenTypeHandler {
              /**
               * 获取手机号
               */
              fun getPhoneNumber(callback: IAppletHandler.IAppletCallback)
          
              /**
               * 选择头像
               */
              fun chooseAvatar(callback: IAppletHandler.IAppletCallback)
          
              /**
               * 从小程序返回到主app
               */
              fun launchApp(appParameter: String?): Boolean
          
              fun contact(json: JSONObject): Boolean
          
              /**
               * 转发小程序
               *
               * @param appInfo 小程序信息,是一串json,包含了小程序id、小程序名称、小程序图标、用户id、转发的数据内容等信息。
               * [appInfo]的内容格式如下:
               * {
               *      "appTitle": "凡泰小程序",
               *      "appAvatar": "https:\/\/www.finogeeks.club\/statics\/images\/swan_mini\/swan_logo.png",
               *      "appId": "5df36b3f687c5c00013e9fd1",
               *      "appType": "trial",
               *      "userId": "finogeeks",
               *      "cryptInfo": "SFODj9IW1ENO8OA0El8P79aMuxB1DJvfKenZd7hrnemVCNcJ+Uj9PzkRkf/Pu5nMz0cGjj0Ne4fcchBRCmJO+As0XFqMrOclsqrXaogsaUPq2jJKCCao03vI8rkHilrWxSDdzopz1ifJCgFC9d6v29m9jU29wTxlHsQUtKsk/wz0BROa+aDGWh0rKvUEPgo8mB+40/zZFNsRZ0PjsQsi7GdLg8p4igKyRYtRgOxUq37wgDU4Ymn/yeXvOv7KrzUT",
               *      "params": {
               *           "title": "apt-test-tweet-接口测试发布的动态!@#¥%……&*(",
               *           "desc": "您身边的服务专家",
               *           "imageUrl": "finfile:\/\/tmp_fc15edd8-2ff6-4c54-9ee9-fe5ee034033d1576550313667.png",
               *           "path": "pages\/tweet\/tweet-detail.html?fcid=%40staff_staff1%3A000000.finogeeks.com&timelineId=db0c2098-031e-41c4-b9c6-87a5bbcf681d&shareId=3dfa2f78-19fc-42fc-b3a9-4779a6dac654",
               *           "appInfo": {
               *               "weixin": {
               *                   "path": "\/studio\/pages\/tweet\/tweet-detail",
               *                   "query": {
               *                       "fcid": "@staff_staff1:000000.finogeeks.com",
               *                       "timelineId": "db0c2098-031e-41c4-b9c6-87a5bbcf681d"
               *                    }
               *               }
               *           }
               *       }
               * }
               * [appInfo]中各字段的说明:
               * appId 小程序ID
               * appTitle 小程序名称
               * appAvatar 小程序头像
               * appType 小程序类型,其中trial表示体验版,temporary表示临时版,review表示审核版,release表示线上版,development表示开发版
               * userId 用户ID
               * cryptInfo 小程序加密信息
               * params 附带的其它参数,由小程序自己透传
               *
               * @param bitmap 小程序封面图片。如果[appInfo].params.imageUrl字段为http、https的链接地址,那么小程序封面图片
               * 就取[appInfo].params.imageUrl对应的图片,否则小程序的封面图片取[bitmap]。
               * @param callback 转发小程序结果回调。
               */
              fun shareAppMessage(appInfo: String, bitmap: Bitmap?, callback: IAppletHandler.IAppletCallback)
          
              /**
               * 打开宿主app用户反馈
               */
              fun feedback(bundle: Bundle): Boolean
          }
          

          示例代码:

            注意

            • FinAppClient类需要在主进程使用。

            • 设置了IAppletOpenTypeHandler,将会覆盖掉IAppletHandler中以上open-type方法的实现。

            • 若集成了微信扩展SDK(WeChatSDK),请勿使用该接口类,而是使用:

              WeChatOpenTypeClient.instance.iWeChatOpenTypeHandler = MyWeChatAppletOpenTypeHandler()
              

            # 7. IShareAppletHandler

            2.39.11 版本开始,小程序更多菜单中会新增”分享“按钮,可以依赖 ShareSDK 并进行相应的简单配置,实现分享小程序的功能,也可以自行实现 IShareAppletHandler 接口,实现对应功能。

            注意

            IShareAppletHandler 的实现类将会在小程序运行时通过反射创建示例,因此请保持无参构造方法,并不要直接访问主进程内的变量,否则将会出现异常。

            interface IShareAppletHandler {
                fun onShareApplet(context: Context, appInfo: FinAppInfo, appletPagePath: String)
            }
            

            示例代码:

              并在SDK初始化时进行设置。

              代码示例:

                # 8. IAppJsonHandler

                2.40.1 版本开始,支持宿主App获取启动的小程序的app.json内容。

                注意

                IAppJsonHandler 的实现类将会在小程序运行时通过反射创建示例,因此请保持无参构造方法,并不要直接访问主进程内的变量,否则将会出现异常。

                该代理方法中返回的是app.json和page.json中的内容经过编译库处理之后的内容。

                interface IAppJsonHandler {
                    fun onAppJsonInit(appInfo: FinAppInfo, appJson: String)
                }
                

                代码示例:

                  在SDK初始化时进行设置。

                  示例代码:

                    # 9. AboutAppletHandler

                    2.40.5 版本开始,支持宿主app自定义小程序关于页。 宿主工程继承AboutAppletHandler类,在goToAboutPage方法中跳转自定义关于页。

                    /**
                     * 打开自定义关于小程序页面。
                     * 如果自定义关于小程序页面是Activity,那么在AndroidManifest.xml声明Activity时建议设置
                     * android:multiprocess="true",试Activity可以运行到小程序进程,
                     * 这样Activity能跟随小程序进程结束(如小程序调用finishRunningApplet)
                     *
                     * @param appInfo 小程序信息
                     *
                     * @return true 打开自定义关于小程序页面,false 打开默认关于小程序页面
                     */
                    open fun goToAboutPage(context: Context, appInfo: FinAppInfo): Boolean {
                        return false
                    }
                    

                    示例代码:

                      # 10. IUserInfoHandler

                      之前的IAppletOpenTypeHandler 和 IAppletHandler 代理方法都需要宿主app 同步获取用户信息并返回。 但是,可能有的场景宿主app只能异步拿到宿主app的用户信息,所以我们新增了该代理。

                      注意

                      • 设置代理需要在主进程中SDK初始化成功之后设置。
                      • 实现该代理之后,IAppletHandler 和 IAppletOpenTypeHandler 中同步返回结果的 getUserInfo 方法都不会再触发。
                      • 该代理中的事件将会在主进程中触发。
                      interface IUserInfoHandler {
                      
                          fun getUserInfo(callback: IAppletHandler.IAppletCallback)
                      }
                      

                      示例代码:

                      public class MyUserInfoHandler extends IUserInfoHandler {
                          @Override
                          public void getUserInfo(@NotNull IAppletHandler.IAppletCallback callback) {
                              try {
                                  JSONObject jsonObj = new JSONObject();
                                  jsonObj.put("nickname", "test_nickname");
                                  jsonObj.put("avatarUrl", "test_avatarUrl");
                                  callback.onSuccess(jsonObj);
                              } catch (JSONException e) {
                                  e.printStackTrace();
                                  callback.onFailure();
                              }
                          }
                      }
                      
                      MyUserInfoHandler userInfoHandler = new MyUserInfoHandler();
                      FinAppClient.INSTANCE.getAppletApiManager().setUserInfoHandler(userInfoHandler);
                      

                      # 11. IUserProfileHandler

                      当小程序中调用getUserProfile接口时,会触发该代理,宿主app可实现该代理方法。

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。(从2.41.5版本开始,将会固定运行在主进程中)
                      • 方法中的contextApplicationContext,请勿直接用于启动Activity等操作。
                      • 若需要实现 getUserProfile 方法,请勿使用自定义api的方式,而是实现代理类的方式。
                      interface IUserProfileHandler {
                          fun getUserProfileWithAppletInfo(
                              context: Context,
                              finAppInfo: FinAppInfo,
                              callback: UserProfileCallback
                          )
                      
                          interface UserProfileCallback {
                              fun onSuccess(result: JSONObject?)
                      
                              fun onError(msg: String?)
                          }
                      }
                      

                      1)实现代理方法

                      实现IUserProfileHandler接口,在getUserProfileWithAppletInfo中完成获取UserProfile的逻辑。

                      示例如下:

                      public class MyUserProfileHandler implements IUserProfileHandler {
                          @Override
                          public void getUserProfileWithAppletInfo(@NotNull Context context,
                                                                   @NotNull FinAppInfo finAppInfo,
                                                                   @NotNull IUserProfileHandler.UserProfileCallback callback) {
                              try {
                                  JSONObject jsonObj = new JSONObject();
                                  jsonObj.put("nickname", "test_nickname");
                                  jsonObj.put("avatarUrl", "test_avatarUrl");
                                  callback.onSuccess(jsonObj);
                              } catch (JSONException e) {
                                  e.printStackTrace();
                                  callback.onError(null);
                              }
                          }
                      }
                      

                      2)设置代理

                      在SDK初始化时注入该实现类:

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setGetUserProfileHandlerClass(MyUserProfileHandler::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      # 12. ShareSDKDelegate

                      2.40.11版本开始,ShareSDK支持自定义分享落地页的链接、分享链接中的apk下载地址。

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      1. 实现代理方法

                      继承ShareSDKDelegate类,并根据需要重写其中的方法。

                      代码示例:

                      public class MyShareDelegate extends ShareSDKDelegate {
                          @Override
                          public void onCustomShareUrl(@NonNull Context context, 
                                                       @NonNull FinAppInfo finAppInfo, 
                                                       @NonNull FinCallback<String> callback) {
                              // 自定义分享落地页链接
                              callback.onSuccess("https://example.com/share/path");
                          }
                      
                          @Override
                          public void onCustomAppDownloadLink(@NonNull Context context, 
                                                              @NonNull FinAppInfo finAppInfo, 
                                                              @NonNull FinCallback<String> callback) {
                              // 自定义分享链接中的apk下载地址
                              callback.onSuccess("https://example.com/download/app.apk");
                          }
                      }
                      

                      2) 设置代理的实现类

                      在【小程序进程】内进行设置。

                      代码示例:

                      public class MyApplication extends Application {
                      
                          @Override
                          public void onCreate() {
                              super.onCreate();
                              if (FinAppClient.INSTANCE.isFinAppProcess(this)) {
                                  // 小程序进程的初始化
                                  FinShareSDK.setShareSdkDelegateClass(MyShareDelegate.class);
                              } else {
                                  // 主进程的其它初始化
                              }
                          }
                      }
                      

                      # 13. ShortcutHandler

                      2.41.5版本开始,支持对更多菜单中的“添加到桌面”按钮事件进行自定义。

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。
                      open class ShortcutHandler {
                      
                          open fun addToDesktop(
                              context: Context,
                              appInfo: FinAppInfo,
                              appletCurrentPath: String
                          ) {
                      
                          }
                      }
                      
                      1. 实现ShortcutHandler中的代理方法

                      继承ShortcutHandler类,并根据重写addToDesktop方法。

                      代码示例:

                      class MyShortcutHandler : ShortcutHandler() {
                          override fun addToDesktop(
                              context: Context,
                              appInfo: FinAppInfo,
                              appletCurrentPath: String
                          ) {
                              Toast.makeText(
                                  context,
                                  "${appInfo.appTitle}: $appletCurrentPath",
                                  Toast.LENGTH_LONG
                              ).show()
                          }
                      }
                      
                      1. 设置实现代理类

                      在SDK初始化时注入该实现类:

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setShortcutHandlerClass(MyShortcutHandler::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      # 14. IAuthRequestHandler

                      2.40.3版本开始,支持宿主app对小程序内的权限请求做前置处理。即小程序里再触发权限弹框逻辑之前会先触发该代理,由宿主app决定是否允许小程序申请该权限。

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。
                      /**
                       * 用于宿主app对scope请求或系统权限申请的前置处理代理类
                       */
                      interface IAuthRequestHandler {
                          fun onAuthRequest(
                              context: Context,
                              appInfo: FinAppInfo,
                              auth: AuthEnum,
                              callback: IAuthRequestCallback
                          )
                      
                          interface IAuthRequestCallback {
                              fun allowAuthRequest(preAllow: Boolean)
                          }
                      }
                      

                      1)宿主app实现IAuthRequestHandler接口,在onAuthRequest方法中处理权限的前置请求。

                      示例代码:

                      class AuthRequestHandler : IAuthRequestHandler {
                      
                          override fun onAuthRequest(
                              context: Context,
                              appInfo: FinAppInfo,
                              auth: AuthEnum,
                              callback: IAuthRequestHandler.IAuthRequestCallback
                          ) {
                              AlertDialog.Builder(context)
                                  .setTitle("宿主app前置处理权限申请")
                                  .setMessage("权限:$auth")
                                  .setPositiveButton("允许") { dialog, which ->
                                      callback.allowAuthRequest(true)
                                  }
                                  .setNegativeButton("拒绝") { dialog, which ->
                                      callback.allowAuthRequest(false)
                                  }
                                  .setCancelable(false)
                                  .show()
                          }
                      }
                      

                      参数说明:

                      参数名 作用
                      context 上下文对象
                      appInfo 小程序的相关信息
                      auth 申请的权限
                      callback 权限前置请求的结果回调

                      AuthEnum说明:

                      权限的枚举类,不区分小程序权限和系统权限,而是针对权限行为的具体描述,目前支持的权限如下:

                      枚举类 说明
                      AUTH_USERINFO 用户信息
                      AUTH_USER_LOCATION 地理位置
                      AUTH_RECORD 录音
                      AUTH_READ_EXTERNAL_STORAGE 读取权限
                      AUTH_WRITE_EXTERNAL_STORAGE 写入权限
                      AUTH_CAMERA 摄像头
                      AUTH_BLUETOOTH 蓝牙
                      AUTH_CONTACT 通讯录
                      AUTH_PHONE_NUMBER 手机号

                      2) 在SDK初始化时注入该实现类

                      val config = FinAppConfig.Builder()
                        // 其它配置省略
                        .setAuthRequestHandlerClass(AuthRequestHandler::class.java)
                        .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      # 15. IAuthResultHandler

                      2.40.3版本开始,支持宿主app接收小程序内的权限请求的结果。(目前仅支持核心SDK、扩展SDK的相关api)

                      /**
                       * 用于宿主app对scope请求或系统权限申请的申请结果回调的代理类
                       */
                      interface IAuthResultHandler {
                          fun onAuthResult(
                              context: Context,
                              appInfo: FinAppInfo,
                              auth: AuthEnum,
                              result: Boolean
                          )
                      }
                      

                      1)宿主app实现IAuthResultHandler接口,在onAuthResult方法中接收权限的请求结果。

                      示例如下:

                      class AuthResultHandler : IAuthResultHandler {
                      
                          override fun onAuthResult(
                              context: Context,
                              appInfo: FinAppInfo,
                              auth: AuthEnum,
                              result: Boolean
                          ) {
                              AlertDialog.Builder(context)
                                  .setTitle("${appInfo.appTitle}权限申请结果回调")
                                  .setMessage("权限:${auth}, 申请结果:$result")
                                  .setPositiveButton("确定") { dialog, which ->
                      
                                  }
                                  .show()
                          }
                      }
                      

                      参数说明:

                      参数名 作用
                      context 上下文对象
                      appInfo 小程序的相关信息
                      auth 本次申请的权限
                      result 本次权限申请结果

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。

                      2)在SDK初始化时注入该实现类

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setAuthResultHandlerClass(AuthResultHandler::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      # 16. IAuthInfoHandler

                      2.40.3版本开始,支持宿主app自定义隐私授权弹窗详情说明中的标题、文案。

                      interface IAuthInfoHandler {
                      
                        fun customizeAuthInfo(
                          context: Context,
                          scope: String,
                          appInfo: FinAppInfo,
                          callback: IAuthInfoCallback
                        )
                      }
                      

                      1)宿主工程实现IAuthInfoHandler接口,在customizeAuthInfo方法中进行自定义。

                      示例如下:

                      class AuthInfoHandler : IAuthInfoHandler {
                          override fun customizeAuthInfo(
                              context: Context,
                              scope: String,
                              appInfo: FinAppInfo,
                              callback: IAuthInfoHandler.IAuthInfoCallback
                          ) {
                              val authInfo = IAuthInfoHandler.AuthInfo(
                                  "隐私授权标题",
                                  "隐私授权文案"
                              )
                              callback.authInfoCallback(authInfo)
                          }
                      }
                      

                      参数说明:

                      参数名 作用
                      context 上下文对象
                      scope 本次隐私授权说明对应的小程序权限
                      appInfo 小程序的相关信息
                      callback 自定义隐私授权说明回调

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。

                      2)在SDK初始化时注入该实现类

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setAuthInfoHandlerClass(AuthInfoHandler::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      # 17. IScopeSettingHandler

                      2.40.3版本开始,支持宿主app自定义小程序权限设置页。

                      interface IScopeSettingHandler {
                          // 是否自定义设置页面
                          fun customizeSettingPageOnAppletInfo(finApplet: FinApplet): Boolean
                          // 打开设置页面
                          fun openCustomizeSettingPage(context: Context, finApplet: FinApplet)
                      }
                      

                      1)宿主工程实现IScopeSettingHandler接口,在customizeSettingPageOnAppletInfo方法中确认是否要跳转自定义页面,在openCustomizeSettingPage方法中做具体的跳转。

                      示例如下:

                      class AuthSettingHandler: IScopeSettingHandler {
                          override fun customizeSettingPageOnAppletInfo(finApplet: FinApplet): Boolean {
                              return true
                          }
                      
                          override fun openCustomizeSettingPage(context: Context, finApplet: FinApplet) {
                              val intent = Intent(context, CustomAuthSettingActivity::class.java)
                              context.startActivity(intent)
                          }
                      }
                      

                      2)在SDK初始化时注入该实现类

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setScopeSettingHandlerClass(AuthSettingHandler::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。
                      • 该实现类的执行进程根据小程序进程的设置而定,默认情况下运行在子进程中,因此请勿直接访问主进程的变量。
                      • 自定义的Activity,在清单文件的声明中要加上android:multiprocess="true"以适配默认多进程模式下的任务栈。
                      • 在自定义的页面中获取小程序权限列表、对小程序权限进行操作参考:自定义小程序权限设置页

                      # 18. ScopeDialogCustomHandler

                      2.40.11版本开始,支持对Scope权限弹窗的部分内容进行自定义。

                      代理方法以及默认实现如下

                      open class ScopeDialogCustomHandler {
                        
                        /**
                        是否向Scope权限弹窗内插入自定义的视图,若返回null则是不插入。
                        可以根据需要,对特定的小程序或特定的权限做自定义处理。
                         */
                        open fun onCustomView(context: Context, finAppInfo: FinAppInfo, scope: AppletScopeBean): View? {
                          return null
                        }
                      
                        /**
                        是否隐藏Scope权限弹窗内自带的权限标题和描述,默认为false,即不隐藏。
                         */
                        open fun isHideTitleAndDescription(
                          context: Context,
                          finAppInfo: FinAppInfo,
                          scope: AppletScopeBean
                        ): Boolean {
                          return false
                        }
                      
                        /**
                        是否隐藏Scope权限弹窗内自带的后台定位权限的额外选项,默认为false,即不隐藏。
                      
                        对于后台定位权限,弹窗内会比其它权限多两个选项,即【使用小程序时】和【使用小程序时和离开后】。
                         */
                        open fun isHideLocationScopeOption(
                          context: Context,
                          finAppInfo: FinAppInfo,
                          scope: AppletScopeBean
                        ): Boolean {
                          return false
                        }
                      
                        /**
                        是否隐藏Scope权限弹窗内自带的【拒绝】、【允许】按钮,默认为false,即不隐藏。
                        若隐藏了这两个按钮之后,务必在`onCustomView`中自定的布局内实现对应的按钮,并加上`deny()`或`allow()`的方法调用。
                         */
                        open fun isHideButton(
                          context: Context,
                          finAppInfo: FinAppInfo,
                          scope: AppletScopeBean
                        ): Boolean {
                          return false
                        }
                      }
                      

                      1)继承ScopeDialogCustomHandler类,并根据需要重写其中的方法。

                      示例如下:

                      public class MyScopeUICustom extends ScopeDialogCustomHandler {
                      
                          private View view;
                      
                          @Nullable
                          @Override
                          public View onCustomView(@NonNull Context context,
                                                   @NonNull FinAppInfo finAppInfo,
                                                   @NonNull AppletScopeBean appletScopeBean) {
                              if (AppletScopeBean.SCOPE_USERINFO.equals(appletScopeBean.getScope())) {
                                  return null;
                              } else {
                                  view = LayoutInflater.from(context).inflate(R.layout.myview, null);
                                  return view;
                              }
                          }
                      
                          @Override
                          public boolean isHideTitleAndDescription(@NonNull Context context,
                                                                   @NonNull FinAppInfo finAppInfo,
                                                                   @NonNull AppletScopeBean appletScopeBean) {
                              return true;
                          }
                      
                          @Override
                          public boolean isHideButton(@NonNull Context context,
                                                      @NonNull FinAppInfo finAppInfo,
                                                      @NonNull AppletScopeBean appletScopeBean) {
                              return true;
                          }
                      
                          @Override
                          public boolean isHideLocationScopeOption(@NonNull Context context,
                                                                   @NonNull FinAppInfo finAppInfo,
                                                                   @NonNull AppletScopeBean appletScopeBean) {
                              return true;
                          }
                      }
                      

                      设置isHideButton为true时的实例代码:

                      @Nullable
                      @Override
                      public View onCustomView(@NonNull Context context,
                                               @NonNull FinAppInfo finAppInfo,
                                               @NonNull AppletScopeBean appletScopeBean) {
                          view = LayoutInflater.from(context).inflate(R.layout.myview, null);
                          Button btnDeny = view.findViewById(R.id.btnDeny);
                          Button btnAllow = view.findViewById(R.id.btnAllow);
                          btnDeny.setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  deny();
                              }
                          });
                          btnAllow.setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  allow();
                              }
                          });
                          return view;
                      }
                      
                      @Override
                      public boolean isHideButton(@NonNull Context context,
                                                  @NonNull FinAppInfo finAppInfo,
                                                  @NonNull AppletScopeBean appletScopeBean) {
                          return true;
                      }
                      

                      对于后台定位权限,弹窗内会比其它权限多两个选项,即【使用小程序时】和【使用小程序时和离开后】。

                      若隐藏了这两个选项之后,务必在onCustomView中自定义的布局内实现对应的选项,并在调用allow()方法时加上具体类型。

                      设置isHideLocationScopeOption为true时的示例代码:

                      @Nullable
                      @Override
                      public View onCustomView(@NonNull Context context,
                                               @NonNull FinAppInfo finAppInfo,
                                               @NonNull AppletScopeBean appletScopeBean) {
                          view = LayoutInflater.from(context).inflate(R.layout.myview, null);
                          Button btnDeny = view.findViewById(R.id.btnDeny);
                          Button btnAllow = view.findViewById(R.id.btnAllow);
                          CheckBox cbAllowWhenUsing = view.findViewById(R.id.cbAllowWhenUsing);
                          CheckBox cbAllow = view.findViewById(R.id.cbAllow);
                          btnDeny.setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  deny();
                              }
                          });
                          btnAllow.setOnClickListener(new View.OnClickListener() {
                              @Override
                              public void onClick(View v) {
                                  if (AppletScopeBean.SCOPE_USER_LOCATION_BACKGROUND.equals(appletScopeBean.getScope())) {
                                      // 后台定位权限的允许要特殊处理
                                      if (cbAllowWhenUsing.isChecked()) {
                                          allow(AppletScopeBean.Status.ALLOW_WHEN_USING);
                                      } else {
                                          allow(AppletScopeBean.Status.ALLOW);
                                      }
                                  } else {
                                      // 其它权限的允许直接调用无参方法即可
                                      allow();
                                  }
                      
                              }
                          });
                          return view;
                      }
                      
                      @Override
                      public boolean isHideLocationScopeOption(@NonNull Context context,
                                                               @NonNull FinAppInfo finAppInfo,
                                                               @NonNull AppletScopeBean appletScopeBean) {
                          return true;
                      }
                      

                      3)在SDK初始化时注入该实现类:

                      val config = FinAppConfig.Builder()
                          // 其它配置省略
                          .setScopeDialogCustomHandlerClass(MyScopeUICustom::class.java)
                          .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,因此请勿在此类内存储变量值并进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。

                      # 19. IScopeStatusChangeHandler

                      2.41.7版本开始,支持监听设置页内用户操作小程序权限的变化情况。

                      interface IScopeStatusChangeHandler {
                          fun onScopeStatusChange(
                              context: Context,
                              appId: String,
                              scope: String,
                              status: AppletScopeBean.Status
                          )
                      }
                      

                      1)宿主工程实现IScopeStatusChangeHandler接口,示例如下:

                      class ScopeChangeHandler : IScopeStatusChangeHandler {
                      
                          override fun onScopeStatusChange(
                              context: Context,
                              appId: String,
                              scope: String,
                              status: AppletScopeBean.Status
                          ) {
                              Toast.makeText(context, "${appId}, ${scope}: $status", Toast.LENGTH_SHORT).show()
                          }
                      }
                      

                      2)在SDK初始化时注入该实现类:

                      val config = FinAppConfig.Builder()
                        // 其它配置省略
                        .setScopeStatusChangeHandler(ScopeChangeHandler::class.java)
                        .build()
                      FinAppClient.init(application, config, finCallback)
                      

                      注意

                      • 该实现类可能会根据小程序的运行情况而定,不同的小程序有不同的该实现类实例,并可能会多次实例化,因此请勿在此类内存储变量值进行使用,否则可能会出现空值等情况。
                      • 该实现类会在小程序运行时以反射的机制进行实例化,因此请保持无参的构造方法。

                      # 20. IFinWatermarkFactory

                      宿主工程实现IFinWatermarkFactory接口,可以对小程序界面覆盖自定义水印层,以下为使用说明。

                      interface IFinWatermarkFactory {
                          
                          /**
                           * @param context Context对象
                           * @param layoutParams View对象的LayoutParams
                           * @param finAppInfo 小程序信息
                           * @param extra 水印的额外参数,可能为空
                           */
                          fun createWatermarkView(
                              context: Context,
                              layoutParams: RelativeLayout.LayoutParams,
                              finAppInfo: FinAppInfo,
                              extra: JSONObject?
                          ): View
                      }
                      
                      1. 实现IFinWatermarkFactory接口

                      代码示例:

                      class WatermarkViewFactory : IFinWatermarkFactory {
                          
                          /**
                           * @param context Context对象
                           * @param layoutParams View对象的LayoutParams
                           * @param finAppInfo 小程序信息
                           * @param extra 水印的额外参数,可能为空
                           */
                          override fun createWatermarkView(
                              context: Context,
                              layoutParams: RelativeLayout.LayoutParams,
                              finAppInfo: FinAppInfo,
                              extra: JSONObject?
                          ): View {
                              // 返回您的自定义View作为水印层覆盖在小程序界面
                          }
                      }
                      
                      1. 初始化时设置水印配置
                      val config = FinAppConfig.Builder()
                          // 是否开启水印
                          .setEnableWatermark(true)
                          // 水印工厂接口IFinWatermarkFactory的实现类,由宿主app自行实现
                          .setWatermarkFactory(WatermarkViewFactory::class.java)
                          // 水印配置优先级
                          .setWatermarkPriority(FinAppConfigPriority.GLOBAL)
                          // 其它配置项省略
                          .build()
                      
                      FinAppClient.init(application, config, finCallback)
                      

                      优先级可选项为:

                      优先级 说明
                      FinAppConfigPriority.GLOBAL 默认值,全局优先,即以SDK全局的配置为准
                      FinAppConfigPriority.SPECIFIED 以指定AppId的配置为准(详细说明看下文);
                      若未配置,则以SDK全局配置为准。
                      FinAppConfigPriority.APPLET_FILE 以小程序自身的配置为准;
                      若小程序自身未配置,则以指定AppId的配置为准;
                      若指定AppId未配置,则以SDK全局配置为准。

                      # 21. IAppletConfigFactory

                      宿主工程实现IAppletConfigFactory接口,可以针对指定的AppId做部分特定配置。

                      interface IAppletConfigFactory {
                      
                          fun createAppletConfig(
                              appId: String,
                              startParams: FinAppInfo.StartParams?
                          ): FinSpecifiedAppletConfig?
                      }
                      
                      1. 实现IAppletConfigFactory接口
                      class AppletConfigFactory : IAppletConfigFactory {
                      
                          override fun createAppletConfig(
                              appId: String,
                              startParams: FinAppInfo.StartParams?
                          ): FinSpecifiedAppletConfig? {
                              return when (appId) {
                                  // 指定小程序进行特定配置
                                  "60dacf37a2b11b0001c43a17" -> {
                                      val builder = FinSpecifiedAppletConfig.Builder()
                                      // 是否允许截屏录屏
                                      builder.setEnableScreenShot(false)
                                      // 是否开启水印
                                      builder.setEnableWatermark(false)
                                      // 是否隐藏导航栏上的"返回首页"按钮
                                      builder.setIsHideBackHome(false)
                                      // http接口header
                                      builder.header = mapOf("key" to "value")
                                      // 创建Config
                                      builder.build()
                                  }
                                  // 非指定小程序,直接返回null即可
                                  else -> null
                              }
                          }
                      }
                      
                      1. 初始化时进行优先级设置
                      val appletConfigFactory = AppletConfigFactory()
                      val config = FinAppConfig.Builder()
                          // 截屏录屏配置优先级为指定AppId级
                          .setScreenShotPriority(FinAppConfigPriority.SPECIFIED)
                          // 水印配置优先级为指定AppId级
                          .setWatermarkPriority(FinAppConfigPriority.SPECIFIED)
                          // IAppletConfigFactory接口的实现类
                          .setAppletConfigFactory(appletConfigFactory)
                          // 其它配置项省略
                          .build()
                      
                      © 2022 FinClip with ❤