乐于分享
好东西不私藏

三个网页一套APK:OpenClaw + Chat Gateway + Hermès 私有化部署与移动端打包指南

三个网页一套APK:OpenClaw + Chat Gateway + Hermès 私有化部署与移动端打包指南

作者:团团 🫧
日期:2026-04-18
适用场景:自己使用的私有 AI 工作站,不想每次输网址,想在手机桌面点开像 APP 一样用

已关注
关注
重播 分享

一、这篇文章解决了什么问题?

把三套 Web 管理界面——OpenClaw Control UIChat GatewayHermès——串联成一套可以装进手机桌面的 APK,像原生 APP 一样点击即用。

效果预览:

手机桌面一个图标 → 点开是三栏导航 → 底部快捷跳转 OpenClaw / Chat Gateway / Hermès


二、先认识三个主角

2.1 OpenClaw Control UI(控制台)

端口:10474
地址:http://你的服务器IP:10474/8snn7a#token=你的登录token
作用:OpenClaw 核心的 Web 控制面板,管理智能体、会话、配置、系统设置。

2.2 Chat Gateway(对话网关)

端口:3115
地址:http://你的服务器IP:3115
作用:多智能体对话管理界面,支持团队模式、会话历史、模型配置、文档预览(Word/Excel/PPT/PDF)。

2.3 Hermès(偏好设置)

端口:8787
地址:http://你的服务器IP:8787/
作用:OpenClaw 的偏好设置面板,管理 SOUL/USER 文件夹、导入导出、个人配置。


三、三者是怎么串联起来的?

1
2
3
4
5
6
7
8
9
10
11
┌─────────────────────────────────────────┐
│  OpenClaw Control UI(端口 10474)       │
│  左侧栏底部有三个跳转链接                │
│                                         │
│  [OpenClaw]  →  http://IP:3115         │
│  [Hermès]     →  http://IP:8787         │
└────────┬────────────────────────────────┘
         │
         ├─→ Chat Gateway(3115)← 多智能体对话
         │
         └─→ Hermès(8787)← 个人偏好配置

技术细节:
OpenClaw Control UI 的侧边栏底部(原sidebar-bottom区域)硬编码了三条跳转链接:

  • • OpenClaw 链接指向 Chat Gateway 的 IP:3115
  • • Hermès 链接指向 Hermès 的 IP:8787
  • • Chat Gateway 底部导航里同样有指向 OpenClaw Control UI 的快捷回程

所以在三个页面之间来回跳转,完全不用手动输地址。


四、服务器端准备

4.1 确认三个服务都在运行

1
2
3
systemctl --user status openclaw-gateway.service
systemctl --user status clawui-3115.service
# Hermès 随 OpenClaw 一起启动,无需单独服务

4.2 确认端口可访问

1
2
3
curl -s -o /dev/null -w "%{http_code}" 自定义端口
curl -s -o /dev/null -w "%{http_code}" 自定义端口
curl -s -o /dev/null -w "%{http_code}" 自定义端口

三个都返回 200 即正常。

4.3 防火墙放行(如需要)

1
2
# 阿里云轻量服务器控制台 → 防火墙 → 添加规则
# 放行端口:10474、3115、8787(TCP)

五、用的是什么技术方案?(方案选择)

目前有三个主流方案,优缺点对比如下:

方案实现难度APP 体验离线可用维护成本
WebView APK(本文推荐)⭐ 低⭐⭐⭐ 好❌ 需联网
Capacitor 打包⭐⭐⭐ 中⭐⭐⭐⭐ 佳部分
PWA(渐进式)⭐ 低⭐⭐ 一般部分最低

本文选用方案一:WebView APK,原因:零门槛、当下可用、三个页面天然支持移动端响应式。


六、动手做 APK(详细步骤)

6.1 环境准备

电脑端(开发打包用):

  • • 系统:Windows / macOS / Linux 均可
  • • Android Studio 最新版(用于生成 APK)
  • • 一台 Android 测试机(开启开发者模式 + USB 调试)

服务器端:

  • • 已部署好的三个 Web 服务(上面第四步已确认)

6.2 创建 Android 项目

如果你不想装 Android Studio,可以用在线打包平台(见 6.6 节),连这一步都可以跳过。

打开 Android Studio → New Project →Empty Views Activity→ 项目名填MyAIStation

6.3 修改布局文件 activity_main.xml

路径:app/src/main/res/layout/activity_main.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">
 
    <!-- 顶部栏(可选:显示当前在哪个服务) -->
    <androidx.appcompat.widget.Toolbar
        android:id="@+id/toolbar"
        android:layout_width="match_parent"
        android:layout_height="?attr/actionBarSize"
        android:background="#1a1a2e"
        android:title="AI 工作站"
        android:titleTextColor="#ffffff" />
 
    <!-- WebView 主区域 -->
    <WebView
        android:id="@+id/webView"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1" />
 
    <!-- 底部快捷导航栏 -->
    <com.google.android.material.bottomnavigation.BottomNavigationView
        android:id="@+id/bottomNav"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#16213e"
        app:itemIconTint="#F5C542"
        app:itemTextColor="#F5C542"
        app:menu="@menu/bottom_nav_menu"
        xmlns:app="http://schemas.android.com/apk/res-auto" />
 
