Anleitung zur Integration des Arbeitsbereichs unter Android
Einführung
Diese Anleitung beschreibt ausführlich, wie Sie den GPTBots-Arbeitsbereich in eine Android-Anwendung integrieren, einschließlich Berechtigungsanfragen, nativer und H5-Interaktion sowie weiterer zugehöriger Konfigurationen.
GPTBots stellt außerdem ein DEMO-Projekt für den Arbeitsbereich bereit, das Ihnen einen schnellen Einstieg ermöglicht. DEMO-Projekt für Android: android-webview-bridge
Berechtigungsliste
Grundlegende Berechtigungen
Um sicherzustellen, dass die Funktionen des Arbeitsbereichs ordnungsgemäß funktionieren, müssen die folgenden Berechtigungen in der AndroidManifest.xml konfiguriert werden:
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 录音权限 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<!-- 存储权限 -->
<!-- Android 13以下 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- Android 13及以上 -->
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<!-- 其他辅助权限 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
Umgang mit Berechtigungen
Um sicherzustellen, dass die Anwendung zur Laufzeit ordnungsgemäß auf sensible Berechtigungen wie Mikrofon, Kamera und Fotoalbum zugreifen kann, sollte die Anwendung beim Start die erforderlichen Laufzeitberechtigungen dynamisch anfordern:
// Android 13及以上请求的权限
private final String[] permissionsForAndroid13 = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_MEDIA_IMAGES,
Manifest.permission.READ_MEDIA_AUDIO,
Manifest.permission.READ_MEDIA_VIDEO
};
// Android 13以下请求的权限
private final String[] permissionsForBelowAndroid13 = {
Manifest.permission.RECORD_AUDIO,
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
WebView-Konfiguration
Grundlegende Konfiguration
Die APP erstellt eine WebView-Instanz und nimmt die erforderlichen Einstellungen vor:
WebSettings webSettings = webView.getSettings();
webSettings.setJavaScriptEnabled(true); // 启用 JavaScript
webSettings.setDomStorageEnabled(true); // 启用 DOM 存储 API
webSettings.setAllowFileAccess(true); // 允许访问文件
webSettings.setAllowContentAccess(true); // 允许访问内容 URL
webSettings.setMixedContentMode(WebSettings.MIXED_CONTENT_ALWAYS_ALLOW); // 允许混合内容
webSettings.setMediaPlaybackRequiresUserGesture(false); // 不需要用户手势即可播放媒体
Konfiguration für die Audioaufnahme
webSettings.setAllowFileAccessFromFileURLs(true); // 允许文件 URL 访问文件
webSettings.setAllowUniversalAccessFromFileURLs(true); // 允许通用访问
webSettings.setDatabaseEnabled(true); // 启用数据库
webSettings.setCacheMode(WebSettings.LOAD_DEFAULT); // 设置缓存模式
User-Agent-Einstellung
String userAgent = webSettings.getUserAgentString();
webSettings.setUserAgentString(userAgent + " WebViewApp/1.0");
Zugriff auf den Arbeitsbereich
URL-Aufbau
Für den Zugriff auf den Arbeitsbereich sind die Parameter Base-URL und AiToken erforderlich:
String baseUrl = "https://gptbots.ai/space/h5/home";
String aiToken = "YOUR_AI_TOKEN"; // 替换为实际的AiToken
String fullUrl = baseUrl + "?AiToken=" + aiToken;
In der Anwendung ist ein Standard-AiToken bereits voreingestellt. Falls eine Änderung erforderlich ist, können Sie ihn auf der Anmeldeseite eingeben.
Informationen zur Erzeugung des AiToken finden Sie unter AiToken-Verschlüsselung.
Laden der Seite
webView.loadUrl(fullUrl);
Interaktion zwischen WebView und nativem Code
Registrieren der JavaScript-Schnittstelle
webView.addJavascriptInterface(new JSBridge(), "agentWebBridge");
Die H5-Seite ruft native Methoden über das globale Objekt agentWebBridge auf.
Umgang mit Berechtigungen
WebView-Berechtigungsanfrage
Wenn die H5-Seite spezielle Berechtigungen (z. B. für die Audioaufnahme) anfordert, muss die Berechtigungsanfrage der WebView verarbeitet werden:
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) {
// 检查应用是否有录音权限
if (checkSelfPermission(Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED) {
request.grant(requestedResources);
} else {
// 请求系统权限
requestPermissions(new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_CODE);
// 存储权限请求,在获得权限后处理
pendingPermissionRequest = request;
}
} else {
// 其他权限直接授予
request.grant(requestedResources);
}
}
});
Umgang mit der Dateiauswahl
Verarbeiten der Dateiauswahl auf der H5-Seite:
webView.setWebChromeClient(new WebChromeClient() {
@Override
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, FileChooserParams fileChooserParams) {
// 保存回调
this.filePathCallback = filePathCallback;
// 创建文件选择 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) {
// 处理选择结果
// ...
}
filePathCallback.onReceiveValue(results);
filePathCallback = null;
}
}
}
Funktionsbeispiele
Schließen der WebView
Die H5-Seite kann auf folgende Weise das Schließen der WebView anfordern:
var message = {
eventType: "click",
data: {
value: "close"
}
};
agentWebBridge.callNative(JSON.stringify(message));
Verarbeitung auf nativer Seite:
public void onClick(JSONObject data) {
String value = data.optString("value");
if (TextUtils.equals(value, "close")) {
closeWeb(data);
}
}
public void closeWeb(JSONObject data) {
// 通知 H5 即将关闭
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);
// 延迟关闭 Activity
webView.postDelayed(() -> {
finish();
}, 1000);
}
