全部产品

Android 小程序 API 权限扩展配置

更新时间:2020-09-11 14:52:36

小程序的某些特殊 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 调用权限:

  1. public static class PermissionConfig {
  2. public String action; // API 名称
  3. public String key; // 权限 key
  4. public String desc; // API 调用展示的文案,文案中可加入 %s 占位符,容器会自动填入小程序的名称
  5. public PermissionConfig() {
  6. }
  7. }
说明:需注意有外情况,当 actionchooseImagechooseVideo 时,接入方配置的 key 是不生效的,容器有特殊逻辑处理这两个 API,但文案依然是可配置的。

加载配置

加载权限配置,需使用容器提供的 TinyAppPermissionExternProvider 接口。接口类如下:

  1. package com.alipay.mobile.nebula.provider;
  2. import android.content.Context;
  3. import java.util.List;
  4. public abstract class TinyAppPermissionExternProvider {
  5. public interface PermissionCheckCallback {
  6. void accept();
  7. void deny();
  8. }
  9. public abstract List<PermissionConfig> loadPermissionCheckConfig();
  10. public abstract void showPermissionDialog(Context context, String appId, PermissionConfig config, PermissionCheckCallback callback);
  11. public abstract boolean shouldHandlePermissionDialog();
  12. }

loadPermissionCheckConfig 方法负责将权限配置加载至容器。

自定义展示

自定义展示授权信息并允许用户进行操作确认。

  1. 首先需使 shouldHandlePermissionDialog 方法返回 true
  2. 随后容器会调用 showPermissionDialog 方法,接入方可在此处展示自定义样式。
  3. 当用户接受或者拒绝调用,需要调用 PermissionCheckCallback 接口的相应方法。

代码示例如下:

  1. package com.mpaas.demo.nebula;
  2. import android.content.Context;
  3. import com.alipay.mobile.antui.dialog.AUNoticeDialog;
  4. import com.alipay.mobile.nebula.provider.TinyAppPermissionExternProvider;
  5. import java.util.ArrayList;
  6. import java.util.List;
  7. public class TinyExternalPermissionCheckProvider extends TinyAppPermissionExternProvider {
  8. private PermissionConfig create(String action, String key, String desc) {
  9. PermissionConfig config = new PermissionConfig();
  10. config.action = action;
  11. config.key = key;
  12. config.desc = desc;
  13. return config;
  14. }
  15. private List<PermissionConfig> permissionConfigs = new ArrayList<>();
  16. public TinyExternalPermissionCheckProvider() {
  17. permissionConfigs.add(create("saveFile", "file", "%s想使用您的文件存储"));
  18. permissionConfigs.add(create("getFileInfo", "file", "%s想使用您的文件存储"));
  19. }
  20. @Override
  21. public List<PermissionConfig> loadPermissionCheckConfig() {
  22. return permissionConfigs;
  23. }
  24. @Override
  25. public void showPermissionDialog(Context context, String action, PermissionConfig permissionConfig, final PermissionCheckCallback permissionCheckCallback) {
  26. AUNoticeDialog dialog = new AUNoticeDialog(context, "授权提醒", permissionConfig.desc, "接受", "拒绝");
  27. dialog.setPositiveListener(new AUNoticeDialog.OnClickPositiveListener() {
  28. @Override
  29. public void onClick() {
  30. permissionCheckCallback.accept();
  31. }
  32. });
  33. dialog.setNegativeListener(new AUNoticeDialog.OnClickNegativeListener() {
  34. @Override
  35. public void onClick() {
  36. permissionCheckCallback.deny();
  37. }
  38. });
  39. dialog.show();
  40. }
  41. @Override
  42. public boolean shouldHandlePermissionDialog() {
  43. return true;
  44. }
  45. }

读写配置

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

  1. MPTinyHelper.getInstance().getMiniProgramSetting(appId)
说明
  • 小程序配置是以应用和用户两个维度存储的,因此要确保应用已经调用 MPLogger.setUserId 方法。
  • 当API从未被调用的情况下,是获取不到该API对应的key值的授权状态的。

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

  1. MPTinyHelper.getInstance().updateMiniProgramSetting(appId, key, isAllowed);

代码示例如下:

  1. package com.mpaas.demo.nebula;
  2. import android.os.Bundle;
  3. import android.view.View;
  4. import android.view.ViewGroup;
  5. import android.widget.CompoundButton;
  6. import com.alipay.mobile.antui.basic.AUSearchBar;
  7. import com.alipay.mobile.antui.tablelist.AUSwitchListItem;
  8. import com.alipay.mobile.framework.app.ui.BaseFragmentActivity;
  9. import com.alipay.mobile.nebula.util.H5Utils;
  10. import com.mpaas.nebula.adapter.api.MPTinyHelper;
  11. import java.util.Map;
  12. public class PermissionDisplayActivity extends BaseFragmentActivity {
  13. private ViewGroup mScrollView;
  14. private AUSearchBar mSearchInputBox;
  15. private Map<String, Boolean> permissions;
  16. @Override
  17. protected void onCreate(Bundle savedInstanceState) {
  18. super.onCreate(savedInstanceState);
  19. setContentView(R.layout.activity_permission);
  20. mScrollView = (ViewGroup) findViewById(R.id.scrollview);
  21. mSearchInputBox = (AUSearchBar) findViewById(R.id.search);
  22. mSearchInputBox.getSearchButton().setOnClickListener(new View.OnClickListener() {
  23. @Override
  24. public void onClick(View v) {
  25. mScrollView.removeAllViews();
  26. final String appId = mSearchInputBox.getSearchEditView().getText().toString();
  27. permissions = MPTinyHelper.getInstance().getMiniProgramSetting(appId);
  28. for (Map.Entry<String, Boolean> entry : permissions.entrySet()) {
  29. AUSwitchListItem item = new AUSwitchListItem(PermissionDisplayActivity.this);
  30. final String key = entry.getKey();
  31. item.setLeftText(key);
  32. item.getCompoundSwitch().setChecked(entry.getValue());
  33. item.getCompoundSwitch().setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
  34. @Override
  35. public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
  36. MPTinyHelper.getInstance().updateMiniProgramSetting(appId, key, isChecked);
  37. }
  38. });
  39. mScrollView.addView(item, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, H5Utils.dip2px(PermissionDisplayActivity.this, 48)));
  40. }
  41. }
  42. });
  43. }
  44. }