</LinearLayout>

6.4 创建底部导航菜单

路径:app/src/main/res/menu/bottom_nav_menu.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
    <item
        android:id="@+id/nav_control"
        android:icon="@android:drawable/ic_menu_compass"
        android:title="控制台" />
    <item
        android:id="@+id/nav_chat"
        android:icon="@android:drawable/ic_menu-chat"
        android:title="对话" />
    <item
        android:id="@+id/nav_settings"
        android:icon="@android:drawable/ic_menu_preferences"
        android:title="设置" />
</menu>

6.5 编写 MainActivity.java

路径:app/src/main/java/com/aiworksation/MainActivity.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package com.aiworksation;
 
import android.os.Bundle;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.widget.Toolbar;
import com.google.android.material.bottomnavigation.BottomNavigationView;
 
public class MainActivity extends AppCompatActivity {
 
    private WebView webView;
    // ★ 改成你自己的服务器 IP
    private static final String CONTROL_URL = "http://42.193.158.92:10474/8snn7a#token=26d300a2bfd2421a95118ef265a89b6b80b072e022885afb";
    private static final String CHAT_URL    = "http://42.193.158.92:3115/";
    private static final String HERMES_URL  = "http://42.193.158.92:8787/";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
 
        webView = findViewById(R.id.webView);
        Toolbar toolbar = findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);
 
        // WebView 基础配置
        WebSettings settings = webView.getSettings();
        settings.setJavaScriptEnabled(true);
        settings.setDomStorageEnabled(true);
        settings.setSupportZoom(true);
        settings.setBuiltInZoomControls(true);
        settings.setDisplayZoomControls(false);
        settings.setCacheMode(WebSettings.LOAD_NO_CACHE);
        settings.setUserAgentString("Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36");
 
        // 页面在 WebView 内打开,不调用外部浏览器
        webView.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView view, android.webkit.WebResourceRequest request) {
                view.loadUrl(request.getUrl().toString());
                return true;
            }
        });
 
        // 默认打开控制台
        webView.loadUrl(CONTROL_URL);
 
        // 底部导航点击切换
        BottomNavigationView bottomNav = findViewById(R.id.bottomNav);
        bottomNav.setOnItemSelectedListener(item -> {
            int id = item.getItemId();
            if (id == R.id.nav_control) {
                webView.loadUrl(CONTROL_URL);
                toolbar.setTitle("控制台");
            } else if (id == R.id.nav_chat) {
                webView.loadUrl(CHAT_URL);
                toolbar.setTitle("对话网关");
            } else if (id == R.id.nav_settings) {
                webView.loadUrl(HERMES_URL);
                toolbar.setTitle("Hermès 设置");
            }
            return true;
        });
    }
 
    // 返回键回到上一页,而不是直接退出 APP
    @Override
    public void onBackPressed() {
        if (webView.canGoBack()) {
            webView.goBack();
        } else {
            super.onBackPressed();
        }
    }
}

6.6 添加网络权限

路径:app/src/main/AndroidManifest.xml

<manifest>标签内加入:

1
2
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

同时确保<application>标签有:

1
android:usesCleartextTraffic="true"

6.7 免 Android Studio 的替代方案:在线打包

如果不想装 Android Studio,用Capacitor + 极简 HTML的方式:

Step 1:创建项目(任意目录)

1
2
3
4
5
npm create vite@latest ai-station -- --template vanilla
cd ai-station
npm install @capacitor/core @capacitor/cli @capacitor/android
npx cap init "AI工作站" "com.aiworksation.app" --web-dir=dist
npx cap add android

