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:指定小程序进行部分特殊配置的代理
  • IPrivacyHandler:自定义隐私协议信息的代理
  • AppletWebViewLoadHandler:支持宿主app控制webview是否可加载H5链接
  • AppletConfigHandler: 小程序配置的代理
  • AppletGrayVersionHandler:小程序灰度配置的代理

# 1. IAppletHandler

支持的app类型

小程序✅ 小游戏🚫 H5应用🚫

部分抽象业务被定义在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

    支持的app类型

    小程序✅ 小游戏✅ H5应用✅

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

    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

      支持的app类型

      小程序✅ 小游戏🚫 H5应用🚫

      注意

      • 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

      支持的app类型

      小程序✅ 小游戏🚫 H5应用🚫

      小程序打开完成的代理。

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

      代码示例

        注意

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

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

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

        # 5. CapsuleHandler

        支持的app类型

        小程序✅ 小游戏🚫 H5应用🚫

        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)
          
          /**
             * 获取注册的"更多"菜单项
             *
             * @param appId 小程序ID
             * @return 注册的"更多"菜单项
             */
            open fun getRegisteredMoreMenuItems(context: Context, appId: String): List<MoreMenuItem>? {
                return null
            }
        
            /**
             * 注册的"更多"菜单项被点击
             *
             * @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]。
             * @param callback 转发小程序结果回调。
             */
             open fun onRegisteredMoreMenuItemClicked(
                context: Context,
                appId: String,
                path: String,
                menuItemId: String,
                appInfo: String?,
                bitmap: Bitmap?,
                callback: IAppletHandler.IAppletCallback) {
        
             }
        
        }
        

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

        代码示例

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

          代码示例

            小程序自定义菜单以及自定义菜单被点击的代理。

            代码示例

              # 6. IAppletLifecycleObserver

              支持的app类型

              小程序✅ 小游戏✅ H5应用✅

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

              /**
               * 小程序生命周期回调新接口
               */
              interface IAppletLifecycleObserver {
              
                /**
                 * 小程序打开完成的事件
                 * 
                 * 此时service层已经加载完成,可以和基础库通信;
                 * 整个生命周期只会执行一次;
                 * 
                 * @param appId 小程序ID
                 */
                fun onOpen(appId: String)
              
                /**
                 * 小程序关闭时的事件
                 * 
                 * 所有调用小程序关闭的API都会触发这个回调;
                 * 小程序关闭,并不代表小程序的Activity被销毁;
                 * 如果是非单任务栈的情况,只是将小程序Activity任务栈移动到后台;
                 * 
                 * @param appId 小程序ID
                 */
                fun onClose(appId: String)
              
                /**
                 * 小程序初始化完成
                 * 
                 * 此时service层已经加载完成,可以和基础库通信;
                 * 整个生命周期只会执行一次;
                 * 
                 * @param appId 小程序ID
                 */
                fun onInitCompletion(appId: String)
              
                /**
                 * 小程序进入活跃状态的事件
                 * 
                 * 1、冷启动,开始加载小程序的页面;
                 * 2、热启动,小程序的 Activity onResume之后(前提是service层已经加载完成);
                 * 
                 * @param appId 小程序ID
                 */
                fun onActive(appId: String)
              
                /**
                 * 小程序进入非活跃状态的事件
                 * 
                 * 小程序的 Activity onPause之后 (前提是service层已经加载完成);
                 * 
                 * @param appId 小程序ID
                 */
                fun onInActive(appId: String)
              
                /**
                 * 小程序出错的事件
                 * 
                 * 只要出现错误,都会触发这个回调;
                 * 
                 * @param appId 小程序ID
                 * @param errorMsg 错误信息
                 */
                fun onOpenFailure(appId: String, errorMsg: String)
              
                /**
                 * 小程序被销毁的事件
                 * 
                 * 小程序的 Activity onDestroy之后;
                 * 小程序真实的被关闭;
                 * 
                 * @param appId 小程序ID
                 */
                fun onDestroy(appId: String)
              }
              
              /**
               * 设置[IAppletLifecycleObserver]
               *
               * @param appletLifecycleObserver [IAppletLifecycleObserver]对象
               */
              fun setAppletLifecycleObserver(appletLifecycleObserver: IAppletLifecycleObserver)
              

              示例代码:

                # 7. IAppletOpenTypeHandler

                支持的app类型

                小程序✅ 小游戏🚫 H5应用🚫

                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

                  支持的app类型

                  小程序✅ 小游戏🚫 H5应用🚫

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

                  注意

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

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

                  示例代码:

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

                    代码示例:

                      # 9. IAppJsonHandler

                      支持的app类型

                      小程序✅ 小游戏🚫 H5应用🚫

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

                      注意

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

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

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

                      代码示例:

                        在SDK初始化时进行设置。

                        示例代码:

                          # 10. AboutAppletHandler

                          支持的app类型

                          小程序✅ 小游戏🚫 H5应用🚫

                          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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            之前的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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            当小程序中调用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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用🚫

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

                            interface IAuthInfoHandler {
                            
                              /**
                               * 获取自定义隐私授权弹窗详情说明中的标题和文案
                               * @param context [Context]实例
                               * @param scope scope名称
                               * @param appInfo 小程序信息
                               * @param callback 接口回调
                               */ 
                              fun customizeAuthInfo(
                                context: Context,
                                scope: String,
                                appInfo: FinAppInfo,
                                callback: IAuthInfoCallback
                              )
                              
                              /**
                               * 当文档链接被点击时
                               * @param context [Context]实例
                               * @param appInfo 小程序信息
                               * @param docName 文档名称
                               * @param docUrl 文档链接
                               * @return 是否有自行处理点击事件。如果有自行处理点击事件,则返回 true,SDK 内部将不再处理点击事件。
                               * 如果没有自行处理点击事件,则返回 false,SDK 内部将按默认逻辑响应点击事件。
                               */  
                              fun onDocLinkClicked(
                                 context: Context,
                                 appInfo: FinAppInfo,
                                 docName: String?,
                                 docUrl: String?
                              ): Boolean
                            }
                            

                            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)
                                }
                              
                                override fun onDocLinkClicked(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    docName: String?,
                                    docUrl: String?
                                ): Boolean {
                                    context.toast("文档${docName}${docUrl}被点击了")
                                    return true
                                }
                            }
                            

                            customizeAuthInfo 方法参数说明:

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

                            onDocLinkClicked 方法参数说明:

                            参数名 作用
                            context 上下文对象
                            appInfo 小程序的相关信息
                            docName 文档名称
                            docUrl 文档链接

                            注意

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

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

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

                            # 18. IScopeSettingHandler

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用🚫

                            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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

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

                            interface IFinWatermarkFactory {
                                
                                /**
                                 * @param context Context对象
                                 * @param layoutParams View对象的LayoutParams
                                 * @param finAppInfo 小程序信息
                                 * @param extra 水印的额外参数,可能为空
                                 */
                                fun createWatermarkView(
                                    context: Context,
                                    layoutParams: ViewGroup.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: ViewGroup.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

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            宿主工程实现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()
                            

                            # 23. IPrivacyHandler

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            2.43.9版本开始,支持自定义隐私协议信息。

                            interface IPrivacyHandler {
                            
                                /**
                                 * 获取隐私协议信息
                                 * @param context [Context]实例
                                 * @param appInfo 小程序信息
                                 * @param callback 获取隐私协议信息接口回调
                                 */
                                fun getPrivacyInfo(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    callback: GetPrivacyInfoCallback
                                )
                              
                                /**
                                 * 当文档链接被点击时
                                 * @param context [Context]实例
                                 * @param appInfo 小程序信息
                                 * @param docName 文档名称
                                 * @param docUrl 文档链接
                                 * @return 是否有自行处理点击事件。如果有自行处理点击事件,则返回 true,SDK 内部将不再处理点击事件。
                                 * 如果没有自行处理点击事件,则返回 false,SDK 内部将按默认逻辑响应点击事件。
                                 */
                                fun onDocLinkClicked(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    docName: String?,
                                    docUrl: String?
                                ): Boolean
                            }
                            

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

                            示例如下:

                            class PrivacyHandler : IPrivacyHandler {
                                override fun getPrivacyInfo(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    callback: IPrivacyHandler.GetPrivacyInfoCallback
                                ) {
                                    callback.onSuccess(IPrivacyHandler.PrivacyInfo(
                                        "隐私协议文档名称",
                                        "隐私协议文档链接")
                                    )
                                }
                              
                                override fun onDocLinkClicked(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    docName: String?,
                                    docUrl: String?
                                ): Boolean {
                                    context.toast("文档${docName}${docUrl}被点击了")
                                    return true
                                }
                            }
                            

                            getPrivacyInfo 参数说明:

                            参数名 作用
                            context 上下文对象
                            appInfo 小程序的相关信息
                            callback 获取隐私协议信息回调

                            onDocLinkClicked 参数说明:

                            参数名 作用
                            context 上下文对象
                            appInfo 小程序的相关信息
                            docName 文档名称
                            docUrl 文档链接

                            注意

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

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

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

                            # 24. AppletWebViewLoadHandler

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            2.45.11版本开始,支持宿主应用控制webview是否可加载H5链接

                                interface UrlCanLoadCallback {
                                    /**
                                     * 是否可加载该Url的回调。
                                     */
                                    fun onResult(canLoad: Boolean)
                                }
                            
                                open fun webviewCanLoadUrl(context: Context, appInfo: FinAppInfo, url: String, callback: UrlCanLoadCallback) {
                                    callback.onResult(true)
                                }
                            
                            

                            示例代码

                            1. 宿主应用继承自AppletWebViewLoadHandler,并重写webviewCanLoadUrl(context: Context, appInfo: FinAppInfo, url: String, callback: UrlCanLoadCallback)
                            class MyAppletWebViewLoadHander: AppletWebViewLoadHandler() {
                            
                                override fun webviewCanLoadUrl(
                                    context: Context,
                                    appInfo: FinAppInfo,
                                    url: String,
                                    callback: UrlCanLoadCallback
                                ) {
                                    Log.d("Test-webviewCanLoadUrl", url)
                                    AlertDialog.Builder(context)
                                        .setTitle("URL加载确认")
                                        .setMessage("是否允许加载 $url ?")
                                        .setPositiveButton("允许") { _, _ -> callback.onResult(true) }
                                        .setNegativeButton("拒绝") { _, _ -> callback.onResult(false) }
                                        .show()
                                }
                            }
                            
                            

                            2)初始化SDK时,设置实现代理的类

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

                            # 25. AppletConfigHandler

                            支持的app类型

                            小程序✅ 小游戏🚫 H5应用🚫

                            自 2.46.13 版本开始支持(从IAppletHandler拆分出来)。小程序使用多进程时,需要在小程序进程设置;小程序使用单进程时,需要在主进程设置。

                            open class AppletConfigHandler {
                            
                                open fun getJSSDKConfig(json: JSONObject, callback: IAppletHandler.IAppletCallback) {
                            
                                }
                            
                                /**
                                 * 获取小程序web-view组件加载使用的自定义Cookie
                                 */
                                open fun getWebViewCookie(appId: String): Map<String, String>? {
                                    return null
                                }
                            }
                            
                            

                            示例代码:

                            FinAppProcessClient.appletConfigHandler = object : AppletConfigHandler() {
                                override fun getJSSDKConfig(json: JSONObject, callback: IAppletHandler.IAppletCallback) {
                            
                                }
                            
                                override fun getWebViewCookie(appId: String): Map<String, String>? {
                                    val cookie = HashMap<String, String>()
                                    cookie["a"] = "a\n"
                                    cookie["b"] = "b\r"
                                    cookie["c"] = "c\u0000"
                                    return cookie
                                }
                            }
                            

                            # 26. AppletGrayVersionHandler

                            支持的app类型

                            小程序✅ 小游戏✅ H5应用✅

                            自 2.46.13 版本开始支持(从IAppletHandler拆分出来),在主进程中设置。

                            open class AppletGrayVersionHandler {
                            
                                /**
                                 * 获取灰度发布配置参数
                                 *
                                 * @param appId 小程序ID
                                 * @return 灰度发布配置参数
                                 */
                                open fun getGrayAppletVersionConfigs(appId: String): List<GrayAppletVersionConfig>? {
                                    return null
                                }
                            
                            }
                            

                            示例代码:

                            FinAppClient.grayVersionHandler = object : AppletGrayVersionHandler() {
                                override fun getGrayAppletVersionConfigs(appId: String): List<GrayAppletVersionConfig>? {
                                    return null
                                }
                            }
                            
                            © FinClip with ❤ , Since 2017