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

# 代理方法

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

# 概览

  • IAppletHandler:最早的代理,内部包含button的open-type代理方法、更多面板等代理方法,将要弃用。
  • IAppletProcessHandler:部分在小程序进程触发的代理
  • AppletLoadingCallback:小程序loading页面自定义弹框的代理
  • AppletOpenCallback:小程序打开完成的代理
  • CapsuleHandler:小程序胶囊操作的代理
  • 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
    }
    
     /**
     * 默认返回true
     */
    fun getJSSDKConfig(json: JSONObject, callback: IAppletCallback)
    
    /**
     * 获取注册的"更多"菜单项
     *
     * @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

    部分在小程序进程触发的代理。

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

    interface IAppletProcessHandler {
    
        /**
         * 小程序导航栏中的"更多"按钮被点击
         *
         * @param appId 小程序ID
         * @return 返回true表示自行处理按钮点击事件,不需要执行默认操作(弹出菜单)。返回false表示需要执行默认操作
         */
        @Deprecated("Use CapsuleHandler.onMoreButtonClick() instead.")
        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. CapsuleHandler

        2.42.3版本增加。用于拦截和处理小程序胶囊按钮点击事件。

        /**
         * 用于宿主app接管胶囊操作的代理类
         */
        open class CapsuleHandler {
        
          class MoreButtonClickHandler {
            /**
             * 显示/隐藏 默认更多菜单。
             * (点击胶囊"更多"按钮默认逻辑)
             */
            fun changeDefaultMoreMenuVisibility()
          }
        
          class CloseButtonClickHandler {
            /**
             * 关闭小程序。
             * (点击胶囊"关闭"按钮默认逻辑)
             */
            fun closeApplet()
          }
        
          /**
           * 小程序胶囊"更多"按钮被点击
           *
           * @param context 小程序Context
           * @param appId 小程序ID
           */
          open fun onMoreButtonClick(context: Context, appId: String, handler: MoreButtonClickHandler)
        
          /**
           * 小程序胶囊"关闭"按钮被点击
           *
           * @param context 小程序Context
           * @param appId 小程序ID
           */
          open fun onCloseButtonClick(context: Context, appId: String, handler: CloseButtonClickHandler)
        }
        

        onMoreButtonClick拦截和处理胶囊"更多"按钮点击事件。可实现自定义更多面板。

        代码示例

          onCloseButtonClick拦截和处理胶囊"关闭"按钮点击事件。

          代码示例

            # 6. IAppletLifecycleObserver

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

            /**
             * 小程序生命周期回调新接口
             */
            interface IAppletLifecycleObserver {
            
              /**
               * 小程序打开完成的事件
               * @param appId 小程序ID
               */
              fun onOpen(appId: String)
            
              /**
               * 小程序关闭时的事件
               * @param appId 小程序ID
               */
              fun onClose(appId: String)
            
              /**
               * 小程序初始化完成,可以和基础库通信。
               * 整个生命周期只会执行一次
               * @param appId 小程序ID
               */
              fun onInitCompletion(appId: String)
            
              /**
               * 小程序进入活跃状态的事件
               * @param appId 小程序ID
               */
              fun onActive(appId: String)
            
              /**
               * 小程序进入非活跃状态的事件
               * @param appId 小程序ID
               */
              fun onInActive(appId: String)
            
              /**
               * 小程序出错的事件
               * @param appId 小程序ID
               * @param errorMsg 错误信息
               */
              fun onOpenFailure(appId: String, errorMsg: String)
            
              /**
               * 小程序被销毁的事件
               * @param appId 小程序ID
               */
              fun onDestroy(appId: String)
            }
            
            /**
             * 设置[IAppletLifecycleObserver]
             *
             * @param appletLifecycleObserver [IAppletLifecycleObserver]对象
             */
            fun setAppletLifecycleObserver(appletLifecycleObserver: IAppletLifecycleObserver)
            

            示例代码:

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

                # 8. IShareAppletHandler

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

                注意

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

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

                示例代码:

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

                  代码示例:

                    # 9. IAppJsonHandler

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

                    注意

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

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

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

                    代码示例:

                      在SDK初始化时进行设置。

                      示例代码:

                        # 10. 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
                        }
                        

                        示例代码:

                          # 11. 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);
                          

                          # 12. 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)
                          

                          # 13. 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 {
                                      // 主进程的其它初始化
                                  }
                              }
                          }
                          

                          # 14. 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)
                          

                          # 15. 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)
                          

                          # 16. 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)
                          

                          # 17. 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)
                          

                          # 18. 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"以适配默认多进程模式下的任务栈。
                          • 在自定义的页面中获取小程序权限列表、对小程序权限进行操作参考:自定义小程序权限设置页

                          # 19. 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)
                          

                          注意

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

                          # 20. 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)
                          

                          注意

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

                          # 21. 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全局配置为准。

                          # 22. 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 ❤