Step 2:修改index.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
  <title>AI 工作站</title>
  <style>
    * { margin: 0; padding: 0; box-sizing: border-box; }
    body { font-family: -apple-system, sans-serif; background: #0f0f1a; color: #fff; }
    iframe { width: 100%; height: calc(100vh - 60px); border: none; }
    nav { display: flex; height: 60px; background: #16213e; }
    nav button { flex: 1; background: none; border: none; color: #F5C542; font-size: 14px; cursor: pointer; }
    nav button.active { background: #1a1a2e; }
  </style>
</head>
<body>
  <iframe id="frame" src="http://42.193.158.92:10474/8snn7a#token=26d300a2bfd2421a95118ef265a89b6b80b072e022885afb"></iframe>
  <nav>
    <button class="active" onclick="switchTo('control')">控制台</button>
    <button onclick="switchTo('chat')">对话</button>
    <button onclick="switchTo('hermes')">设置</button>
  </nav>
  <script>
    const PAGES = {
      control: 'http://42.193.158.92:10474/8snn7a#token=26d300a2bfd2421a95118ef265a89b6b80b072e022885afb',
      chat:    'http://42.193.158.92:3115/',
      hermes:  'http://42.193.158.92:8787/'
    };
    function switchTo(key) {
      document.getElementById('frame').src = PAGES[key];
      document.querySelectorAll('nav button').forEach(b => b.classList.remove('active'));
      event.target.classList.add('active');
    }
  </script>
</body>
</html>

Step 3:打包

1
2
npm run build
npx cap sync android

Step 4:生成 APK

1
2
3
4
5
# 用 Android Studio 打开 ai-station/android/ 目录
# 或者用命令行:
cd ai-station/android
./gradlew assembleRelease
# APK 输出在:app/build/outputs/apk/release/app-release.apk

6.8 安装到手机

方法 A(USB 直装):

1
adb install -r app-release.apk

方法 B(扫码安装):
上传 APK 到手机可访问的 URL,或通过微信/QQ文件传输助手发送到手机安装。

首次安装需要开启「安装未知来源应用」权限。


七、怎么让 APK 更像原生 APP?

7.1 添加启动页(Splash Screen)

res/drawable放一张 1080×1920 的启动图splash.png,然后创建res/layout/splash.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#0f0f1a"
    android:gravity="center"
    android:orientation="vertical">
    <TextView android:layout_width="wrap_content" android:layout_height="wrap_content"
        android:text="🫧 AI 工作站"
        android:textColor="#F5C542"
        android:textSize="28sp"
        android:textStyle="bold" />
</LinearLayout>

7.2 隐藏状态栏(沉浸式)

MainActivityonCreate()里加:

1
2
3
4
5
getWindow().getDecorView().setSystemUiVisibility(
    View.SYSTEM_UI_FLAG_FULLSCREEN
    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
);

7.3 添加 APP 图标

res/mipmap-*目录放不同分辨率的图标 PNG文件(512×512 原图),Android Studio 会自动生成各尺寸。


八、安全注意事项

⚠️ 重要:这三个地址暴露公网意味着什么?

风险项等级应对
Token 泄露🔴 高当前 token 有效期请确认,目前用的是永久 token,建议添加 IP 白名单
3115 端口无密码🔴 高至少加一层 Basic Auth 或 Gatekeeper 插件
HTTP 明文传输🟡 中条件允许的话配上 HTTPS

快速加固:给 Chat Gateway 加密码

1
2
# 在 Chat Gateway 的设置页开启 Basic Auth
# 或在 Nginx 层做反向代理认证

快速加固:Nginx HTTPS 反代配置参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
server {
    listen 443 ssl;
    server_name your-domain.com;
 
    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
 
    location / {
        proxy_pass http://127.0.0.1:10474;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
 
    location /chat {
        proxy_pass http://127.0.0.1:3115;
    }
 
    location /hermes {
        proxy_pass http://127.0.0.1:8787;
    }
}

九、日常使用流程

打开 APP

手机桌面点「AI 工作站」图标 → 进入 OpenClaw 控制台

在三个服务间切换

点底部三个 Tab:控制台/对话/设置

切换智能体对话

控制台 → 左侧栏选智能体 → 自动切换到对应团队的 Chat Gateway 会话

发送文件预览

Chat Gateway 对话 → 直接拖入 Word/Excel/PPT/PDF → 自动预览(依赖 LibreOffice)


十、常见问题

Q:装了 APK 打不开页面,显示空白?
A:检查手机网络能否访问服务器 IP(公司网络可能限制了非标准端口)。建议配上域名 + 443 端口。

Q:底部导航点击没反应?
A:在AndroidManifest.xml确认<application android:usesCleartextTraffic="true">

Q:页面加载很慢?
A:服务器带宽不够,建议开启 CDN 加速静态资源;也可以把三个服务都配上 Nginx 缓存。

Q:APP 图标能不能换成自己的?
A:可以。用 512×512 PNG 图标,通过 Android Studio 的 Image Asset 工具自动生成各尺寸,替换res/mipmap-*目录下的文件。

Q:APP 要更新怎么办?
A:重新打 APK,通过 URL 分发(如http://your-server.com/app.apk),在 APP 里写一个版本检测逻辑,跳转下载即可。


十一、今天的修改记录(技术细节存档)

如果你是在自己的服务器上复刻这套三联系统,以下是今天的改动点:

文件改动说明
openclaw/dist/control-ui/assets/index-M4TNVXB3.js第 4333 行侧边栏加入 OpenClaw + Hermès 跳转链接
hermes-webui/static/index.html第 163 行底部加入 OpenClaw Control UI 快捷入口
Chat-Gateway/frontend/src/components/Sidebar.tsx第 138-162 行侧边栏底部加 OpenClaw 快捷按钮

有问题或需要进一步定制化开发,欢迎联系作者。