feat: replace with native Android empty-shell UI (Main/Settings + stub ServerClient/WatchBridge)

This commit is contained in:
2026-09-01 18:49:15 +08:00
parent 18ec9fadc7
commit 0673ff77b7
29 changed files with 367 additions and 266 deletions
+19
View File
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:label="@string/app_name"
android:theme="@style/Theme.DSHWatch">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".SettingsActivity"
android:exported="false" />
</application>
</manifest>
@@ -0,0 +1,38 @@
package com.dshwatch.app;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView status = findViewById(R.id.status_text);
status.setText(getString(R.string.status_disconnected));
Button settings = findViewById(R.id.btn_settings);
settings.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
}
});
Button refresh = findViewById(R.id.btn_refresh);
refresh.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 空壳:后续调用 ServerClient 拉取 Harness 状态
status.setText(R.string.status_disconnected);
}
});
}
}
@@ -0,0 +1,31 @@
package com.dshwatch.app;
/**
* Harness 服务器客户端(空壳)。
* 后续接入 WebSocket(OkHttp ws),通过 DSHWatch_Server 或直连 dsh-watch 插件,
* 实现 harness.status / session.prompt / session.list 等 RPC。
*/
public class ServerClient {
private String serverUrl;
private String userId;
private String token;
public ServerClient(String serverUrl, String userId, String token) {
this.serverUrl = serverUrl;
this.userId = userId;
this.token = token;
}
public void connect() {
// 空壳:TODO 实现 WebSocket 握手 + 请求/响应 + 事件回调
}
public void sendRequest(String method, String paramsJson, Callback cb) {
// 空壳:TODO
}
public interface Callback {
void onResult(String json);
void onError(String message);
}
}
@@ -0,0 +1,35 @@
package com.dshwatch.app;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class SettingsActivity extends AppCompatActivity {
private EditText serverUrl;
private EditText userId;
private EditText token;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
serverUrl = findViewById(R.id.input_server);
userId = findViewById(R.id.input_user);
token = findViewById(R.id.input_token);
Button save = findViewById(R.id.btn_save);
save.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 空壳:后续持久化到 SharedPreferences / 安全存储
Toast.makeText(SettingsActivity.this, "保存(空壳): " + serverUrl.getText(), Toast.LENGTH_SHORT).show();
}
});
}
}
@@ -0,0 +1,15 @@
package com.dshwatch.app;
/**
* 手表 BLE 互联桥(空壳)。
* 后续接入小米穿戴 SDK:Wearable / MessageApi / sendMessage / addListener,
* 用于把手表(DSHWatch) 与手机端双向转发。
*/
public interface WatchBridge {
/** 连接手表(小米穿戴服务) */
void connect();
/** 发送消息给手表 */
void sendToWatch(String json);
/** 接收来自手表的消息 */
String onWatchMessage(String json);
}
+48
View File
@@ -0,0 +1,48 @@
<?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"
android:padding="24dp"
android:background="@color/deep_blue">
<TextView
android:id="@+id/title"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/app_name"
android:textColor="@color/white"
android:textSize="24sp"
android:textStyle="bold" />
<TextView
android:id="@+id/status_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/status_disconnected"
android:textColor="@color/white"
android:textSize="16sp" />
<Button
android:id="@+id/btn_refresh"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/btn_refresh" />
<Button
android:id="@+id/btn_settings"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:text="@string/btn_settings" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="32dp"
android:text="@string/shell_hint"
android:textColor="@color/light_blue"
android:textSize="13sp" />
</LinearLayout>
@@ -0,0 +1,69 @@
<?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"
android:padding="24dp"
android:background="@color/deep_blue">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/settings_title"
android:textColor="@color/white"
android:textSize="22sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:text="@string/label_server"
android:textColor="@color/light_blue" />
<EditText
android:id="@+id/input_server"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_server"
android:textColor="@color/white"
android:textColorHint="@color/light_blue" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/label_user"
android:textColor="@color/light_blue" />
<EditText
android:id="@+id/input_user"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_user"
android:textColor="@color/white"
android:textColorHint="@color/light_blue" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="@string/label_token"
android:textColor="@color/light_blue" />
<EditText
android:id="@+id/input_token"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/hint_token"
android:inputType="textPassword"
android:textColor="@color/white"
android:textColorHint="@color/light_blue" />
<Button
android:id="@+id/btn_save"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="24dp"
android:text="@string/btn_save" />
</LinearLayout>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="deep_blue">#0B1220</color>
<color name="white">#FFFFFF</color>
<color name="light_blue">#B7C8E8</color>
</resources>
+16
View File
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">DSHWatch Phone</string>
<string name="status_disconnected">未连接(空壳)</string>
<string name="btn_refresh">刷新状态</string>
<string name="btn_settings">设置</string>
<string name="settings_title">设置</string>
<string name="label_server">服务器地址</string>
<string name="hint_server">ws://host:port</string>
<string name="label_user">用户ID</string>
<string name="hint_user">userId</string>
<string name="label_token">Token</string>
<string name="hint_token">token</string>
<string name="btn_save">保存(空壳)</string>
<string name="shell_hint">空壳 UI:后续接入 DSHWatch_Server + 小米穿戴 SDK(BLE 网关)。</string>
</resources>
+9
View File
@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="Theme.DSHWatch" parent="Theme.MaterialComponents.DayNight.NoActionBar">
<item name="colorPrimary">#33B4FF</item>
<item name="colorPrimaryDark">#0B1220</item>
<item name="colorAccent">#33B4FF</item>
<item name="android:windowBackground">@color/deep_blue</item>
</style>
</resources>