logo
Desarrollo
Buscar
Guía de integración del espacio de trabajo en Android

Guía de integración del espacio de trabajo en Android

Introducción

Esta guía proporciona instrucciones detalladas sobre cómo integrar el espacio de trabajo de GPTBots en una aplicación Android, incluidas las solicitudes de permisos, la interacción nativo–H5 y otras configuraciones relacionadas.

GPTBots también proporciona un proyecto de demostración del espacio de trabajo para empezar rápidamente. Proyecto de demostración de Android: android-webview-bridge.

Lista de permisos

Permisos básicos

Para garantizar que las funciones relacionadas con el espacio de trabajo funcionen correctamente, se deben configurar los siguientes permisos en AndroidManifest.xml:

Gestión de permisos

Para garantizar que la aplicación pueda acceder en tiempo de ejecución a permisos sensibles como el micrófono, la cámara y la galería, se deben solicitar los permisos de ejecución necesarios cuando se inicia la aplicación:

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

                    
Este bloque de código en una ventana flotante

Configuración de WebView

Configuración básica

La aplicación crea una instancia de WebView y realiza los ajustes necesarios:

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
                      
                      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

                    
Este bloque de código en una ventana flotante

Configuración de grabación de audio

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
                      
                      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

                    
Este bloque de código en una ventana flotante

Configuración de User-Agent

String userAgent = webSettings.getUserAgentString(); webSettings.setUserAgentString(userAgent + " WebViewApp/1.0");
                      
                      String userAgent = webSettings.getUserAgentString();
webSettings.setUserAgentString(userAgent + " WebViewApp/1.0");

                    
Este bloque de código en una ventana flotante

Acceso al espacio de trabajo

Construcción de URL

El acceso al espacio de trabajo requiere los parámetros Base URL y AiToken:

String baseUrl = "https://gptbots.ai/space/h5/home"; String aiToken = "YOUR_AI_TOKEN"; // Replace with actual AiToken String fullUrl = baseUrl + "?AiToken=" + aiToken;
                      
                      String baseUrl = "https://gptbots.ai/space/h5/home";
String aiToken = "YOUR_AI_TOKEN"; // Replace with actual AiToken
String fullUrl = baseUrl + "?AiToken=" + aiToken;

                    
Este bloque de código en una ventana flotante

El AiToken predeterminado está preconfigurado en la aplicación. Si necesita cambiarlo, puede introducirlo en la página de inicio de sesión.

Carga de páginas

webView.loadUrl(fullUrl);
                      
                      webView.loadUrl(fullUrl);

                    
Este bloque de código en una ventana flotante

Interacción entre WebView y nativo

Registrar la interfaz de JavaScript

webView.addJavascriptInterface(new JSBridge(), "agentWebBridge");
                      
                      webView.addJavascriptInterface(new JSBridge(), "agentWebBridge");

                    
Este bloque de código en una ventana flotante

La página H5 llama a métodos nativos a través del objeto global agentWebBridge.

Gestión de permisos

Solicitudes de permisos de WebView

Cuando la página H5 solicita permisos especiales (como la grabación de audio), se deben gestionar las solicitudes de permisos de WebView:

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

                    
Este bloque de código en una ventana flotante

Gestión de selección de archivos

Gestionar las operaciones de selección de archivos desde páginas H5:

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

                    
Este bloque de código en una ventana flotante

Ejemplos de funciones

Cerrar WebView

La página H5 puede solicitar el cierre de WebView de la siguiente manera:

var message = { eventType: "click", data: { value: "close" } }; agentWebBridge.callNative(JSON.stringify(message));
                      
                      var message = {
    eventType: "click",
    data: {
        value: "close"
    }
};
agentWebBridge.callNative(JSON.stringify(message));

                    
Este bloque de código en una ventana flotante

Gestión en el lado nativo:

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

                    
Este bloque de código en una ventana flotante