diff --git a/app/src/main/java/com/dshwatch/app/MainActivity.java b/app/src/main/java/com/dshwatch/app/MainActivity.java
index 115a25e..60d7176 100644
--- a/app/src/main/java/com/dshwatch/app/MainActivity.java
+++ b/app/src/main/java/com/dshwatch/app/MainActivity.java
@@ -1,12 +1,19 @@
package com.dshwatch.app;
+import android.annotation.SuppressLint;
import android.content.Intent;
import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
import android.view.View;
-import android.widget.Button;
+import android.webkit.WebSettings;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
import android.widget.TextView;
+import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
+import androidx.appcompat.widget.Toolbar;
import org.json.JSONArray;
import org.json.JSONObject;
@@ -14,24 +21,45 @@ import org.json.JSONObject;
public class MainActivity extends AppCompatActivity {
private TextView status;
- private TextView balanceView;
+ private WebView webView;
+ private View emptyHint;
private ServerClient serverClient;
private WatchBridge watchBridge;
private boolean balancePending = false;
+ @SuppressLint("SetJavaScriptEnabled")
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ Toolbar toolbar = findViewById(R.id.toolbar);
+ setSupportActionBar(toolbar);
status = findViewById(R.id.status_text);
- balanceView = findViewById(R.id.balance_text);
+ webView = findViewById(R.id.webview);
+ emptyHint = findViewById(R.id.empty_hint);
- // 服务器客户端
+ // WebView:加载 Harness 网页壳(框子常驻,数据由插件/网关填入)
+ WebSettings ws = webView.getSettings();
+ ws.setJavaScriptEnabled(true);
+ ws.setDomStorageEnabled(true);
+ ws.setCacheMode(WebSettings.LOAD_DEFAULT);
+ ws.setAllowFileAccess(true);
+ ws.setMediaPlaybackRequiresUserGesture(false);
+ webView.setWebViewClient(new WebViewClient() {
+ @Override
+ public void onPageFinished(WebView view, String url) {
+ emptyHint.setVisibility(View.GONE);
+ }
+ });
+
+ loadWeb();
+
+ // 服务器客户端:连 Harness 插件(把 Harness 数据串过来的通道)
serverClient = new ServerClient(new ServerClient.Listener() {
@Override
public void onConnectionChanged(boolean connected) {
- runOnUiThread(() -> status.setText(connected ? "服务器已连接" : "服务器断开"));
+ runOnUiThread(() -> status.setText(connected ? "已连接 Harness" : "未连接 Harness"));
}
@Override
@@ -73,10 +101,7 @@ public class MainActivity extends AppCompatActivity {
double total = (infos != null && infos.length() > 0 && infos.optJSONObject(0) != null)
? infos.optJSONObject(0).optDouble("total_balance", 0.0) : 0.0;
String balance = String.format("%.2f", total);
- runOnUiThread(() -> {
- status.setText("余额 ¥ " + balance);
- balanceView.setText("DeepSeek 余额 ¥" + balance);
- });
+ runOnUiThread(() -> status.setText("DeepSeek 余额 ¥" + balance));
JSONObject payload = new JSONObject();
try { payload.put("balance", balance); } catch (Exception e) {}
JSONObject msg = new JSONObject();
@@ -93,7 +118,7 @@ public class MainActivity extends AppCompatActivity {
}
});
- // 手表互联桥
+ // 手表互联桥(BLE 网关,后续完善“手机连接手表”)
watchBridge = new WatchBridge(this, new WatchBridge.Listener() {
@Override
public void onWatchConnected(boolean connected, String nodeId) {
@@ -134,51 +159,66 @@ public class MainActivity extends AppCompatActivity {
runOnUiThread(() -> status.setText("WatchBridge: " + message));
}
});
+ }
- 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));
- }
- });
+ private void loadWeb() {
+ String url = SettingsStore.webUrl(this);
+ if (url == null || url.trim().isEmpty()) {
+ emptyHint.setVisibility(View.VISIBLE);
+ return;
+ }
+ emptyHint.setVisibility(View.GONE);
+ webView.loadUrl(url.trim());
+ }
- Button sessions = findViewById(R.id.btn_sessions);
- sessions.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(MainActivity.this, SessionListActivity.class));
- }
- });
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ getMenuInflater().inflate(R.menu.menu_main, menu);
+ return true;
+ }
- Button events = findViewById(R.id.btn_events);
- events.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(MainActivity.this, EventLogActivity.class));
- }
- });
+ @Override
+ public boolean onOptionsItemSelected(MenuItem item) {
+ int id = item.getItemId();
+ if (id == R.id.action_refresh) {
+ status.setText("连接中...");
+ String serverUrl = SettingsStore.serverUrl(this);
+ String userId = SettingsStore.userId(this);
+ String token = SettingsStore.token(this);
+ serverClient.connect(serverUrl, userId, token);
+ watchBridge.connect();
+ loadWeb();
+ return true;
+ } else if (id == R.id.action_watch) {
+ watchBridge.connect();
+ Toast.makeText(this, "正在连接手表…", Toast.LENGTH_SHORT).show();
+ return true;
+ } else if (id == R.id.action_hermes) {
+ Toast.makeText(this, "Hermès 链接(待接入)", Toast.LENGTH_SHORT).show();
+ return true;
+ } else if (id == R.id.action_sessions) {
+ startActivity(new Intent(this, SessionListActivity.class));
+ return true;
+ } else if (id == R.id.action_events) {
+ startActivity(new Intent(this, EventLogActivity.class));
+ return true;
+ } else if (id == R.id.action_command) {
+ startActivity(new Intent(this, CommandActivity.class));
+ return true;
+ } else if (id == R.id.action_settings) {
+ startActivity(new Intent(this, SettingsActivity.class));
+ return true;
+ }
+ return super.onOptionsItemSelected(item);
+ }
- Button command = findViewById(R.id.btn_command);
- command.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- startActivity(new Intent(MainActivity.this, CommandActivity.class));
- }
- });
-
- Button refresh = findViewById(R.id.btn_refresh);
- refresh.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- status.setText("连接中...");
- String serverUrl = SettingsStore.serverUrl(MainActivity.this);
- String userId = SettingsStore.userId(MainActivity.this);
- String token = SettingsStore.token(MainActivity.this);
- serverClient.connect(serverUrl, userId, token);
- watchBridge.connect();
- }
- });
+ @Override
+ public void onBackPressed() {
+ if (webView != null && webView.canGoBack()) {
+ webView.goBack();
+ } else {
+ super.onBackPressed();
+ }
}
@Override
diff --git a/app/src/main/java/com/dshwatch/app/SettingsActivity.java b/app/src/main/java/com/dshwatch/app/SettingsActivity.java
index 0391cca..879cbf3 100644
--- a/app/src/main/java/com/dshwatch/app/SettingsActivity.java
+++ b/app/src/main/java/com/dshwatch/app/SettingsActivity.java
@@ -4,6 +4,7 @@ import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
+import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
@@ -13,6 +14,10 @@ public class SettingsActivity extends AppCompatActivity {
private EditText serverUrl;
private EditText userId;
private EditText token;
+ private EditText web;
+ private TextView watchStatus;
+ private TextView hermesStatus;
+ private WatchBridge watchBridge;
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -22,6 +27,14 @@ public class SettingsActivity extends AppCompatActivity {
serverUrl = findViewById(R.id.input_server);
userId = findViewById(R.id.input_user);
token = findViewById(R.id.input_token);
+ web = findViewById(R.id.input_web);
+ watchStatus = findViewById(R.id.watch_status);
+ hermesStatus = findViewById(R.id.hermes_status);
+
+ serverUrl.setText(SettingsStore.serverUrl(this));
+ userId.setText(SettingsStore.userId(this));
+ token.setText(SettingsStore.token(this));
+ web.setText(SettingsStore.webUrl(this));
Button save = findViewById(R.id.btn_save);
save.setOnClickListener(new View.OnClickListener() {
@@ -32,8 +45,44 @@ public class SettingsActivity extends AppCompatActivity {
serverUrl.getText().toString().trim(),
userId.getText().toString().trim(),
token.getText().toString().trim());
+ SettingsStore.saveWebUrl(SettingsActivity.this, web.getText().toString().trim());
Toast.makeText(SettingsActivity.this, "已保存", Toast.LENGTH_SHORT).show();
}
});
+
+ Button watchConnect = findViewById(R.id.btn_watch_connect);
+ watchConnect.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ watchStatus.setText("正在连接手表…");
+ watchBridge = new WatchBridge(SettingsActivity.this, new WatchBridge.Listener() {
+ @Override
+ public void onWatchConnected(boolean connected, String nodeId) {
+ runOnUiThread(() -> watchStatus.setText(connected ? "已连接: " + nodeId : "未找到手表"));
+ }
+ @Override
+ public void onWatchMessage(String json) { }
+ @Override
+ public void onError(String message) {
+ runOnUiThread(() -> watchStatus.setText("错误: " + message));
+ }
+ });
+ watchBridge.connect();
+ }
+ });
+
+ Button hermes = findViewById(R.id.btn_hermes);
+ hermes.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ hermesStatus.setText("Hermès 链接(待接入)");
+ Toast.makeText(SettingsActivity.this, "Hermès 链接待接入", Toast.LENGTH_SHORT).show();
+ }
+ });
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
}
}
diff --git a/app/src/main/java/com/dshwatch/app/SettingsStore.java b/app/src/main/java/com/dshwatch/app/SettingsStore.java
index 8451bae..35ec36c 100644
--- a/app/src/main/java/com/dshwatch/app/SettingsStore.java
+++ b/app/src/main/java/com/dshwatch/app/SettingsStore.java
@@ -8,6 +8,7 @@ public class SettingsStore {
private static final String KEY_SERVER = "serverUrl";
private static final String KEY_USER = "userId";
private static final String KEY_TOKEN = "token";
+ private static final String KEY_WEB = "webUrl";
public static void save(Context c, String serverUrl, String userId, String token) {
SharedPreferences p = c.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
@@ -29,4 +30,12 @@ public class SettingsStore {
public static String token(Context c) {
return c.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString(KEY_TOKEN, "change-me");
}
+
+ public static String webUrl(Context c) {
+ return c.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString(KEY_WEB, "http://10.0.2.2:43120");
+ }
+
+ public static void saveWebUrl(Context c, String url) {
+ c.getSharedPreferences(PREFS, Context.MODE_PRIVATE).edit().putString(KEY_WEB, url == null ? "" : url).apply();
+ }
}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 4042bce..469d97b 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -1,79 +1,51 @@
-
-
-
+ android:layout_height="?attr/actionBarSize"
+ android:background="@android:color/transparent"
+ app:title="DeepSeek Harness"
+ app:titleTextColor="@color/white"
+ app:titleTextAppearance="@style/TextAppearance.MaterialComponents.Headline6">
-
+
-
+
-
+ android:layout_height="0dp"
+ android:layout_weight="1">
-
+
-
-
-
-
-
+
+
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
index 90984e6..7941774 100644
--- a/app/src/main/res/layout/activity_settings.xml
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -60,6 +60,75 @@
android:textColor="@color/white"
android:textColorHint="@color/light_blue" />
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+