Android Mini Program API permission extension configuration

更新时间:
复制 MD 格式

Some miniapp APIs, such as those for location, camera, and albums, require user authorization. The API call can only be executed after the user grants permission.

The miniapp container lets you extend API calls in the following ways:

  1. Customize the prompt text. The integrator can control the text and display style.

  2. Allow the integrator to read and write permission configurations.

Note

This extension configuration is active only when miniapp access control is enabled in the background.

Permission configuration

You can configure a permission key for each API that requires user authorization. Multiple APIs can be mapped to the same key. For example, choosing an image and scanning a code can both be mapped to a camera key.

The miniapp includes default keys and their corresponding APIs, as shown in the following table:

Permission

key

API

Camera

camera

scan, chooseImage, chooseVideo

Album

album

saveImage, saveVideosToPhotosAlbum, shareTokenImageSilent

Location

location

getLocation, getCurrentLocation

The container reads the following permission configuration class, which is passed in by the integrator, to handle API call permissions:

 public static class PermissionConfig {
    public String action;   // API name
    public String key;      // Permission key
    public String desc;     // Text displayed for the API call. You can add the %s placeholder to the text. The container automatically fills in the miniapp name.

    public PermissionConfig() {
    }
}
Note

When action is chooseImage or chooseVideo, the key configured by the integrator does not take effect. The container handles these two APIs with special logic, but the text is still configurable.

Load configurations

To load permission configurations, you can use the TinyAppPermissionExternProvider interface provided by the container. The interface class is as follows:

package com.alipay.mobile.nebula.provider;

import android.content.Context;

import java.util.List;

public abstract class TinyAppPermissionExternProvider {

    public interface PermissionCheckCallback {
        void accept();

        void deny();
    }

    public abstract List<PermissionConfig> loadPermissionCheckConfig();

    public abstract void showPermissionDialog(Context context, String appId, PermissionConfig config, PermissionCheckCallback callback);

    public abstract boolean shouldHandlePermissionDialog();
}

The loadPermissionCheckConfig method loads permission configurations into the container.

Customize the display

You can customize the display of authorization information and allow users to confirm the operation.

  1. First, ensure that the shouldHandlePermissionDialog method returns true.

  2. Then, the container calls the showPermissionDialog method. The integrator can then display a custom style.

  3. When the user accepts or denies the call, you must call the corresponding method of the PermissionCheckCallback interface.

The following code provides an example:

package com.mpaas.demo.nebula;

import android.content.Context;

import com.alipay.mobile.antui.dialog.AUNoticeDialog;
import com.alipay.mobile.nebula.provider.TinyAppPermissionExternProvider;

import java.util.ArrayList;
import java.util.List;

public class TinyExternalPermissionCheckProvider extends TinyAppPermissionExternProvider {

    private PermissionConfig create(String action, String key, String desc) {
        PermissionConfig config = new PermissionConfig();
        config.action = action;
        config.key = key;
        config.desc = desc;
        return config;
    }

    private List<PermissionConfig> permissionConfigs = new ArrayList<>();

    public TinyExternalPermissionCheckProvider() {
        permissionConfigs.add(create("saveFile", "file", "%s wants to use your file storage"));
        permissionConfigs.add(create("getFileInfo", "file", "%s wants to use your file storage"));
    }

    @Override
    public List<PermissionConfig> loadPermissionCheckConfig() {
        return permissionConfigs;
    }

    @Override
    public void showPermissionDialog(Context context, String action, PermissionConfig permissionConfig, final PermissionCheckCallback permissionCheckCallback) {
        AUNoticeDialog dialog = new AUNoticeDialog(context, "Authorization Reminder", permissionConfig.desc, "Accept", "Deny");
        dialog.setPositiveListener(new AUNoticeDialog.OnClickPositiveListener() {
            @Override
            public void onClick() {
                permissionCheckCallback.accept();
            }
        });
        dialog.setNegativeListener(new AUNoticeDialog.OnClickNegativeListener() {
            @Override
            public void onClick() {
                permissionCheckCallback.deny();
            }
        });
        dialog.show();
    }

    @Override
    public boolean shouldHandlePermissionDialog() {
        return true;
    }
}

Read and write configurations

To read configurations, you can call the following method:

MPTinyHelper.getInstance().getMiniProgramSetting(appId)
Note

  • Miniapp configurations are stored based on two dimensions: application and user. Therefore, you must ensure that the application has called the MPLogger.setUserId method.

  • If an API has never been called, the authorization status of the key for that API cannot be retrieved.

To write configurations, you can call the following method:

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

The following code provides an example:

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 = MPTinyHelper.getInstance().getMiniProgramSetting(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) {
                            MPTinyHelper.getInstance().updateMiniProgramSetting(appId, key, isChecked);
                        }
                    });
                    mScrollView.addView(item, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, H5Utils.dip2px(PermissionDisplayActivity.this, 48)));
                }
            }
        });
    }
}