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:
Customize the prompt text. The integrator can control the text and display style.
Allow the integrator to read and write permission configurations.
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() {
}
}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.
First, ensure that the
shouldHandlePermissionDialogmethod returnstrue.Then, the container calls the
showPermissionDialogmethod. The integrator can then display a custom style.When the user accepts or denies the call, you must call the corresponding method of the
PermissionCheckCallbackinterface.
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)Miniapp configurations are stored based on two dimensions: application and user. Therefore, you must ensure that the application has called the
MPLogger.setUserIdmethod.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)));
}
}
});
}
}