The HTML5 container component provides extension features such as retrieving Activity results, customizing error pages, enabling the immersive status bar, and adding third-party JavaScriptInterface objects.
Get the result returned by an Activity in an H5Plugin
Scenarios such as face scanning and recognition require starting a new Activity to obtain its result. In these cases, a JSAPI cannot obtain the result by overriding `H5Activity`. To obtain the result from an Activity in an HTML5 container, follow these steps:
-
In your custom H5Plugin, register the
OnH5ActivityResultcallback. The following code provides an example:H5ActivityResultManager.getInstance().put(onH5ActivityResult);Note-
The
putmethod does not check for duplicate registrations. You must prevent duplicate registrations. -
After use, call the
removemethod to remove the callback. You can remove the callback in theonReleasemethod of the H5Plugin. The following code provides an example:
H5ActivityResultManager.getInstance().remove(onH5ActivityResult); -
-
Start the destination Activity using
startActivityForResult. You can start it in thehandleEventmethod of a customH5Plugin. The following code provides an example:public boolean handleEvent(H5Event event, H5BridgeContext context) { if ("CustomJSAPI".equals(event.getAction())) { if (event.getActivity()!=null){ Intent intent = new Intent(event.getActivity(), yourDestinationActivity.class); event.getActivity().startActivityForResult(intent,requestCode,bundle); } return true; } return false; }NoteA callback is performed only for the result of `H5Activity`.
-
In the
OnH5ActivityResultcallback method, pass the result to the frontend through theH5BridgeContextobject.public interface OnH5ActivityResult { void onGetResult(int requestCode, int resultCode, Intent intent); }
Customize HTML5 error pages
To customize HTML5 error pages, follow these steps:
-
Create a custom error page in HTML format.
<!doctype html> <html lang="en"> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width,maximum-scale=1.0,minimum-scale=1.0,user-scalable=no" /> <meta name="format-detection" content="telephone=no" /> <title>Custom Error</title> </head> <body> <p>This is a custom error page</p> </body> </html> -
Implement
H5ErrorPageView. InAPWebView, set the error page that you created.public class H5ErrorPageViewImpl implements H5ErrorPageView { @Override public boolean enableShowErrorPage() { // true indicates that the custom error page is enabled. return true; } @Override public void errorPageCallback(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg) { // Get the HTML of the error page. In this demo, it is placed in the raw directory, but you can place it elsewhere. String html = H5ResourceManager.readRawFromResource(R.raw.custom_error, LauncherApplicationAgent.getInstance().getApplicationContext().getResources()); // Set the error page for the webview. view.loadDataWithBaseURL(errorUrl, html, "text/html", "utf-8", errorUrl); } } -
Register
H5ErrorPageView. Before you open the HTML5 container, register the customH5ErrorPageViewwith the container.H5Utils.setProvider(H5ErrorPageView.class.getName(),new H5ErrorPageViewImpl());
Baselines 10.1.68.7 and later support the new MPH5ErrorPageView. The method name and usage are the same as H5ErrorPageView, but the method parameters are extended.
/**
* Interface for custom network error pages
*/
public interface MPH5ErrorPageView {
/**
* @param h5Page The page object
* @param view The webview object
* @param errorUrl The error URL
* @param statusCode The error code
* @param errorMsg The error description
* @param subErrorMsg The sub error description
* @param extInfo Extended information. Check if it is empty.
* @param extObj The extension class. Check if it is empty.
* @return true indicates that the custom page needs to be displayed, and the errorPageCallback method below will be called.
*/
boolean enableShowErrorPage(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg, Bundle extInfo, Object extObj);
/**
* @param h5Page The page object
* @param view The webview object
* @param errorUrl The error URL
* @param statusCode The error code
* @param errorMsg The error description
* @param subErrorMsg The sub error description
* @param extInfo Extended information. Check if it is empty.
* @param extObj The extension class. Check if it is empty.
*/
void errorPageCallback(H5Page h5Page, APWebView view, String errorUrl, int statusCode, String errorMsg, String subErrorMsg, Bundle extInfo, Object extObj);
}
Enable the immersive status bar
To enable the immersive status bar, follow these steps:
-
This feature is supported only in baseline versions 10.1.60 and later.
-
This method sets the status bar color for all HTML5 pages opened by the container. For more complex status bar color requirements, implement a custom title bar for the HTML5 container.
-
You can set the status bar color in the
openTranslucentStatusBarSupportmethod of the container title bar interface or elsewhere.
-
Enable
TSBSin the HTML5 container configuration. -
If you use the built-in title bar, implement the
H5TransStatusBarColorProviderinterface. Then, use theH5Utils.setProvidermethod to set the instance for the HTML5 container. The following code provides an example:package com.mpaas.demo.nebula; import android.graphics.Color; import com.alipay.mobile.nebula.provider.H5TransStatusBarColorProvider; public class H5TransStatusBarColorProviderImpl implements H5TransStatusBarColorProvider { @Override public int getColor() { return Color.argb(70, 255, 255, 255); } }
Add a third-party JavaScriptInterface
When integrating third-party pages, you may need to use JavaScriptInterface. To add a third-party JavaScriptInterface, follow these steps:
-
Implement a plugin to intercept third-party page loading events.
-
Obtain the WebView and inject the JavaScript object.
The following code provides an example:
package com.mpaas.demo.nebula;
import android.text.TextUtils;
import com.alibaba.fastjson.JSONObject;
import com.alipay.mobile.h5container.api.H5BridgeContext;
import com.alipay.mobile.h5container.api.H5Event;
import com.alipay.mobile.h5container.api.H5EventFilter;
import com.alipay.mobile.h5container.api.H5Param;
import com.alipay.mobile.h5container.api.H5SimplePlugin;
public class TechFinSitePlugin extends H5SimplePlugin {
@Override
public void onPrepare(H5EventFilter filter) {
super.onPrepare(filter);
filter.addAction(CommonEvents.H5_PAGE_SHOULD_LOAD_URL);
}
@Override
public boolean interceptEvent(H5Event event, H5BridgeContext context) {
String action = event.getAction();
if (CommonEvents.H5_PAGE_SHOULD_LOAD_URL.equals(action)) {
JSONObject params = event.getParam();
String url = params.getString(H5Param.LONG_URL);
if (!TextUtils.isEmpty(url) && url.contains("tech.antfin.com")) {
event.getH5page().getWebView().addJavascriptInterface(new TechFinJavaScriptInterface(), "techFinBridge");
}
}
return false;
}
}
Do not return true in the interceptEvent method. Otherwise, the container cannot load the page.
package com.mpaas.demo.nebula;
import android.webkit.JavascriptInterface;
public class TechFinJavaScriptInterface {
@JavascriptInterface
@com.uc.webview.export.JavascriptInterface
public String whoAmI() {
return "It is tech fin.";
}
}
The system kernel and the UC kernel use different annotation classes. You must ensure compatibility with both annotation classes.
Add transition animations to HTML5 containers
To add transition animations to an HTML5 container, place animation resource files in the res/anim folder of your project. Follow these steps:
-
In your project's
resfolder, create ananimfolder. If the folder already exists, you can skip this step. -
Add the animation resource files to the
animfolder. The HTML5 container automatically detects the resource files based on their filenames. The filenames must beh5_slide_out_right.xml,h5_slide_out_left.xml,h5_slide_in_right.xml, orh5_slide_in_left.xml. You can use the following examples to create your own resource files.-
h5_slide_out_right.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%" android:toXDelta="100%" android:duration="300" /> </set> -
h5_slide_out_left.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0%" android:toXDelta="-100%" android:duration="300" /> </set> -
h5_slide_in_right.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%" android:toXDelta="0" android:duration="300" /> </set> -
h5_slide_in_left.xml
<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="-100%" android:toXDelta="0%" android:duration="300" /> </set>
-
Configure a blacklist for HTML5 container JSAPIs
To control JSAPI call permissions for specific domains, you can configure a blacklist. Follow these steps:
-
Inherit the
H5JSApiPermissionProviderclass and override thehasDomainPermissionmethod. This method takes two input parameters:action(the event name of the custom JSAPI) andurl(the domain of the current page). It returns abooleanvalue:trueindicates that the event can be processed, andfalseindicates no permission. The following code provides an example.public class H5JSApiPermissionProviderImpl implements H5JSApiPermissionProvider { private static final List blackList = new ArrayList<String>(); static { // URLs in the blacklist do not have permission to execute JSAPI events. blackList.add("https://mcube-prod.cn-hangzhou.oss.aliyuncs.com/ONEX4B905F1032156-MUAT/20210728/0.0.0.1_all/nebula/fallback/www/index.html"); } @override public boolean hasDomainPermission(String action, String url) { // You can determine whether you have permission to execute the current action based on the action name and URL. // action is the defined JSAPI event. Return true if the event can be processed. Return false if you do not have permission to process the event. if (blackList.contains(url)) { return false; } return true; } @override public boolean hasThisPermission(String permission, String url) { return true; } } -
After the framework is initialized, set the
Provider.H5Utils.setProvider(H5JSApiPermissionProvider.class.getName(), new H5JSApiPermissionProviderImpl());