小程序的某些特殊 API,如定位、相机、相册等,通常会提示用户授权,待用户允许后方可执行 API。
小程序容器允许针对 API 调用进行如下扩展:
自定义文案提示,接入可控制文案以及展示样式。
允许接入方读写权限配置。
此扩展配置仅在后台已开启 小程序权限控制 时才可用。
权限配置
对于需要用户授权使用的 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() {
}
}
当 action 为 chooseImage、chooseVideo 时,接入方配置的 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;
}
}
自定义展示
自定义展示授权信息并允许用户进行操作确认。使用步骤如下:
设置自定义展示。
Mriver.setProxy(LocalPermissionDialogProxy.class, new CustomAuthDialogProxy());
用户接受或者拒绝调用,需要调用 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)));
}
}
});
}
}