Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions demohouse/hgdoll/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.DS_Store
.idea/
21 changes: 21 additions & 0 deletions demohouse/hgdoll/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2025 削微寒

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
92 changes: 92 additions & 0 deletions demohouse/hgdoll/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<p align="center">
<img src="https://raw.githubusercontent.com/521xueweihan/HGDoll/refs/heads/main/docs/assets/icon.png" width='200'/>
<br>中文 | <a href="docs/README_en.md">English</a>
<br>HGDoll 是一款 AI 手机陪玩应用.
</p>

这是一款完全开源的 AI 手机陪玩应用。在你游戏时,HGDoll 可实时看到你的游戏画面,陪你聊天、为你加油鼓劲,带来有趣的陪伴体验。它基于豆包大模型和火山方舟 Arkitect 构建,包含[安卓客户端](android/README.md)(Kotlin)和[后端服务](server/README.md)(Python)两部分,支持本地运行轻松上手。

https://github.com/user-attachments/assets/704d7f2a-3206-45f2-8760-d9cf9577ca7c

目前,HGDoll 还只是一个“小玩具”,仍有许多 Bug 和改进空间,我会持续更新和完善,同时欢迎大家上手体验,一起贡献代码。

## 架构图

```mermaid
graph TD
User((用户)) --> Android[安卓客户端]

subgraph Client[客户端]
Android --> Speech[语音识别]
Android --> Screen[屏幕录制]
Speech --> SpeechAPI[Doubao-流式语音识别]
SpeechAPI --> TextResult[语音转文字结果]
Screen --> ScreenCapture[定时截图]
AudioPlay[语音播放] --> Android
end

subgraph Server[Server 端 Arkitect]
TextResult --> Backend[后端服务]
ScreenCapture --> Backend
Backend --> TempMemory[临时记忆体]
TempMemory --> Context[会话上下文]
Context --> CTX1[Context-id-1]
Context --> CTX2[Context-id-2]
Context --> CTX3[Context-id-3]
Context --> CTXN[...]
Context --> Prompt[Prompt 生成]
ImageResult[截图识别结果] --> TempMemory
AudioResult[语音合成结果] --> AudioPlay
end

subgraph AI[AI 模型服务]
Backend --> VLM[Doubao-vision-pro-32k]
VLM --> ImageResult
Prompt --> LLM[Doubao-pro-32k]
LLM --> TTS[Doubao-语音合成]
TTS --> AudioResult
end

style User fill:#f9f,stroke:#333,stroke-width:2px
style Client fill:#e4f7fb,stroke:#333,stroke-width:1px
style Server fill:#e6ffe6,stroke:#333,stroke-width:1px
style AI fill:#e6e6ff,stroke:#333,stroke-width:1px
style Android fill:#fff,stroke:#333,stroke-width:1px
style Backend fill:#fff,stroke:#333,stroke-width:1px
style VLM fill:#fff,stroke:#333,stroke-width:1px
style LLM fill:#fff,stroke:#333,stroke-width:1px
style TTS fill:#fff,stroke:#333,stroke-width:1px
```


## 快速开始

客户端、后端的启动和安装步骤都在对应目录下,需要配置必要的 API Key 申请方法,[点击查看](docs/key.md)

### 项目结构

```
HGDoll/
├── android/ # 安卓客户端
├── server/ # 后端服务
└── docs/ # 项目文档
```

### 技术栈

#### 安卓客户端
- Kotlin
- Jetpack Compose
- Gradle Kotlin DSL
- AndroidX

#### 后端服务
- Python 3.8-3.12
- FastAPI
- 火山方舟 Arkitect SDK
- Uvicorn


## 许可证

本项目采用 MIT 许可证,详见 [LICENSE](LICENSE) 文件。
29 changes: 29 additions & 0 deletions demohouse/hgdoll/android/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Compiled class file
*.class

# Log file
*.log

# BlueJ files
*.ctxt

# Mobile Tools for Java (J2ME)
.mtj.tmp/

# Package Files #
*.jar
*.war
*.nar
*.ear
*.zip
*.tar.gz
*.rar

# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
hs_err_pid*
replay_pid*

