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

# 小程序权限

小程序权限主要介绍跟小程序Scope权限相关的方法、代理类等。

# 1. 权限请求前置处理

2.40.3版本开始,支持宿主app对小程序内的权限请求做前置处理。

宿主工程实现IAuthRequestHandler接口,参考:「IAuthRequestHandler」

# 2. 权限请求结果处理

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

宿主工程实现IAuthResultHandler接口,参考:「IAuthResultHandler」

# 3. 自定义隐私授权弹窗详情说明中的标题、文案

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

宿主工程实现IAuthInfoHandler接口,参考:「IAuthInfoHandler」

# 4. 自定义小程序权限设置页

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

# 4.1 实现

宿主工程实现IScopeSettingHandler接口,参考:「IScopeSettingHandler」

# 4.2 获取小程序目前包含的小程序权限列表

使用FinAppClientFinAppProcessClientgetScopeList方法,具体根据执行时的进程情况而定。

示例如下:

if (FinAppClient.isFinAppProcess(context)) {
    // 小程序进程
    val scopeList = FinAppProcessClient.getScopeList(context, appId)
} else {
    // 主进程
    val scopeList = FinAppClient.getScopeList(context, appId)
}

其中结果集合内的ScopeBean具有以下方法,

获取scope值:

scope.scope

获取scope对应的标题:

scope.getScopeName(context)

获取scope对应的描述:

 scope.getDesc(context)

获取scope的状态:

scope.isAllow()
// 或
scope.isDisallow()
// 或
scope.isAllowWhenUsing() // 主要用于定位权限的【使用小程序时允许]

# 4.3 修改小程序的小程序权限状态

使用FinAppClientFinAppProcessClientupdateScopeStatus方法,具体根据执行时的进程情况而定。

示例如下:

if (FinAppClient.isFinAppProcess(context)) {
    // 小程序进程
    FinAppProcessClient.updateScopeStatus(
        context,
        appId,
        scope,
        AppletScopeBean.Status.ALLOW
    )
} else {
    // 主进程
    FinAppClient.updateScopeStatus(
        context,
        appId,
        scope,
        AppletScopeBean.Status.ALLOW
    )
}

支持的状态:

状态值 说明
UNSET 未设置
DISALLOW 拒绝
ALLOW_WHEN_USING 使用小程序时允许,主要用于定位权限
ALLOW 允许

# 5. 自定义Scope权限申请弹窗部分内容

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

宿主工程实现ScopeDialogCustomHandler接口,参考:「ScopeDialogCustomHandler」

# 6. 打开小程序授权管理页

该方法将会打开一个页面展示所有已使用过的小程序列表以及涉及的权限。

# 6.1 普通打开

示例如下:

FinAppClient.appletApiManager.openPrivacyManage(context)

# 6.2 打开时自定义导航栏

示例如下:

val config = AppletScopeManagerConfig()
config.backImageRes = R.drawable.back
config.isCenterTitle = false
FinAppClient.appletApiManager.openPrivacyManage(context, config)

配置项说明:

变量名 说明
backImageRes 返回按钮的图片资源文件。若要适配深色模式,需自行准备深色模式的图片资源文件,放在对应的night目录下。
isCenterTitle 是否居中显示标题。true居中,false居左,null则以sdk初始化时的全局配置为准。

# 7. 获取隐私授权相关信息

该方法支持宿主app获取小程序的隐私授权相关配置信息。

示例如下:

if (FinAppClient.isFinAppProcess(context)) {
    // 小程序进程
    FinAppProcessClient.appletProcessApiManager.getPrivacyInfo(
        context,
        object : FinSimpleCallback<PrivacyInfo>() {
            override fun onSuccess(result: PrivacyInfo) {
                // 获取隐私授权信息成功的回调
            }
  
            override fun onError(code: Int, error: String?) {
                // 获取隐私授权相关信息失败的回调
            }
        })
} else {
    // 主进程
    FinAppClient.appletApiManager.getPrivacyInfo(
        this,
        apiServer,
        appId,
        object : FinSimpleCallback<PrivacyInfo>() {
            override fun onSuccess(result: PrivacyInfo) {
                // 获取隐私授权信息成功的回调
            }

            override fun onError(code: Int, error: String?) {
                // 获取隐私授权相关信息失败的回调
            }
        })
}

PrivacyInfo相关说明:

变量名 说明
defaultPrivacyName 默认隐私协议的协议名
defaultPrivacyContent 默认隐私协议的内容,为html代码
customPrivacyName 自定义隐私协议的协议名
customPrivacyUrl 自定义隐私协议的url

# 8. 自定义小程序(Scope)权限

自定义Scope权限,一般与自定义Api关联实现。

自定义Api类继承抽象类ScopeApi,并与其它普通的自定义Api一样,实现对应抽象方法:

public class CustomScopeApi extends ScopeApi {

    public CustomScopeApi(@NonNull Context context) {
        super(context);
    }

    @Override
    public String[] apis() {
        // 在此定义该类需要接管的自定义api方法
        return new String[]{"customScopeApi"};
    }

    @Override
    public void invoke(String event, JSONObject param, ICallback callback) {
        if (event.equals("customScopeApi")) {
            customScopeApi(callback);
        }
    }
}

创建自定义权限、创建自定义View,展示弹窗:

private void customScopeApi(ICallback callback) {
    View view = createCustomView(callback);
    // 展示弹窗
    checkScope(view);
}

private View createCustomView(ICallback callback) {
    // 自定义身份证权限
    AppletScopeBean idCardScopeBean = new AppletScopeBean(
            "scope.idCard",
            "身份证",
            "获取身份证信息",
            "获取您的身份证信息用于XXXXXX"
    );
    // 自定义手机号权限,此处 scope.getPhoneNumber 与内置Scope权限冲突,将会被忽略,仅作示例
    AppletScopeBean phoneNumScopeBean = new AppletScopeBean(
            "scope.getPhoneNumber",
            "手机号",
            "获取手机号信息",
            "获取您的手机号信息用于XXXXXX"
    );
    // 自定义数字钱包权限
    AppletScopeBean walletScopeBean = new AppletScopeBean(
            "scope.wallet",
            "数字钱包",
            "获取数字钱包信息信息",
            "获取您的数字钱包信息用于XXXXXX"
    );
    // 创建自定义View,并处理交互事件
    View view = LayoutInflater.from(getContext()).inflate(R.layout.layout_custom_scope, null);
    view.findViewById(R.id.btnConfirm).setOnClickListener(v -> {
        // 设置身份证权限状态
        AppletScopeBean.Status idCardStatus = view.findViewById(R.id.cbIdCard).isChecked()
                ? AppletScopeBean.Status.ALLOW
                : AppletScopeBean.Status.DISALLOW;
        idCardScopeBean.setStatus(idCardStatus);
        // 设置手机号权限状态
        AppletScopeBean.Status phoneNumStatus = view.findViewById(R.id.cbPhoneNum).isChecked()
                ? AppletScopeBean.Status.ALLOW
                : AppletScopeBean.Status.DISALLOW;
        phoneNumScopeBean.setStatus(phoneNumStatus);
        // 设置数字钱包权限状态
        AppletScopeBean.Status walletStatus = view.findViewById(R.id.cbWallet).isChecked()
                ? AppletScopeBean.Status.ALLOW
                : AppletScopeBean.Status.DISALLOW;
        walletScopeBean.setStatus(walletStatus);
        // 关闭弹窗并更新权限状态
        dismiss(Arrays.asList(idCardScopeBean, phoneNumScopeBean, walletScopeBean));
        // 执行在申请权限之后您的其它业务逻辑,如回调结果等
        callback.onSuccess(new JSONObject());
    });
    return view;
}

上述代码示例中的checkScope方法即为唤起申请Scope权限的弹窗,其中传入的view参数为自定义布局。

开发者需要自行处理自定义view中的交互,并在申请完成时调用dismiss方法将【已设置状态】的自定义Scope权限对象传入,并关闭弹窗。

以下为R.layout.layout_custom_scope布局文件代码,配合上述示例以作对照:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <CheckBox
        android:id="@+id/cbIdCard"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="身份证" />

    <CheckBox
        android:id="@+id/cbPhoneNum"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="手机号(跟内置权限冲突,将会被忽略)" />

    <CheckBox
        android:id="@+id/cbWallet"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="数字钱包" />

    <Button
        android:id="@+id/btnConfirm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        android:layout_marginBottom="16dp"
        android:background="@android:color/holo_green_light"
        android:text="确认" />

</LinearLayout>

注意

  • 上文中的内置Scope权限列表如下:

    • scope.userInfo
    • scope.userLocation
    • scope.userLocationBackground
    • scope.record
    • scope.writePhotosAlbum
    • scope.camera
    • scope.bluetooth
    • scope.addPhoneContact
    • scope.getPhoneNumber
    • scope.addPhoneCalendar
  • 注册Api实现类(即上述示例的customScopeApi)时要将其注册到对应的进程中。

    即如果要使用单进程模式,则将Api注册到主进程中;

    如果要使用多进程模式,则需要将Api注册到子进程中;

    如果可能同时使用单进程和多进程模式,则主进程和小程序进程都要进行Api注册。

# 9. 监听默认设置页面内小程序状态的变化

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

宿主工程实现IScopeStatusChangeHandler接口,参考:「IScopeStatusChangeHandler」

© FinClip with ❤ , Since 2017