feat: phone client as WebView shell of Harness web app + settings (webUrl / watch link / Hermes); menu
This commit is contained in:
@@ -1,12 +1,19 @@
|
|||||||
package com.dshwatch.app;
|
package com.dshwatch.app;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.view.Menu;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
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.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
|
import androidx.appcompat.widget.Toolbar;
|
||||||
|
|
||||||
import org.json.JSONArray;
|
import org.json.JSONArray;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
@@ -14,24 +21,45 @@ import org.json.JSONObject;
|
|||||||
public class MainActivity extends AppCompatActivity {
|
public class MainActivity extends AppCompatActivity {
|
||||||
|
|
||||||
private TextView status;
|
private TextView status;
|
||||||
private TextView balanceView;
|
private WebView webView;
|
||||||
|
private View emptyHint;
|
||||||
private ServerClient serverClient;
|
private ServerClient serverClient;
|
||||||
private WatchBridge watchBridge;
|
private WatchBridge watchBridge;
|
||||||
private boolean balancePending = false;
|
private boolean balancePending = false;
|
||||||
|
|
||||||
|
@SuppressLint("SetJavaScriptEnabled")
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.activity_main);
|
setContentView(R.layout.activity_main);
|
||||||
|
|
||||||
|
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||||
|
setSupportActionBar(toolbar);
|
||||||
status = findViewById(R.id.status_text);
|
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() {
|
serverClient = new ServerClient(new ServerClient.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onConnectionChanged(boolean connected) {
|
public void onConnectionChanged(boolean connected) {
|
||||||
runOnUiThread(() -> status.setText(connected ? "服务器已连接" : "服务器断开"));
|
runOnUiThread(() -> status.setText(connected ? "已连接 Harness" : "未连接 Harness"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -73,10 +101,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
double total = (infos != null && infos.length() > 0 && infos.optJSONObject(0) != null)
|
double total = (infos != null && infos.length() > 0 && infos.optJSONObject(0) != null)
|
||||||
? infos.optJSONObject(0).optDouble("total_balance", 0.0) : 0.0;
|
? infos.optJSONObject(0).optDouble("total_balance", 0.0) : 0.0;
|
||||||
String balance = String.format("%.2f", total);
|
String balance = String.format("%.2f", total);
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> status.setText("DeepSeek 余额 ¥" + balance));
|
||||||
status.setText("余额 ¥ " + balance);
|
|
||||||
balanceView.setText("DeepSeek 余额 ¥" + balance);
|
|
||||||
});
|
|
||||||
JSONObject payload = new JSONObject();
|
JSONObject payload = new JSONObject();
|
||||||
try { payload.put("balance", balance); } catch (Exception e) {}
|
try { payload.put("balance", balance); } catch (Exception e) {}
|
||||||
JSONObject msg = new JSONObject();
|
JSONObject msg = new JSONObject();
|
||||||
@@ -93,7 +118,7 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 手表互联桥
|
// 手表互联桥(BLE 网关,后续完善“手机连接手表”)
|
||||||
watchBridge = new WatchBridge(this, new WatchBridge.Listener() {
|
watchBridge = new WatchBridge(this, new WatchBridge.Listener() {
|
||||||
@Override
|
@Override
|
||||||
public void onWatchConnected(boolean connected, String nodeId) {
|
public void onWatchConnected(boolean connected, String nodeId) {
|
||||||
@@ -134,51 +159,66 @@ public class MainActivity extends AppCompatActivity {
|
|||||||
runOnUiThread(() -> status.setText("WatchBridge: " + message));
|
runOnUiThread(() -> status.setText("WatchBridge: " + message));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Button settings = findViewById(R.id.btn_settings);
|
private void loadWeb() {
|
||||||
settings.setOnClickListener(new View.OnClickListener() {
|
String url = SettingsStore.webUrl(this);
|
||||||
@Override
|
if (url == null || url.trim().isEmpty()) {
|
||||||
public void onClick(View v) {
|
emptyHint.setVisibility(View.VISIBLE);
|
||||||
startActivity(new Intent(MainActivity.this, SettingsActivity.class));
|
return;
|
||||||
}
|
}
|
||||||
});
|
emptyHint.setVisibility(View.GONE);
|
||||||
|
webView.loadUrl(url.trim());
|
||||||
|
}
|
||||||
|
|
||||||
Button sessions = findViewById(R.id.btn_sessions);
|
@Override
|
||||||
sessions.setOnClickListener(new View.OnClickListener() {
|
public boolean onCreateOptionsMenu(Menu menu) {
|
||||||
@Override
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||||
public void onClick(View v) {
|
return true;
|
||||||
startActivity(new Intent(MainActivity.this, SessionListActivity.class));
|
}
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Button events = findViewById(R.id.btn_events);
|
@Override
|
||||||
events.setOnClickListener(new View.OnClickListener() {
|
public boolean onOptionsItemSelected(MenuItem item) {
|
||||||
@Override
|
int id = item.getItemId();
|
||||||
public void onClick(View v) {
|
if (id == R.id.action_refresh) {
|
||||||
startActivity(new Intent(MainActivity.this, EventLogActivity.class));
|
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);
|
@Override
|
||||||
command.setOnClickListener(new View.OnClickListener() {
|
public void onBackPressed() {
|
||||||
@Override
|
if (webView != null && webView.canGoBack()) {
|
||||||
public void onClick(View v) {
|
webView.goBack();
|
||||||
startActivity(new Intent(MainActivity.this, CommandActivity.class));
|
} else {
|
||||||
}
|
super.onBackPressed();
|
||||||
});
|
}
|
||||||
|
|
||||||
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
|
@Override
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import android.os.Bundle;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.EditText;
|
import android.widget.EditText;
|
||||||
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
import androidx.appcompat.app.AppCompatActivity;
|
import androidx.appcompat.app.AppCompatActivity;
|
||||||
@@ -13,6 +14,10 @@ public class SettingsActivity extends AppCompatActivity {
|
|||||||
private EditText serverUrl;
|
private EditText serverUrl;
|
||||||
private EditText userId;
|
private EditText userId;
|
||||||
private EditText token;
|
private EditText token;
|
||||||
|
private EditText web;
|
||||||
|
private TextView watchStatus;
|
||||||
|
private TextView hermesStatus;
|
||||||
|
private WatchBridge watchBridge;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
@@ -22,6 +27,14 @@ public class SettingsActivity extends AppCompatActivity {
|
|||||||
serverUrl = findViewById(R.id.input_server);
|
serverUrl = findViewById(R.id.input_server);
|
||||||
userId = findViewById(R.id.input_user);
|
userId = findViewById(R.id.input_user);
|
||||||
token = findViewById(R.id.input_token);
|
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);
|
Button save = findViewById(R.id.btn_save);
|
||||||
save.setOnClickListener(new View.OnClickListener() {
|
save.setOnClickListener(new View.OnClickListener() {
|
||||||
@@ -32,8 +45,44 @@ public class SettingsActivity extends AppCompatActivity {
|
|||||||
serverUrl.getText().toString().trim(),
|
serverUrl.getText().toString().trim(),
|
||||||
userId.getText().toString().trim(),
|
userId.getText().toString().trim(),
|
||||||
token.getText().toString().trim());
|
token.getText().toString().trim());
|
||||||
|
SettingsStore.saveWebUrl(SettingsActivity.this, web.getText().toString().trim());
|
||||||
Toast.makeText(SettingsActivity.this, "已保存", Toast.LENGTH_SHORT).show();
|
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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public class SettingsStore {
|
|||||||
private static final String KEY_SERVER = "serverUrl";
|
private static final String KEY_SERVER = "serverUrl";
|
||||||
private static final String KEY_USER = "userId";
|
private static final String KEY_USER = "userId";
|
||||||
private static final String KEY_TOKEN = "token";
|
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) {
|
public static void save(Context c, String serverUrl, String userId, String token) {
|
||||||
SharedPreferences p = c.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
|
SharedPreferences p = c.getSharedPreferences(PREFS, Context.MODE_PRIVATE);
|
||||||
@@ -29,4 +30,12 @@ public class SettingsStore {
|
|||||||
public static String token(Context c) {
|
public static String token(Context c) {
|
||||||
return c.getSharedPreferences(PREFS, Context.MODE_PRIVATE).getString(KEY_TOKEN, "change-me");
|
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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,79 +1,51 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:padding="24dp"
|
|
||||||
android:background="@color/deep_blue">
|
android:background="@color/deep_blue">
|
||||||
|
|
||||||
<TextView
|
<com.google.android.material.appbar.MaterialToolbar
|
||||||
android:id="@+id/title"
|
android:id="@+id/toolbar"
|
||||||
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_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="?attr/actionBarSize"
|
||||||
android:layout_marginTop="24dp"
|
android:background="@android:color/transparent"
|
||||||
android:text="@string/status_disconnected"
|
app:title="DeepSeek Harness"
|
||||||
android:textColor="@color/white"
|
app:titleTextColor="@color/white"
|
||||||
android:textSize="16sp" />
|
app:titleTextAppearance="@style/TextAppearance.MaterialComponents.Headline6">
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/balance_text"
|
android:id="@+id/status_text"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_gravity="end"
|
||||||
android:text="DeepSeek 余额 ¥--"
|
android:paddingEnd="16dp"
|
||||||
android:textColor="#33B4FF"
|
android:text="未连接"
|
||||||
android:textSize="28sp"
|
android:textColor="@color/light_blue"
|
||||||
android:textStyle="bold" />
|
android:textSize="13sp" />
|
||||||
|
|
||||||
<Button
|
</com.google.android.material.appbar.MaterialToolbar>
|
||||||
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
|
<FrameLayout
|
||||||
android:id="@+id/btn_settings"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:layout_marginTop="12dp"
|
android:layout_weight="1">
|
||||||
android:text="@string/btn_settings" />
|
|
||||||
|
|
||||||
<Button
|
<WebView
|
||||||
android:id="@+id/btn_sessions"
|
android:id="@+id/webview"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent" />
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:text="@string/btn_sessions" />
|
|
||||||
|
|
||||||
<Button
|
<TextView
|
||||||
android:id="@+id/btn_events"
|
android:id="@+id/empty_hint"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_marginTop="12dp"
|
android:gravity="center"
|
||||||
android:text="@string/btn_events" />
|
android:padding="24dp"
|
||||||
|
android:text="请在设置中填写 Harness 网页地址\n(例如 http://10.0.2.2:43120)\n\n点右上角设置可配置"
|
||||||
<Button
|
android:textColor="@color/light_blue"
|
||||||
android:id="@+id/btn_command"
|
android:textSize="15sp"
|
||||||
android:layout_width="match_parent"
|
android:visibility="gone" />
|
||||||
android:layout_height="wrap_content"
|
</FrameLayout>
|
||||||
android:layout_marginTop="12dp"
|
|
||||||
android:text="@string/btn_command" />
|
|
||||||
|
|
||||||
<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>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -60,6 +60,75 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textColorHint="@color/light_blue" />
|
android:textColorHint="@color/light_blue" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="Harness 网页地址(串流壳,如 http://10.0.2.2:43120)"
|
||||||
|
android:textColor="@color/light_blue" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/input_web"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="http://10.0.2.2:43120"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textColorHint="@color/light_blue" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="链接"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="12dp"
|
||||||
|
android:text="⌚ 手表链接"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/watch_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="未连接"
|
||||||
|
android:textColor="@color/light_blue"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_watch_connect"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="连接手表" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="16dp"
|
||||||
|
android:text="🔗 Hermès 链接"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/hermes_status"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="未配置"
|
||||||
|
android:textColor="@color/light_blue"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/btn_hermes"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="连接 Hermès" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/btn_save"
|
android:id="@+id/btn_save"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<item android:id="@+id/action_refresh" android:title="刷新" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_watch" android:title="手表链接" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_hermes" android:title="Hermès 链接" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_sessions" android:title="会话列表" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_events" android:title="事件流" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_command" android:title="命令" app:showAsAction="never" />
|
||||||
|
<item android:id="@+id/action_settings" android:title="设置" app:showAsAction="always" />
|
||||||
|
</menu>
|
||||||
Reference in New Issue
Block a user