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);
}