diff --git a/.eslintignore b/.eslintignore
deleted file mode 100644
index dc1a78f..0000000
--- a/.eslintignore
+++ /dev/null
@@ -1,7 +0,0 @@
-/.nyc_output
-/coverage
-/node_modules
-/tests/fixtures
-/sign
-/dist
-/build
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 3d1760d..c61557c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,16 +1,10 @@
-node_modules
-build
-dist
-
-.DS_Store
-Thumbs.db
-
-*.log
-*.iml
+.gradle/
+build/
+local.properties
.idea/
-.vscode/
-
-.nyc_output
-/coverage
-
-/logs
+*.iml
+.DS_Store
+*.log
+captures/
+.externalNativeBuild/
+.cxx/
diff --git a/README.md b/README.md
index f859aa2..f734b54 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,26 @@
-## 快速上手
+# DSHWatchPhone(手机端 / 原生 Android)
-您可通过运行 `npm run start` 后,使用快应用引擎扫描二维码快速开发。
+DSHWatch 手机客户端空壳。后续接入:
-## 了解更多
+- DSHWatch_Server(或 dsh-watch 插件直连)WebSocket。
+- 小米穿戴 SDK(Wearable / MessageApi)作为手表 BLE 互联对端。
+- 作为手表网关,把服务器状态/事件转发给 DSHWatch,并把手表指令转发回服务器。
-你可以通过我们的[官方文档](https://doc.quickapp.cn/)熟悉和了解快应用。
+## 当前为 UI 空壳
-可以通过我们[快应用官方示例项目](https://github.com/quickappcn/sample),快速掌握
-api 和组件的用法
+- MainActivity:状态页(刷新 / 设置入口)。
+- SettingsActivity:服务器地址 / userId / token 表单。
+- WatchBridge.java / ServerClient.java:占位接口,未接入 SDK。
-对我们有什么意见,建议或者 bug,可以在这里反馈
-https://github.com/quickappcn/issues
+## 构建
+
+用 Android Studio 打开本目录(Gradle 会拉取 AGP + AndroidX)。
+
+- compileSdk 34 / minSdk 26 / targetSdk 34
+- Java 17
+
+## 后续接入小米穿戴 SDK
+
+- 从官方 demo(open-vela packages_apps / interconnect_image_demo 的 android_program)拿 libs/。
+- 包名与签名需与 DSHWatch(手表 rpk)一致:com.dshwatch.app。
+- 在 ServerClient 里接 WebSocket,在 WatchBridge 里接 MessageApi。
diff --git a/app/build.gradle b/app/build.gradle
new file mode 100644
index 0000000..313b7e4
--- /dev/null
+++ b/app/build.gradle
@@ -0,0 +1,29 @@
+plugins {
+ id 'com.android.application'
+}
+android {
+ namespace 'com.dshwatch.app'
+ compileSdk 34
+ defaultConfig {
+ applicationId "com.dshwatch.app"
+ minSdk 26
+ targetSdk 34
+ versionCode 1
+ versionName "0.1.0"
+ }
+ buildTypes {
+ release {
+ minifyEnabled false
+ proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
+ }
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_17
+ targetCompatibility JavaVersion.VERSION_17
+ }
+}
+dependencies {
+ implementation 'androidx.appcompat:appcompat:1.6.1'
+ implementation 'com.google.android.material:material:1.9.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
+}
diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro
new file mode 100644
index 0000000..fb164d6
--- /dev/null
+++ b/app/proguard-rules.pro
@@ -0,0 +1 @@
+# Add project specific ProGuard rules here.
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..22e969d
--- /dev/null
+++ b/app/src/main/AndroidManifest.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/java/com/dshwatch/app/MainActivity.java b/app/src/main/java/com/dshwatch/app/MainActivity.java
new file mode 100644
index 0000000..b617f26
--- /dev/null
+++ b/app/src/main/java/com/dshwatch/app/MainActivity.java
@@ -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);
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/dshwatch/app/ServerClient.java b/app/src/main/java/com/dshwatch/app/ServerClient.java
new file mode 100644
index 0000000..f6fd63e
--- /dev/null
+++ b/app/src/main/java/com/dshwatch/app/ServerClient.java
@@ -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);
+ }
+}
diff --git a/app/src/main/java/com/dshwatch/app/SettingsActivity.java b/app/src/main/java/com/dshwatch/app/SettingsActivity.java
new file mode 100644
index 0000000..d0303d2
--- /dev/null
+++ b/app/src/main/java/com/dshwatch/app/SettingsActivity.java
@@ -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();
+ }
+ });
+ }
+}
diff --git a/app/src/main/java/com/dshwatch/app/WatchBridge.java b/app/src/main/java/com/dshwatch/app/WatchBridge.java
new file mode 100644
index 0000000..11ec0b8
--- /dev/null
+++ b/app/src/main/java/com/dshwatch/app/WatchBridge.java
@@ -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);
+}
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
new file mode 100644
index 0000000..bb73b9f
--- /dev/null
+++ b/app/src/main/res/layout/activity_main.xml
@@ -0,0 +1,48 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_settings.xml b/app/src/main/res/layout/activity_settings.xml
new file mode 100644
index 0000000..90984e6
--- /dev/null
+++ b/app/src/main/res/layout/activity_settings.xml
@@ -0,0 +1,69 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml
new file mode 100644
index 0000000..70c2f4e
--- /dev/null
+++ b/app/src/main/res/values/colors.xml
@@ -0,0 +1,6 @@
+
+
+ #0B1220
+ #FFFFFF
+ #B7C8E8
+
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
new file mode 100644
index 0000000..658405b
--- /dev/null
+++ b/app/src/main/res/values/strings.xml
@@ -0,0 +1,16 @@
+
+
+ DSHWatch Phone
+ 未连接(空壳)
+ 刷新状态
+ 设置
+ 设置
+ 服务器地址
+ ws://host:port
+ 用户ID
+ userId
+ Token
+ token
+ 保存(空壳)
+ 空壳 UI:后续接入 DSHWatch_Server + 小米穿戴 SDK(BLE 网关)。
+
diff --git a/app/src/main/res/values/themes.xml b/app/src/main/res/values/themes.xml
new file mode 100644
index 0000000..1b6bf36
--- /dev/null
+++ b/app/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
diff --git a/build.gradle b/build.gradle
new file mode 100644
index 0000000..4897847
--- /dev/null
+++ b/build.gradle
@@ -0,0 +1,3 @@
+plugins {
+ id 'com.android.application' version '8.5.2' apply false
+}
diff --git a/gradle.properties b/gradle.properties
new file mode 100644
index 0000000..3c5e113
--- /dev/null
+++ b/gradle.properties
@@ -0,0 +1,2 @@
+org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
+android.useAndroidX=true
diff --git a/jsconfig.json b/jsconfig.json
deleted file mode 100644
index e69de29..0000000
diff --git a/package.json b/package.json
deleted file mode 100644
index e884377..0000000
--- a/package.json
+++ /dev/null
@@ -1,18 +0,0 @@
-{
- "name": "DSHWatchPhone",
- "version": "1.0.0",
- "description": "",
- "engines": {
- "node": ">=8.10"
- },
- "scripts": {
- "start": "aiot start --watch",
- "build": "aiot build",
- "release": "aiot release",
- "lint": "eslint --format codeframe --fix --ext .ux,.js src/"
- },
- "devDependencies": {
- "@aiot-toolkit/jsc": "^1.0.3",
- "aiot-toolkit": "^2.0.5"
- }
-}
\ No newline at end of file
diff --git a/settings.gradle b/settings.gradle
new file mode 100644
index 0000000..9063c3c
--- /dev/null
+++ b/settings.gradle
@@ -0,0 +1,16 @@
+pluginManagement {
+ repositories {
+ google()
+ mavenCentral()
+ gradlePluginPortal()
+ }
+}
+dependencyResolutionManagement {
+ repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
+ repositories {
+ google()
+ mavenCentral()
+ }
+}
+rootProject.name = "DSHWatchPhone"
+include ':app'
diff --git a/src/CardDemo/index.ux b/src/CardDemo/index.ux
deleted file mode 100644
index 7d0b3f5..0000000
--- a/src/CardDemo/index.ux
+++ /dev/null
@@ -1,24 +0,0 @@
-
-
-
- {{text}}
- {{des}}
-
-
-
-
-
-
diff --git a/src/Common/logo.png b/src/Common/logo.png
deleted file mode 100644
index b3c0fb0..0000000
Binary files a/src/Common/logo.png and /dev/null differ
diff --git a/src/Demo/index.ux b/src/Demo/index.ux
deleted file mode 100644
index dd018c4..0000000
--- a/src/Demo/index.ux
+++ /dev/null
@@ -1,48 +0,0 @@
-
-
-
- 欢迎打开{{title}}
-
-
-
-
-
-
-
-
diff --git a/src/DemoDetail/index.ux b/src/DemoDetail/index.ux
deleted file mode 100644
index ad9b3b2..0000000
--- a/src/DemoDetail/index.ux
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- {{text}}
-
-
-
-
-
-
diff --git a/src/app.ux b/src/app.ux
deleted file mode 100644
index b2c4fdf..0000000
--- a/src/app.ux
+++ /dev/null
@@ -1,14 +0,0 @@
-
diff --git a/src/config-phone.json b/src/config-phone.json
deleted file mode 100644
index 9e26dfe..0000000
--- a/src/config-phone.json
+++ /dev/null
@@ -1 +0,0 @@
-{}
\ No newline at end of file
diff --git a/src/global.js b/src/global.js
deleted file mode 100644
index da7ab8f..0000000
--- a/src/global.js
+++ /dev/null
@@ -1,34 +0,0 @@
-/**
- * @file 全局能力的配置与获取
- * 文档地址:https://doc.quickapp.cn/tutorial/framework/optimization-skills.html#%E4%BD%BF%E7%94%A8-globaljs
- */
-
-function getGlobalRef() {
- return Object.getPrototypeOf(global) || global
-}
-
-const quickappGlobal = getGlobalRef()
-
-/**
- * 设置全局(被APP与Page共享)数据;
- * @param key {string}
- * @param val {*}
- */
-function setGlobalData(key, val) {
- quickappGlobal[key] = val
-}
-
-/**
- * 获取全局(被APP与Page共享)数据;
- * @param key {string}
- * @return {*}
- */
-function getGlobalData(key) {
- return quickappGlobal[key]
-}
-
-// 两个方法默认定义在全局
-setGlobalData('setGlobalData', setGlobalData)
-setGlobalData('getGlobalData', getGlobalData)
-
-export { setGlobalData, getGlobalData }
diff --git a/src/manifest.json b/src/manifest.json
deleted file mode 100644
index f62afba..0000000
--- a/src/manifest.json
+++ /dev/null
@@ -1,66 +0,0 @@
-{
- "package": "com.application.demo",
- "name": "DSHWatchPhone",
- "versionName": "1.0.0",
- "versionCode": 1,
- "minPlatformVersion": 1070,
- "icon": "/Common/logo.png",
- "deviceTypeList": [
- "phone"
- ],
- "features": [
- {
- "name": "system.prompt"
- },
- {
- "name": "system.router"
- },
- {
- "name": "system.shortcut"
- }
- ],
- "permissions": [
- {
- "origin": "*"
- }
- ],
- "config": {
- "logLevel": "log"
- },
- "router": {
- "entry": "Demo",
- "pages": {
- "Demo": {
- "component": "index"
- },
- "DemoDetail": {
- "component": "index"
- }
- },
- "widgets": {
- "CardDemo": {
- "name": "CardDemo",
- "description": "快应用卡片展示",
- "component": "index",
- "path": "/CardDemo",
- "features": []
- }
- }
- },
- "display": {
- "titleBarBackgroundColor": "#f2f2f2",
- "titleBarTextColor": "#414141",
- "menu": false,
- "menuBarData": {
- "menuBar": true
- },
- "pages": {
- "Demo": {
- "titleBarText": "示例页"
- },
- "DemoDetail": {
- "titleBarText": "详情页"
- }
- }
- }
-}
\ No newline at end of file
diff --git a/src/sitemap.json b/src/sitemap.json
deleted file mode 100644
index 8d03ea3..0000000
--- a/src/sitemap.json
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "doc": "https://doc.quickapp.cn/framework/sitemap.html",
- "rules": [{ "rule": "enable", "page": "*" }]
-}