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"> - + -