diff --git a/test/src/main/AndroidManifest.xml b/test/src/main/AndroidManifest.xml
index 62f5af7..ec2408a 100644
--- a/test/src/main/AndroidManifest.xml
+++ b/test/src/main/AndroidManifest.xml
@@ -28,7 +28,8 @@
+ android:exported="false"
+ android:theme="@style/Theme.DUIX.Call">
diff --git a/test/src/main/java/ai/guiji/duix/test/model/AvatarModel.kt b/test/src/main/java/ai/guiji/duix/test/model/AvatarModel.kt
new file mode 100644
index 0000000..700daa6
--- /dev/null
+++ b/test/src/main/java/ai/guiji/duix/test/model/AvatarModel.kt
@@ -0,0 +1,15 @@
+package ai.guiji.duix.test.model
+
+/**
+ * 数字人形象模型
+ * @param name 中文显示名
+ * @param voice 语音音色名(传给 Omni Realtime)
+ * @param modelUrl 模型资源下载地址
+ * @param avatarRes 头像资源 ID(mipmap)
+ */
+data class AvatarModel(
+ val name: String,
+ val voice: String,
+ val modelUrl: String,
+ val avatarRes: Int
+)
diff --git a/test/src/main/java/ai/guiji/duix/test/realtime/OmniRealtimeClient.java b/test/src/main/java/ai/guiji/duix/test/realtime/OmniRealtimeClient.java
index c09f74b..adeaa73 100644
--- a/test/src/main/java/ai/guiji/duix/test/realtime/OmniRealtimeClient.java
+++ b/test/src/main/java/ai/guiji/duix/test/realtime/OmniRealtimeClient.java
@@ -30,10 +30,12 @@ public class OmniRealtimeClient {
private final OkHttpClient okHttpClient;
private WebSocket webSocket;
private final Callback callback;
+ private final String voice;
private final AtomicBoolean isConnected = new AtomicBoolean(false);
private final AtomicBoolean userSpeaking = new AtomicBoolean(false);
- public OmniRealtimeClient(Callback callback) {
+ public OmniRealtimeClient(String voice, Callback callback) {
+ this.voice = voice;
this.callback = callback;
this.okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
@@ -98,7 +100,7 @@ public class OmniRealtimeClient {
try {
JSONObject session = new JSONObject();
session.put("modalities", new org.json.JSONArray().put("text").put("audio"));
- session.put("voice", "Ethan");
+ session.put("voice", voice);
session.put("input_audio_format", "pcm");
session.put("output_audio_format", "pcm");
session.put("instructions", "你是一名面向中国老年群体的心理陪伴 AI。你的职责是为老人提供温和、耐心、尊重、稳定的情感陪伴、情绪支持、回忆唤起、生活关怀和风险识别服务。你不是医生,也不是心理治疗师,不能替代专业诊疗,但应在必要时建议联系家属、社区、医生或急救资源。\n" +
diff --git a/test/src/main/java/ai/guiji/duix/test/ui/activity/CallActivity.kt b/test/src/main/java/ai/guiji/duix/test/ui/activity/CallActivity.kt
index 508ebfa..f55d6b0 100644
--- a/test/src/main/java/ai/guiji/duix/test/ui/activity/CallActivity.kt
+++ b/test/src/main/java/ai/guiji/duix/test/ui/activity/CallActivity.kt
@@ -25,7 +25,6 @@ import android.util.Log
import android.view.View
import android.widget.CompoundButton
import android.widget.Toast
-import androidx.core.content.ContextCompat
import com.bumptech.glide.Glide
import java.io.File
import java.io.FileInputStream
@@ -39,6 +38,7 @@ class CallActivity : BaseActivity() {
}
private var modelUrl = ""
+ private var voice = "Ethan"
private var debug = false
private var mMessage = ""
@@ -82,6 +82,7 @@ class CallActivity : BaseActivity() {
setContentView(binding.root)
modelUrl = intent.getStringExtra("modelUrl") ?: ""
+ voice = intent.getStringExtra("voice") ?: "Ethan"
debug = intent.getBooleanExtra("debug", false)
Glide.with(mContext).load("file:///android_asset/bg/bg1.png").into(binding.ivBg)
@@ -311,14 +312,15 @@ class CallActivity : BaseActivity() {
applyMessage("AI对话: 连接中...")
binding.tvSubtitle.visibility = View.VISIBLE
binding.tvSubtitle.text = "正在连接..."
- binding.btnAIConversation.text = getString(R.string.ai_fab_stop)
+ binding.btnAIConversation.setImageResource(R.drawable.ic_mic_off)
+ binding.btnAIConversation.setBackgroundResource(R.drawable.shape_fab_ai_active)
- omniClient = OmniRealtimeClient(object : OmniRealtimeClient.Callback {
+ omniClient = OmniRealtimeClient(voice, object : OmniRealtimeClient.Callback {
override fun onConnected() {
mainHandler.post {
binding.tvSubtitle.text = "已连接,请对着麦克风说话"
binding.btnCameraToggle.visibility = View.VISIBLE
- binding.btnCameraToggle.background = ContextCompat.getDrawable(mContext, R.drawable.shape_circle_camera_off)
+ binding.btnCameraToggle.setBackgroundResource(R.drawable.shape_fab_camera_off)
binding.btnCameraToggle.contentDescription = getString(R.string.camera_off)
isCameraEnabled = false
applyMessage("AI对话: 已连接")
@@ -425,7 +427,8 @@ class CallActivity : BaseActivity() {
mainHandler.post {
if (!isFinishing) {
- binding.btnAIConversation.text = getString(R.string.ai_fab_start)
+ binding.btnAIConversation.setImageResource(R.drawable.ic_mic)
+ binding.btnAIConversation.setBackgroundResource(R.drawable.shape_fab_ai)
binding.btnCameraToggle.visibility = View.GONE
binding.tvSubtitle.visibility = View.GONE
binding.tvSubtitle.text = ""
@@ -451,11 +454,11 @@ class CallActivity : BaseActivity() {
}
}, binding.cameraPreview)
cameraFrameCapture?.start()
- binding.btnCameraToggle.background = ContextCompat.getDrawable(mContext, R.drawable.shape_circle_camera_on)
+ binding.btnCameraToggle.setBackgroundResource(R.drawable.shape_fab_camera_on)
binding.btnCameraToggle.contentDescription = getString(R.string.camera_on)
} else {
stopCamera()
- binding.btnCameraToggle.background = ContextCompat.getDrawable(mContext, R.drawable.shape_circle_camera_off)
+ binding.btnCameraToggle.setBackgroundResource(R.drawable.shape_fab_camera_off)
binding.btnCameraToggle.contentDescription = getString(R.string.camera_off)
}
}
diff --git a/test/src/main/java/ai/guiji/duix/test/ui/activity/MainActivity.kt b/test/src/main/java/ai/guiji/duix/test/ui/activity/MainActivity.kt
index 15b5ef7..c868f76 100644
--- a/test/src/main/java/ai/guiji/duix/test/ui/activity/MainActivity.kt
+++ b/test/src/main/java/ai/guiji/duix/test/ui/activity/MainActivity.kt
@@ -1,113 +1,96 @@
package ai.guiji.duix.test.ui.activity
-import ai.guiji.duix.sdk.client.BuildConfig
import ai.guiji.duix.sdk.client.VirtualModelUtil
import ai.guiji.duix.test.R
import ai.guiji.duix.test.databinding.ActivityMainBinding
+import ai.guiji.duix.test.model.AvatarModel
+import ai.guiji.duix.test.ui.adapter.AvatarAdapter
import ai.guiji.duix.test.ui.dialog.LoadingDialog
-import ai.guiji.duix.test.ui.dialog.ModelSelectorDialog
-import android.annotation.SuppressLint
import android.content.Intent
import android.os.Bundle
-import android.text.TextUtils
import android.widget.Toast
+import androidx.recyclerview.widget.GridLayoutManager
import java.io.File
class MainActivity : BaseActivity() {
private lateinit var binding: ActivityMainBinding
- private var mLoadingDialog: LoadingDialog?=null
+ private var mLoadingDialog: LoadingDialog? = null
private var mLastProgress = 0
- val models = arrayListOf(
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/bendi3_20240518.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/airuike_20240409.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/675429759852613_7f8d9388a4213080b1820b83dd057cfb_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/674402003804229_f6e86fb375c4f1f1b82b24f7ee4e7cb4_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/674400178376773_3925e756433c5a9caa9b9d54147ae4ab_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/674397294927941_6e297e18a4bdbe35c07a6ae48a1f021f_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/674393494597701_f49fcf68f5afdb241d516db8a7d88a7b_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/651705983152197_ccf3256b2449c76e77f94276dffcb293_optim_m80.zip",
- "https://github.com/duixcom/Duix-Mobile/releases/download/v1.0.0/627306542239813_1871244b5e6912efc636ba31ea4c5c6d_optim_m80.zip",
+ private val baseConfigUrl = "https://dl.xn--876a.net/models/gj_dh_res.zip"
+
+ private val avatarModels = listOf(
+ AvatarModel("晨煦", "Ethan", "https://dl.xn--876a.net/models/bendi3_20240518.zip", R.mipmap.ethan),
+ AvatarModel("詹妮弗", "Jennifer", "https://dl.xn--876a.net/models/Emma.zip", R.mipmap.jennifer),
+ AvatarModel("月白", "Moon", "https://dl.xn--876a.net/models/Kai.zip", R.mipmap.moon),
+ AvatarModel("艾登", "Aiden", "https://dl.xn--876a.net/models/Leo.zip", R.mipmap.leo),
+ AvatarModel("四月", "Maia", "https://dl.xn--876a.net/models/Lily.zip", R.mipmap.lily),
+ AvatarModel("奥利弗", "Andre", "https://dl.xn--876a.net/models/Oliver.zip", R.mipmap.oliver),
+ AvatarModel("索菲亚", "Sonrisa", "https://dl.xn--876a.net/models/Sofia.zip", R.mipmap.sofia),
)
- private var mBaseConfigUrl = ""
- private var mModelUrl = ""
+ private var mSelectedModel: AvatarModel? = null
- @SuppressLint("SetTextI18n")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
- binding.tvSdkVersion.text = "SDK Version: ${BuildConfig.VERSION_NAME}"
-
-
- binding.btnMoreModel.setOnClickListener {
- val modelSelectorDialog = ModelSelectorDialog(mContext, models, object : ModelSelectorDialog.Listener{
- override fun onSelect(url: String) {
- binding.etUrl.setText(url)
- }
- })
- modelSelectorDialog.show()
- }
- binding.btnPlay.setOnClickListener {
- play()
- }
+ binding.rvAvatars.layoutManager = GridLayoutManager(this, 2)
+ binding.rvAvatars.adapter = AvatarAdapter(avatarModels, object : AvatarAdapter.Callback {
+ override fun onSelect(model: AvatarModel) {
+ mSelectedModel = model
+ play(model)
+ }
+ })
}
- private fun play(){
- mBaseConfigUrl = binding.etBaseConfig.text.toString()
- mModelUrl = binding.etUrl.text.toString()
- if (TextUtils.isEmpty(mBaseConfigUrl)){
- Toast.makeText(mContext, R.string.base_config_cannot_be_empty, Toast.LENGTH_SHORT).show()
- return
- }
- if (TextUtils.isEmpty(mModelUrl)){
- Toast.makeText(mContext, R.string.model_url_cannot_be_empty, Toast.LENGTH_SHORT).show()
- return
- }
+ private fun play(model: AvatarModel) {
+ mSelectedModel = model
checkBaseConfig()
}
- private fun checkBaseConfig(){
- if (VirtualModelUtil.checkBaseConfig(mContext)){
+ private fun checkBaseConfig() {
+ if (VirtualModelUtil.checkBaseConfig(mContext)) {
checkModel()
} else {
baseConfigDownload()
}
}
- private fun checkModel(){
- if (VirtualModelUtil.checkModel(mContext, mModelUrl)){
+ private fun checkModel() {
+ val model = mSelectedModel ?: return
+ if (VirtualModelUtil.checkModel(mContext, model.modelUrl)) {
jumpPlayPage()
} else {
modelDownload()
}
}
- private fun jumpPlayPage(){
+ private fun jumpPlayPage() {
+ val model = mSelectedModel ?: return
val intent = Intent(mContext, CallActivity::class.java)
- intent.putExtra("modelUrl", mModelUrl)
- val debug = binding.switchDebug.isChecked
- intent.putExtra("debug", debug)
+ intent.putExtra("modelUrl", model.modelUrl)
+ intent.putExtra("voice", model.voice)
+ intent.putExtra("debug", false)
startActivity(intent)
}
- private fun baseConfigDownload(){
+ private fun baseConfigDownload() {
mLoadingDialog?.dismiss()
- mLoadingDialog = LoadingDialog(mContext, "Start downloading")
+ mLoadingDialog = LoadingDialog(mContext, "正在准备资源...")
mLoadingDialog?.show()
- VirtualModelUtil.baseConfigDownload(mContext, mBaseConfigUrl, object :
+ VirtualModelUtil.baseConfigDownload(mContext, baseConfigUrl, object :
VirtualModelUtil.ModelDownloadCallback {
override fun onDownloadProgress(url: String?, current: Long, total: Long) {
val progress = (current * 100 / total).toInt()
- if (progress != mLastProgress){
+ if (progress != mLastProgress) {
mLastProgress = progress
runOnUiThread {
- if (mLoadingDialog?.isShowing == true){
- mLoadingDialog?.setContent("Config download(${progress}%)")
+ if (mLoadingDialog?.isShowing == true) {
+ mLoadingDialog?.setContent("基础配置下载中(${progress}%)")
}
}
}
@@ -115,11 +98,11 @@ class MainActivity : BaseActivity() {
override fun onUnzipProgress(url: String?, current: Long, total: Long) {
val progress = (current * 100 / total).toInt()
- if (progress != mLastProgress){
+ if (progress != mLastProgress) {
mLastProgress = progress
runOnUiThread {
- if (mLoadingDialog?.isShowing == true){
- mLoadingDialog?.setContent("Config unzip(${progress}%)")
+ if (mLoadingDialog?.isShowing == true) {
+ mLoadingDialog?.setContent("基础配置解压中(${progress}%)")
}
}
}
@@ -135,45 +118,37 @@ class MainActivity : BaseActivity() {
override fun onDownloadFail(url: String?, code: Int, msg: String?) {
runOnUiThread {
mLoadingDialog?.dismiss()
- Toast.makeText(mContext, "BaseConfig download error: $msg", Toast.LENGTH_SHORT).show()
+ Toast.makeText(mContext, "资源下载失败: $msg", Toast.LENGTH_SHORT).show()
}
}
-
})
}
- private fun modelDownload(){
+ private fun modelDownload() {
+ val model = mSelectedModel ?: return
mLoadingDialog?.dismiss()
- mLoadingDialog = LoadingDialog(mContext, "Start downloading")
+ mLoadingDialog = LoadingDialog(mContext, "正在下载 ${model.name} ...")
mLoadingDialog?.show()
- VirtualModelUtil.modelDownload(mContext, mModelUrl, object : VirtualModelUtil.ModelDownloadCallback{
- override fun onDownloadProgress(
- url: String?,
- current: Long,
- total: Long,
- ) {
+ VirtualModelUtil.modelDownload(mContext, model.modelUrl, object : VirtualModelUtil.ModelDownloadCallback {
+ override fun onDownloadProgress(url: String?, current: Long, total: Long) {
val progress = (current * 100 / total).toInt()
- if (progress != mLastProgress){
+ if (progress != mLastProgress) {
mLastProgress = progress
runOnUiThread {
- if (mLoadingDialog?.isShowing == true){
- mLoadingDialog?.setContent("Model download(${progress}%)")
+ if (mLoadingDialog?.isShowing == true) {
+ mLoadingDialog?.setContent("${model.name} 下载中(${progress}%)")
}
}
}
}
- override fun onUnzipProgress(
- url: String?,
- current: Long,
- total: Long,
- ) {
+ override fun onUnzipProgress(url: String?, current: Long, total: Long) {
val progress = (current * 100 / total).toInt()
- if (progress != mLastProgress){
+ if (progress != mLastProgress) {
mLastProgress = progress
runOnUiThread {
- if (mLoadingDialog?.isShowing == true){
- mLoadingDialog?.setContent("Model unzip(${progress}%)")
+ if (mLoadingDialog?.isShowing == true) {
+ mLoadingDialog?.setContent("${model.name} 解压中(${progress}%)")
}
}
}
@@ -186,18 +161,12 @@ class MainActivity : BaseActivity() {
}
}
- override fun onDownloadFail(
- url: String?,
- code: Int,
- msg: String?,
- ) {
+ override fun onDownloadFail(url: String?, code: Int, msg: String?) {
runOnUiThread {
mLoadingDialog?.dismiss()
- Toast.makeText(mContext, "Model download error: $msg", Toast.LENGTH_SHORT).show()
+ Toast.makeText(mContext, "下载失败: $msg", Toast.LENGTH_SHORT).show()
}
}
-
})
}
-
}
diff --git a/test/src/main/java/ai/guiji/duix/test/ui/adapter/AvatarAdapter.kt b/test/src/main/java/ai/guiji/duix/test/ui/adapter/AvatarAdapter.kt
new file mode 100644
index 0000000..011aecc
--- /dev/null
+++ b/test/src/main/java/ai/guiji/duix/test/ui/adapter/AvatarAdapter.kt
@@ -0,0 +1,38 @@
+package ai.guiji.duix.test.ui.adapter
+
+import ai.guiji.duix.test.databinding.ItemAvatarCardBinding
+import ai.guiji.duix.test.model.AvatarModel
+import android.view.LayoutInflater
+import android.view.ViewGroup
+import androidx.recyclerview.widget.RecyclerView
+
+class AvatarAdapter(
+ private val list: List,
+ private val callback: Callback
+) : RecyclerView.Adapter() {
+
+ class ViewHolder(val binding: ItemAvatarCardBinding) :
+ RecyclerView.ViewHolder(binding.root)
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ val binding = ItemAvatarCardBinding.inflate(
+ LayoutInflater.from(parent.context), parent, false
+ )
+ return ViewHolder(binding)
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val model = list[position]
+ holder.binding.ivAvatar.setImageResource(model.avatarRes)
+ holder.binding.tvName.text = model.name
+ holder.binding.cardAvatar.setOnClickListener {
+ callback.onSelect(model)
+ }
+ }
+
+ override fun getItemCount(): Int = list.size
+
+ interface Callback {
+ fun onSelect(model: AvatarModel)
+ }
+}
diff --git a/test/src/main/res/drawable/ic_camera.xml b/test/src/main/res/drawable/ic_camera.xml
new file mode 100644
index 0000000..a6f4f9c
--- /dev/null
+++ b/test/src/main/res/drawable/ic_camera.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/test/src/main/res/drawable/ic_mic.xml b/test/src/main/res/drawable/ic_mic.xml
new file mode 100644
index 0000000..d963e13
--- /dev/null
+++ b/test/src/main/res/drawable/ic_mic.xml
@@ -0,0 +1,10 @@
+
+
+
diff --git a/test/src/main/res/drawable/ic_mic_off.xml b/test/src/main/res/drawable/ic_mic_off.xml
new file mode 100644
index 0000000..1aa5ae6
--- /dev/null
+++ b/test/src/main/res/drawable/ic_mic_off.xml
@@ -0,0 +1,14 @@
+
+
+
+
diff --git a/test/src/main/res/drawable/shape_fab_ai.xml b/test/src/main/res/drawable/shape_fab_ai.xml
new file mode 100644
index 0000000..942b2f3
--- /dev/null
+++ b/test/src/main/res/drawable/shape_fab_ai.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/test/src/main/res/drawable/shape_fab_ai_active.xml b/test/src/main/res/drawable/shape_fab_ai_active.xml
new file mode 100644
index 0000000..1078fe0
--- /dev/null
+++ b/test/src/main/res/drawable/shape_fab_ai_active.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/test/src/main/res/drawable/shape_fab_camera_off.xml b/test/src/main/res/drawable/shape_fab_camera_off.xml
new file mode 100644
index 0000000..10c91c1
--- /dev/null
+++ b/test/src/main/res/drawable/shape_fab_camera_off.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/test/src/main/res/drawable/shape_fab_camera_on.xml b/test/src/main/res/drawable/shape_fab_camera_on.xml
new file mode 100644
index 0000000..cf47529
--- /dev/null
+++ b/test/src/main/res/drawable/shape_fab_camera_on.xml
@@ -0,0 +1,5 @@
+
+
+
+
diff --git a/test/src/main/res/layout/activity_call.xml b/test/src/main/res/layout/activity_call.xml
index 2219ea2..75b721c 100644
--- a/test/src/main/res/layout/activity_call.xml
+++ b/test/src/main/res/layout/activity_call.xml
@@ -2,7 +2,6 @@
-
-
diff --git a/test/src/main/res/layout/activity_main.xml b/test/src/main/res/layout/activity_main.xml
index 99044d7..5715811 100644
--- a/test/src/main/res/layout/activity_main.xml
+++ b/test/src/main/res/layout/activity_main.xml
@@ -3,119 +3,56 @@
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:padding="12dp">
+ android:fitsSystemWindows="true"
+ android:background="@color/warm_bg">
+
-
+
+ android:clipToPadding="false"
+ android:paddingStart="10dp"
+ android:paddingEnd="10dp"
+ android:paddingBottom="16dp"
+ app:layout_constraintBottom_toTopOf="@+id/tvBottomHint"
+ app:layout_constraintTop_toBottomOf="@+id/tv_subtitle" />
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
\ No newline at end of file
diff --git a/test/src/main/res/layout/item_avatar_card.xml b/test/src/main/res/layout/item_avatar_card.xml
new file mode 100644
index 0000000..a2ee6a3
--- /dev/null
+++ b/test/src/main/res/layout/item_avatar_card.xml
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/src/main/res/mipmap-hdpi/ethan.webp b/test/src/main/res/mipmap-hdpi/ethan.webp
new file mode 100644
index 0000000..121547c
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/ethan.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/jennifer.webp b/test/src/main/res/mipmap-hdpi/jennifer.webp
new file mode 100644
index 0000000..1274f65
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/jennifer.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/leo.webp b/test/src/main/res/mipmap-hdpi/leo.webp
new file mode 100644
index 0000000..34bbbeb
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/leo.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/lily.webp b/test/src/main/res/mipmap-hdpi/lily.webp
new file mode 100644
index 0000000..9e0f13a
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/lily.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/moon.webp b/test/src/main/res/mipmap-hdpi/moon.webp
new file mode 100644
index 0000000..bacf907
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/moon.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/oliver.webp b/test/src/main/res/mipmap-hdpi/oliver.webp
new file mode 100644
index 0000000..4b261fd
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/oliver.webp differ
diff --git a/test/src/main/res/mipmap-hdpi/sofia.webp b/test/src/main/res/mipmap-hdpi/sofia.webp
new file mode 100644
index 0000000..4445669
Binary files /dev/null and b/test/src/main/res/mipmap-hdpi/sofia.webp differ
diff --git a/test/src/main/res/values/colors.xml b/test/src/main/res/values/colors.xml
index 9d797fb..0f72057 100644
--- a/test/src/main/res/values/colors.xml
+++ b/test/src/main/res/values/colors.xml
@@ -9,4 +9,11 @@
#FFFFFFFF
#5a7bbe
#995a7bbe
+
+
+ #FFF5F0EB
+ #FF3E2723
+ #FF8D6E63
+ #FFBCAAA4
+ #FFE8926F
\ No newline at end of file
diff --git a/test/src/main/res/values/strings.xml b/test/src/main/res/values/strings.xml
index c2857c7..5d196fe 100644
--- a/test/src/main/res/values/strings.xml
+++ b/test/src/main/res/values/strings.xml
@@ -1,5 +1,8 @@
- DUIX Demo
+ AI 情感陪护
+ AI 情感陪护
+ 选一位陪伴者,开始温暖对话
+ 点击头像即可开始对话
Play
BaseConfig Url:
Model Url:
diff --git a/test/src/main/res/values/themes.xml b/test/src/main/res/values/themes.xml
index 8122445..fdafecf 100644
--- a/test/src/main/res/values/themes.xml
+++ b/test/src/main/res/values/themes.xml
@@ -1,15 +1,24 @@
-
+
+
+
\ No newline at end of file