小程序权限

小程序的某些特殊 API,如定位、相机、相册等,通常会提示用户授权,待用户允许后方可执行 API。

小程序容器允许针对 API 调用进行如下扩展:

  1. 自定义文案提示,接入可控制文案以及展示样式。

  2. 允许接入方读写权限配置。

说明

此扩展配置仅在后台已开启 小程序权限控制 时才可用。

权限配置

对于需要用户授权使用的 API,都必须配置一个权限 key。多个 API 可对应同一个 key,比如选择图片和扫码可对应一个相机的 key。

小程序已有默认配置的 key 以及对应的 API,详见下表:

权限

key

API

相机

camera

scan, chooseImage, chooseVideo

相册

album

saveImage, saveVideosToPhotosAlbum, shareTokenImageSilent

位置

location

getLocation, getCurrentLocation

麦克风

audioRecord

startAudioRecord, stopAudioRecord, cancelAudioRecord

容器读取接入方传入的如下权限配置类来处理 API 调用权限:

public static class Config {
    public String action;   // API 名称
    public String scope;      // 权限 key
    public String desc;     // API 调用展示的文案
    public Config() {
    }
}
说明

actionchooseImagechooseVideo 时,接入方配置的 key 是不生效的。容器有特殊逻辑处理这两个 API,但文案依然可配置的。

加载配置

加载权限配置,需使用容器提供的 ApiPermissionConfigProxy 接口。

接口类如下:

package com.mpaas.mriver.base.proxy;

import com.alibaba.ariver.kernel.common.Proxiable;
import com.mpaas.mriver.base.permission.Config;
import java.util.List;

public interface ApiPermissionConfigProxy {
    List<Config> getConfigurationList();
}

调用方式如下:

// 配置自定义
Mriver.setProxy(ApiPermissionConfigProxy.class, new CustomApiPermissionConfigProxy());

代码示例如下:

public class CustomApiPermissionConfigProxy implements ApiPermissionConfigProxy {
    @Override
    public List<Config> getConfigurationList() {
        List<Config> permissionList = new ArrayList<>();
        permissionList.add(new Config("saveFile", "file", "使用您的文件存储"));
        permissionList.add(new Config("getFileInfo", "file", "使用您的文件存储哟"));
        return permissionList;
    }
}

自定义展示

自定义展示授权信息并允许用户进行操作确认。使用步骤如下:

  1. 设置自定义展示。

    Mriver.setProxy(LocalPermissionDialogProxy.class, new CustomAuthDialogProxy());
  2. 用户接受或者拒绝调用,需要调用 PermissionPermitListener 接口的相应方法。代码示例如下:

    public class CustomAuthDialogProxy implements LocalPermissionDialogProxy {
        @Override
        public LocalPermissionDialog create(Context context) {
            return new CustomPermissionDialog(context);
        }
    
        public static class CustomPermissionDialog implements LocalPermissionDialog {
            private AUNoticeDialog mDialog;
    
            private final Context mContext;
    
            private PermissionPermitListener mPermissionPermitListener;
    
            public CustomPermissionDialog(Context context) {
                mContext = context;
            }
    
            @Override
            public void setDialogContent(String content, String title, String icon) {
                mDialog = new AUNoticeDialog(mContext, title, content,
                    "接受",
                    "拒绝");
                mDialog.setPositiveListener(new AUNoticeDialog.OnClickPositiveListener() {
                    @Override
                    public void onClick() {
                        if (mPermissionPermitListener != null) {
                            mPermissionPermitListener.onSuccess();
                        }
                    }
                });
                mDialog.setNegativeListener(new AUNoticeDialog.OnClickNegativeListener() {
                    @Override
                    public void onClick() {
                        if (mPermissionPermitListener != null) {
                            mPermissionPermitListener.onFailed(-1, "", true);
                        }
                    }
                });
            }
    
            @Override
            public void setPermissionPermitListener(PermissionPermitListener permissionPermitListener) {
                mPermissionPermitListener = permissionPermitListener;
            }
    
            @Override
            public void show() {
                if (mDialog != null && mContext instanceof Activity) {
                    if (!((Activity) mContext).isFinishing()) {
                        mDialog.show();
                    }
                }
            }
        }
    

读写配置

读取配置请调用如下方法:

RVProxy.get(ApiPermissionConfigManagerProxy.class).getAllPermissionStates(appId);
说明

  • 小程序配置是以应用和用户两个维度存储的,因此要确保应用已经调用 MPLogger.setUserId 方法。

  • API 未被调用时,该 API 对应的 key 值授权状态是获取不到的。

写入配置请调用如下方法:

RVProxy.get(ApiPermissionConfigManagerProxy.class).setPermissionState(appId, key, true);

代码示例如下:

package com.mpaas.demo.nebula;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CompoundButton;
import com.alipay.mobile.antui.basic.AUSearchBar;
import com.alipay.mobile.antui.tablelist.AUSwitchListItem;
import com.alipay.mobile.framework.app.ui.BaseFragmentActivity;
import com.alipay.mobile.nebula.util.H5Utils;
import com.mpaas.nebula.adapter.api.MPTinyHelper;
import java.util.Map;
public class PermissionDisplayActivity extends BaseFragmentActivity {
    private ViewGroup mScrollView;
    private AUSearchBar mSearchInputBox;
    private Map<String, Boolean> permissions;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_permission);
        mScrollView = (ViewGroup) findViewById(R.id.scrollview);
        mSearchInputBox = (AUSearchBar) findViewById(R.id.search);
        mSearchInputBox.getSearchButton().setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mScrollView.removeAllViews();
                final String appId = mSearchInputBox.getSearchEditView().getText().toString();
                permissions = RVProxy.get(ApiPermissionConfigManagerProxy.class).getAllPermissionStates(appId);
                for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
                    AUSwitchListItem item = new AUSwitchListItem(PermissionDisplayActivity.this);
                    final String key = entry.getKey();
                    item.setLeftText(key);
                    item.getCompoundSwitch().setChecked(entry.getValue());
                    item.getCompoundSwitch().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
                        @Override
                        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                            RVProxy.get(ApiPermissionConfigManagerProxy.class).setPermissionState(appId, key, isChecked);
                        }
                    });
                    mScrollView.addView(item, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, H5Utils.dip2px(PermissionDisplayActivity.this, 48)));
                }
            }
        });
    }
}