feat: add phone CommandActivity (send session.prompt + stream events)
This commit is contained in:
@@ -22,5 +22,8 @@
|
||||
<activity
|
||||
android:name=".EventLogActivity"
|
||||
android:exported="false" />
|
||||
<activity
|
||||
android:name=".CommandActivity"
|
||||
android:exported="false" />
|
||||
</application>
|
||||
</manifest>
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
package com.dshwatch.app;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 命令/聊天页:发送 session.prompt 并流式展示 status/event 回显。
|
||||
* 这是远程控制 Harness 的核心入口。
|
||||
*/
|
||||
public class CommandActivity extends AppCompatActivity {
|
||||
|
||||
private EditText input;
|
||||
private ArrayAdapter<String> adapter;
|
||||
private ServerClient client;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_command);
|
||||
|
||||
input = findViewById(R.id.command_input);
|
||||
ListView list = findViewById(R.id.command_log);
|
||||
List<String> data = new ArrayList<>();
|
||||
adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, data);
|
||||
list.setAdapter(adapter);
|
||||
|
||||
client = new ServerClient(new ServerClient.Listener() {
|
||||
@Override
|
||||
public void onConnectionChanged(boolean connected) {
|
||||
runOnUiThread(() -> adapter.add(connected ? "[已连接]" : "[连接断开]"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHello(JSONObject hello) {
|
||||
// connected
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatus(JSONObject status) {
|
||||
runOnUiThread(() -> adapter.add("[status] " + status.optString("model") + " running=" + status.optBoolean("running")));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onEvent(JSONObject event) {
|
||||
runOnUiThread(() -> {
|
||||
adapter.add("[event] " + event.toString());
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResponse(String requestId, boolean ok, JSONObject result, JSONObject error) {
|
||||
runOnUiThread(() -> {
|
||||
adapter.add(ok ? ("[响应] " + (result != null ? result.toString() : "ok")) : ("[错误] " + (error != null ? error.optString("message") : "unknown")));
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(String message) {
|
||||
runOnUiThread(() -> {
|
||||
adapter.add("[错误] " + message);
|
||||
adapter.notifyDataSetChanged();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
client.connect(
|
||||
SettingsStore.serverUrl(CommandActivity.this),
|
||||
SettingsStore.userId(CommandActivity.this),
|
||||
SettingsStore.token(CommandActivity.this));
|
||||
|
||||
Button send = findViewById(R.id.command_send);
|
||||
send.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
String text = input.getText().toString().trim();
|
||||
if (text.isEmpty()) return;
|
||||
JSONObject params = new JSONObject();
|
||||
try {
|
||||
params.put("content", text);
|
||||
} catch (Exception e) { }
|
||||
client.sendRequest("session.prompt", params);
|
||||
input.setText("");
|
||||
}
|
||||
});
|
||||
|
||||
Button cancel = findViewById(R.id.command_cancel);
|
||||
cancel.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
JSONObject params = new JSONObject();
|
||||
try { params.put("sessionId", JSONObject.NULL); } catch (Exception e) { }
|
||||
client.sendRequest("session.cancel", params);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy() {
|
||||
super.onDestroy();
|
||||
if (client != null) client.close();
|
||||
}
|
||||
}
|
||||
@@ -117,6 +117,14 @@ public class MainActivity extends AppCompatActivity {
|
||||
}
|
||||
});
|
||||
|
||||
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
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
<?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="16dp"
|
||||
android:background="@color/deep_blue">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="命令 / 聊天"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<EditText
|
||||
android:id="@+id/command_input"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:hint="输入要发给 DeepSeek 的指令..."
|
||||
android:textColor="@color/white"
|
||||
android:textColorHint="@color/light_blue" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp">
|
||||
<Button
|
||||
android:id="@+id/command_send"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="发送" />
|
||||
<Button
|
||||
android:id="@+id/command_cancel"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginStart="8dp"
|
||||
android:text="取消" />
|
||||
</LinearLayout>
|
||||
|
||||
<ListView
|
||||
android:id="@+id/command_log"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:layout_marginTop="12dp"
|
||||
android:divider="@color/light_blue"
|
||||
android:dividerHeight="1dp" />
|
||||
</LinearLayout>
|
||||
@@ -52,6 +52,13 @@
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/btn_events" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_command"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/btn_command" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
<string name="btn_settings">设置</string>
|
||||
<string name="btn_sessions">会话列表</string>
|
||||
<string name="btn_events">事件流</string>
|
||||
<string name="btn_command">命令</string>
|
||||
<string name="settings_title">设置</string>
|
||||
<string name="label_server">服务器地址</string>
|
||||
<string name="hint_server">ws://host:port</string>
|
||||
|
||||
Reference in New Issue
Block a user