# Kotlin Gradle plugin data, see https://kotlinlang.org/docs/whatsnew20.html#new-directory-for-kotlin-data-in-gradle-projects
.kotlin/
.DS_Store
.gradle/
60 changes: 60 additions & 0 deletions demohouse/hgdoll/android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# HGDoll 安卓客户端

![](show.png)

HGDoll 是一个基于 Kotlin 和 Jetpack Compose 开发的安卓客户端应用,它采用豆包语音大模型服务,[点击查看](../docs/key.md)如何申请运行所需的 API Key。

## 环境要求

- Android Studio Hedgehog | 2023.1.1 或更高版本
- JDK 17 或更高版本
- Gradle 8.0 或更高版本
- Android SDK 34 (Android 14) 或更高版本

## 快速开始

### 1. 克隆代码库

```bash
git clone https://github.com/521xueweihan/HGDoll.git
cd android/
```

### 2. 配置开发环境

1. 打开 Android Studio
2. 选择 "Open an existing project"
3. 选择克隆下来的 `android` 目录
4. 等待 Gradle 同步完成

### 3. 运行应用

1. 连接 Android 设备或启动模拟器
2. 点击 Android Studio 工具栏中的 "Run" 按钮(绿色三角形)
3. 选择目标设备
4. 等待应用安装和启动
5. 在 App 中输入对应的 ASR Token、ASR App ID、本地 Server IP


## 项目结构

- `app/` - 主应用模块
- `gradle/` - Gradle 包装器文件
- `build.gradle.kts` - 项目级构建配置
- `settings.gradle.kts` - 项目设置文件
- `gradle.properties` - Gradle 属性配置

## 技术栈

- Kotlin - 主要编程语言
- Jetpack Compose - 现代 UI 工具包
- Gradle Kotlin DSL - 构建脚本
- AndroidX - Android 扩展库

## 贡献指南

1. Fork 项目
2. 创建特性分支 (`git checkout -b feature/AmazingFeature`)
3. 提交更改 (`git commit -m 'Add some AmazingFeature'`)
4. 推送到分支 (`git push origin feature/AmazingFeature`)
5. 创建 Pull Request
1 change: 1 addition & 0 deletions demohouse/hgdoll/android/app/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/build
73 changes: 73 additions & 0 deletions demohouse/hgdoll/android/app/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
alias(libs.plugins.kotlin.compose)
}

android {
namespace = "com.example.android"
compileSdk = 35

defaultConfig {
applicationId = "com.example.android"
minSdk = 24
targetSdk = 35
versionCode = 1
versionName = "1.0"

testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
}

buildTypes {
release {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = "11"
}
buildFeatures {
compose = true
}
}

dependencies {
implementation(libs.androidx.core.ktx)
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.androidx.activity.compose)
implementation(platform(libs.androidx.compose.bom))
implementation(libs.androidx.ui)
implementation(libs.androidx.ui.graphics)
implementation(libs.androidx.ui.tooling.preview)
implementation(libs.androidx.material3)

// 添加屏幕录制相关依赖
implementation("androidx.media:media:1.6.0")
implementation("com.github.bumptech.glide:glide:4.12.0")

// 添加音频录制相关依赖
implementation("com.google.android.exoplayer:exoplayer-core:2.19.1")
implementation("com.google.android.exoplayer:exoplayer-ui:2.19.1")

// 网络请求相关依赖
implementation("com.squareup.retrofit2:retrofit:2.9.0")
implementation("com.squareup.retrofit2:converter-gson:2.9.0")
implementation("com.squareup.okhttp3:okhttp:4.11.0")
implementation("com.squareup.okhttp3:logging-interceptor:4.11.0")

testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
debugImplementation(libs.androidx.ui.tooling)
debugImplementation(libs.androidx.ui.test.manifest)
}
21 changes: 21 additions & 0 deletions demohouse/hgdoll/android/app/proguard-rules.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}

# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
48 changes: 48 additions & 0 deletions demohouse/hgdoll/android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">

<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />

<application
android:usesCleartextTraffic="true"
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Android"
tools:targetApi="31">
<service
android:name=".service.ScreenshotService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="mediaProjection" />
<service
android:name=".service.AsrService"
android:enabled="true"
android:exported="false"
android:foregroundServiceType="microphone" />
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Android">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading