Android Workspace Integration Guide
Introduction
This guide provides detailed instructions on how to integrate the GPTBots workspace into an Android application, including permission requests, native-H5 interaction, and other related configurations.
GPTBots also provides a workspace demo project to help you get started quickly. Android demo project: Android Demo Project
Permission List
Basic Permissions
To ensure workspace-related functions work properly, configure the following permissions in AndroidManifest.xml:
Permission Handling
To ensure the app can access sensitive permissions like microphone, camera, and gallery at runtime, necessary runtime permissions should be requested when the app starts:
// Permissions requested for Android 13 and above
private final String[] permissionsForAndroid13 = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO
};
// Permissions requested for below Android 13
private final String[] permissionsForBelowAndroid13 = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
WebView Configuration
Basic Configuration
The app creates a WebView instance and performs necessary settings:
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); // Enable JavaScript
webSettings.setDomStorageEnabled(true); // Enable DOM storage API
webSettings.setAllowFileAccess(true); // Allow file access
webSettings.setAllowContentAccess(true); // Allow content URL access
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); // Allow mixed content
webSettings.setMediaPlaybackRequiresUserGesture(false); // Media playback does not require user gesture
Audio Recording Configuration
webSettings.setAllowFileAccessFromFileURLs(true); // Allow file URLs to access files
webSettings.setAllowUniversalAccessFromFileURLs(true); // Allow universal access
webSettings.setDatabaseEnabled(true); // Enable database
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); // Set cache mode
User-Agent Setting
String userAgent = webSettings.getUserAgentString();
webSettings.setUserAgentString(userAgent + " WebViewApp/1.0");
``
## Workspace Access
### URL Construction
Workspace access requires Base URL and AiToken parameters:
```java
String baseUrl = "https://gptbots.ai/space/h5/home";
String aiToken = "YOUR_AI_TOKEN"; // Replace with actual AiToken
String fullUrl = baseUrl + "?AiToken=" + aiToken;
The default AiToken is pre-configured in the app. If you need to change it, you can enter it on the login page.
### Page Loading
webView.loadUrl(fullUrl);
## WebView and Native Interaction
### Register JavaScript Interface
```java
webView.addJavascriptInterface(new JSBridge(), "agentWebBridge");
The H5 page calls native methods through the global object agentWebBridge.
Permission Handling
WebView Permission Requests
When the H5 page requests special permissions (such as audio recording), WebView permission requests need to be handled:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public void onPermissionRequest(PermissionRequest request) {
String[] requestedResources = request.getResources();
boolean hasAudioPermission = false;
for (String resource : requestedResources) {
if (PermissionRequest.RESOURCE_AUDIO_CAPTURE.equals(resource)) {
hasAudioPermission = true;
break;
}
}
if (hasAudioPermission) {
// Check if the app has audio recording permission
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
request.grant(requestedResources);
} else {
// Request system permission
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CODE);
// Store permission request for handling after obtaining permission
pendingPermissionRequest = request;
}
} else {
// Grant other permissions directly
request.grant(requestedResources);
}
}
});
File Selection Handling
Handle file selection operations from H5 pages:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
// Save callback
this.filePathCallback = filePathCallback;
// Create file selection Intent
Intent intent = fileChooserParams.createIntent();
startActivityForResult(intent, REQUEST_FILE_CHOOSER);
return true;
}
});
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_FILE_CHOOSER) {
if (filePathCallback != null) {
Uri[] results = null;
if (resultCode == RESULT_OK && data != null) {
// Process selection results
// ...
}
filePathCallback.onReceiveValue(results);
filePathCallback = null;
}
}
}
Function Examples
Closing WebView
The H5 page can request to close the WebView in the following way:
var message = {
eventType: "click",
data: {
value: "close"
}
};
agentWebBridge.callNative(JSON.stringify(message));
Native side handling:
public void onClick(JSONObject data) {
String value = data.optString("value");
if (TextUtils.equals(value, "close")) {
closeWeb(data);
}
}
public void closeWeb(JSONObject data) {
// Notify H5 that it will close
JSONObject willCloseData = new JSONObject();
willCloseData.put("value", data.optString("value"));
willCloseData.put("reason", "user_request");
willCloseData.put("delay", 1000);
willCloseData.put("timestamp", System.currentTimeMillis());
webViewBridge.callH5(WebViewBridge.EVENT_CLICK, willCloseData);
// Delay closing Activity
webView.postDelayed(() -> {
finish();
}, 1000);
}
