aa
155
androidExampleDemo/(红头)项目编译Debug版本和Release版本apk的方法.txt
Normal file
@@ -0,0 +1,155 @@
|
||||
# Android 项目编译 Debug 和 Release 版本 APK 的方法
|
||||
|
||||
## 项目信息
|
||||
- **项目名称**: com.xunpaisoft.social
|
||||
- **项目路径**: D:\zhini\android-im
|
||||
- **JDK 要求**: Java 11 或更高版本
|
||||
- **推荐 JDK**: Android Studio 内置 JDK 21
|
||||
|
||||
## 环境准备
|
||||
|
||||
### 1. 检查 Java 版本
|
||||
```bash
|
||||
java -version
|
||||
```
|
||||
**注意**: 如果系统只有 Java 8,需要使用 Android Studio 的 JDK 21
|
||||
|
||||
### 2. 设置环境变量
|
||||
```powershell
|
||||
# 设置 Android Studio JDK 路径
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"
|
||||
|
||||
# 设置 Android SDK 路径
|
||||
$env:ANDROID_HOME="C:\Users\$env:USERNAME\AppData\Local\Android\Sdk"
|
||||
```
|
||||
|
||||
## 编译方法
|
||||
|
||||
### 方法一:使用 Gradle Wrapper(推荐)
|
||||
|
||||
#### 1. Debug 版本编译
|
||||
```bash
|
||||
# 设置环境变量并编译 Debug 版本
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"; $env:ANDROID_HOME="C:\Users\$env:USERNAME\AppData\Local\Android\Sdk"; .\gradlew.bat assembleDebug
|
||||
```
|
||||
|
||||
**编译结果**:
|
||||
- ✅ 编译状态: BUILD SUCCESSFUL
|
||||
- ⏱️ 编译时间: 约 34 秒
|
||||
- 📁 APK 位置: `app\build\outputs\apk\debug\app-debug.apk`
|
||||
|
||||
#### 2. Release 版本编译
|
||||
```bash
|
||||
# 设置环境变量并编译 Release 版本
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"; $env:ANDROID_HOME="C:\Users\$env:USERNAME\AppData\Local\Android\Sdk"; .\gradlew.bat assembleRelease
|
||||
```
|
||||
|
||||
**编译结果**:
|
||||
- ✅ 编译状态: BUILD SUCCESSFUL
|
||||
- ⏱️ 编译时间: 约 3分48秒
|
||||
- 📁 APK 位置: `app\build\outputs\apk\release\app-release.apk`
|
||||
|
||||
### 方法二:使用 Android Studio(最简单)
|
||||
|
||||
1. **打开 Android Studio**
|
||||
2. **导入项目**: 选择 `D:\zhini\android-im` 目录
|
||||
3. **等待 Gradle 同步完成**
|
||||
4. **编译项目**:
|
||||
- **Debug 版本**: `Build` → `Build Bundle(s) / APK(s)` → `Build APK(s)`
|
||||
- **Release 版本**: `Build` → `Generate Signed Bundle / APK` → `APK`
|
||||
|
||||
## 安装 APK 到设备
|
||||
|
||||
### 安装 Debug 版本
|
||||
```bash
|
||||
adb install -r app\build\outputs\apk\debug\app-debug.apk
|
||||
```
|
||||
|
||||
### 安装 Release 版本
|
||||
```bash
|
||||
adb install -r app\build\outputs\apk\release\app-release.apk
|
||||
```
|
||||
|
||||
## 版本对比
|
||||
|
||||
| 特性 | Debug 版本 | Release 版本 |
|
||||
|------|------------|--------------|
|
||||
| **编译时间** | 约 34 秒 | 约 3分48秒 |
|
||||
| **APK 大小** | 较大 | 较小(优化后) |
|
||||
| **代码混淆** | 否 | 是(ProGuard) |
|
||||
| **调试信息** | 包含 | 移除 |
|
||||
| **性能** | 较慢 | 较快 |
|
||||
| **用途** | 开发测试 | 正式发布 |
|
||||
|
||||
## 常见问题解决
|
||||
|
||||
### 问题1: Java 版本不兼容
|
||||
**错误信息**: `Dependency requires at least JVM runtime version 11. This build uses a Java 8 JVM.`
|
||||
|
||||
**解决方案**:
|
||||
```bash
|
||||
# 停止现有 Gradle daemon
|
||||
.\gradlew.bat --stop
|
||||
|
||||
# 使用 Android Studio JDK 编译
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"; .\gradlew.bat assembleDebug
|
||||
```
|
||||
|
||||
### 问题2: Gradle Wrapper 不存在
|
||||
**解决方案**: 项目已包含 `gradlew.bat` 文件,如果缺失可以重新创建。
|
||||
|
||||
### 问题3: 权限重复警告
|
||||
**现象**: 编译时出现权限重复警告
|
||||
**影响**: 不影响编译,但建议清理重复权限声明
|
||||
|
||||
## 编译命令总结
|
||||
|
||||
### 一键编译脚本
|
||||
```powershell
|
||||
# Debug 版本一键编译
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"; $env:ANDROID_HOME="C:\Users\$env:USERNAME\AppData\Local\Android\Sdk"; .\gradlew.bat assembleDebug
|
||||
|
||||
# Release 版本一键编译
|
||||
$env:JAVA_HOME="C:\Program Files\Android\Android Studio1\jbr"; $env:ANDROID_HOME="C:\Users\$env:USERNAME\AppData\Local\Android\Sdk"; .\gradlew.bat assembleRelease
|
||||
```
|
||||
|
||||
### 清理和重新编译
|
||||
```bash
|
||||
# 清理项目
|
||||
.\gradlew.bat clean
|
||||
|
||||
# 重新编译 Debug 版本
|
||||
.\gradlew.bat assembleDebug
|
||||
|
||||
# 重新编译 Release 版本
|
||||
.\gradlew.bat assembleRelease
|
||||
```
|
||||
|
||||
## 注意事项
|
||||
|
||||
1. **JDK 版本**: 必须使用 Java 11 或更高版本
|
||||
2. **环境变量**: 每次编译前需要设置正确的 JAVA_HOME
|
||||
3. **签名配置**: Release 版本需要配置签名文件
|
||||
4. **混淆规则**: Release 版本会应用 ProGuard 混淆规则
|
||||
5. **资源优化**: Release 版本会进行资源压缩和优化
|
||||
|
||||
## 文件位置
|
||||
|
||||
- **Debug APK**: `app\build\outputs\apk\debug\app-debug.apk`
|
||||
- **Release APK**: `app\build\outputs\apk\release\app-release.apk`
|
||||
- **Gradle Wrapper**: `gradlew.bat`
|
||||
- **构建配置**: `app\build.gradle`
|
||||
|
||||
## 成功标志
|
||||
|
||||
编译成功后会显示:
|
||||
```
|
||||
BUILD SUCCESSFUL in [时间]
|
||||
[数量] actionable tasks: [执行数量] executed, [跳过数量] up-to-date
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**最后更新**: 2025年10月29日
|
||||
**适用版本**: Android Gradle Plugin 8.7.3
|
||||
**JDK 版本**: Android Studio JDK 21
|
||||
15
androidExampleDemo/.gitignore
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
*.iml
|
||||
.gradle
|
||||
/local.properties
|
||||
/.idea/caches
|
||||
/.idea/libraries
|
||||
/.idea/modules.xml
|
||||
/.idea/workspace.xml
|
||||
/.idea/navEditor.xml
|
||||
/.idea/assetWizardSettings.xml
|
||||
.DS_Store
|
||||
/build
|
||||
/captures
|
||||
.externalNativeBuild
|
||||
.cxx
|
||||
local.properties
|
||||
230
androidExampleDemo/README.md
Normal file
@@ -0,0 +1,230 @@
|
||||
# Android Agent调用示例 (Java版本)
|
||||
|
||||
这是一个使用Java开发的Android示例项目,演示如何调用情感分析Agent。
|
||||
|
||||
## 📋 项目结构
|
||||
|
||||
```
|
||||
androidExampleDemo/
|
||||
├── app/
|
||||
│ ├── src/
|
||||
│ │ └── main/
|
||||
│ │ ├── java/com/example/agentclient/
|
||||
│ │ │ ├── MainActivity.java
|
||||
│ │ │ ├── models/
|
||||
│ │ │ │ ├── Agent.java
|
||||
│ │ │ │ ├── AgentExecutionRequest.java
|
||||
│ │ │ │ ├── ExecutionResponse.java
|
||||
│ │ │ │ ├── ExecutionStatusResponse.java
|
||||
│ │ │ │ └── TokenResponse.java
|
||||
│ │ │ └── utils/
|
||||
│ │ │ └── ApiClient.java
|
||||
│ │ ├── res/
|
||||
│ │ │ ├── layout/
|
||||
│ │ │ │ └── activity_main.xml
|
||||
│ │ │ ├── values/
|
||||
│ │ │ │ └── strings.xml
|
||||
│ │ │ └── xml/
|
||||
│ │ │ └── network_security_config.xml
|
||||
│ │ └── AndroidManifest.xml
|
||||
│ └── build.gradle
|
||||
├── build.gradle
|
||||
├── settings.gradle
|
||||
├── gradle.properties
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## 🚀 快速开始
|
||||
|
||||
### 1. 配置API地址
|
||||
|
||||
在 `app/src/main/java/com/example/agentclient/utils/ApiClient.java` 中修改:
|
||||
|
||||
```java
|
||||
private static final String BASE_URL = "http://your-server-ip:8037";
|
||||
```
|
||||
|
||||
### 2. 配置登录信息
|
||||
|
||||
在 `MainActivity.java` 中修改:
|
||||
|
||||
```java
|
||||
private static final String USERNAME = "admin";
|
||||
private static final String PASSWORD = "123456";
|
||||
private static final String AGENT_NAME = "情感分析Agent"; // Agent名称
|
||||
```
|
||||
|
||||
### 3. 运行项目
|
||||
|
||||
1. 使用Android Studio打开项目
|
||||
2. 同步Gradle依赖
|
||||
3. 运行到Android设备或模拟器
|
||||
|
||||
## 📱 功能特性
|
||||
|
||||
- ✅ 用户登录
|
||||
- ✅ 调用Agent API
|
||||
- ✅ 实时显示执行状态
|
||||
- ✅ 显示Agent回复
|
||||
- ✅ 错误处理
|
||||
|
||||
## 🔧 依赖库
|
||||
|
||||
- Retrofit2:网络请求
|
||||
- OkHttp:HTTP客户端
|
||||
- Gson:JSON解析
|
||||
- AndroidX:Android支持库
|
||||
|
||||
## 📝 使用说明
|
||||
|
||||
1. **登录**
|
||||
- 应用启动后会自动登录(使用配置的用户名和密码)
|
||||
- 登录成功后可以开始使用Agent
|
||||
|
||||
2. **发送消息**
|
||||
- 在输入框中输入文本
|
||||
- 点击"发送"按钮
|
||||
- 等待Agent处理并返回结果
|
||||
|
||||
3. **查看结果**
|
||||
- Agent的回复会显示在消息列表中
|
||||
- 执行状态会实时更新
|
||||
|
||||
## 🔑 API说明
|
||||
|
||||
### 登录API
|
||||
```
|
||||
POST /api/v1/auth/login
|
||||
Content-Type: application/x-www-form-urlencoded
|
||||
|
||||
username=admin&password=123456
|
||||
```
|
||||
|
||||
### 执行Agent API
|
||||
```
|
||||
POST /api/v1/executions
|
||||
Authorization: Bearer <token>
|
||||
Content-Type: application/json
|
||||
|
||||
{
|
||||
"agent_id": "agent-id",
|
||||
"input_data": {
|
||||
"query": "用户输入",
|
||||
"USER_INPUT": "用户输入"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 获取执行状态API
|
||||
```
|
||||
GET /api/v1/executions/{execution_id}/status
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
### 获取执行结果API
|
||||
```
|
||||
GET /api/v1/executions/{execution_id}
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
## 🎯 示例:调用情感分析Agent
|
||||
|
||||
```java
|
||||
// 1. 登录获取token
|
||||
Call<TokenResponse> loginCall = ApiClient.getService().login("admin", "123456");
|
||||
loginCall.enqueue(new Callback<TokenResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<TokenResponse> call, Response<TokenResponse> response) {
|
||||
if (response.isSuccessful()) {
|
||||
String token = "Bearer " + response.body().getAccessToken();
|
||||
|
||||
// 2. 通过名称查找Agent
|
||||
Call<List<Agent>> agentsCall = ApiClient.getService()
|
||||
.getAgents("情感分析Agent", 100, token);
|
||||
agentsCall.enqueue(new Callback<List<Agent>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<Agent>> call, Response<List<Agent>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
String agentId = response.body().get(0).getId();
|
||||
|
||||
// 3. 执行Agent
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("query", "这个产品真的很棒!");
|
||||
inputData.put("USER_INPUT", "这个产品真的很棒!");
|
||||
|
||||
AgentExecutionRequest request = new AgentExecutionRequest(agentId, inputData);
|
||||
Call<ExecutionResponse> execCall = ApiClient.getService()
|
||||
.executeAgent(request, token);
|
||||
execCall.enqueue(new Callback<ExecutionResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<ExecutionResponse> call,
|
||||
Response<ExecutionResponse> response) {
|
||||
if (response.isSuccessful()) {
|
||||
String executionId = response.body().getId();
|
||||
// 4. 轮询获取结果(见MainActivity.pollExecutionResult方法)
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ExecutionResponse> call, Throwable t) {
|
||||
// 处理错误
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<Agent>> call, Throwable t) {
|
||||
// 处理错误
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<TokenResponse> call, Throwable t) {
|
||||
// 处理错误
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
## 📦 构建要求
|
||||
|
||||
- Android Studio Hedgehog | 2023.1.1 或更高版本
|
||||
- JDK 17 或更高版本
|
||||
- Android SDK API 24 或更高版本
|
||||
- Gradle 8.0 或更高版本
|
||||
|
||||
## 💻 开发语言
|
||||
|
||||
- **Java 17** - 主要开发语言
|
||||
- 使用Retrofit进行网络请求
|
||||
- 使用Gson进行JSON解析
|
||||
|
||||
## 🔒 安全注意事项
|
||||
|
||||
1. **不要硬编码密码**:生产环境应该使用安全的认证方式
|
||||
2. **使用HTTPS**:生产环境必须使用HTTPS
|
||||
3. **Token管理**:妥善保管和刷新Token
|
||||
4. **网络安全配置**:Android 9+需要配置网络安全策略
|
||||
|
||||
## 🐛 故障排除
|
||||
|
||||
### 问题1:网络连接失败
|
||||
- 检查API地址是否正确
|
||||
- 检查设备网络连接
|
||||
- 检查服务器是否运行
|
||||
|
||||
### 问题2:登录失败
|
||||
- 检查用户名和密码是否正确
|
||||
- 检查服务器认证服务是否正常
|
||||
|
||||
### 问题3:Agent执行失败
|
||||
- 检查Agent ID是否正确
|
||||
- 检查Agent是否已发布
|
||||
- 查看服务器日志获取详细错误信息
|
||||
|
||||
## 📚 相关文档
|
||||
|
||||
- [Agent使用说明](../Agent使用说明.md)
|
||||
- [API文档](../backend/API_DOCUMENTATION.md)
|
||||
1
androidExampleDemo/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
58
androidExampleDemo/app/build.gradle
Normal file
@@ -0,0 +1,58 @@
|
||||
plugins {
|
||||
alias(libs.plugins.android.application)
|
||||
}
|
||||
|
||||
android {
|
||||
namespace 'com.example.agentclient'
|
||||
compileSdk 34
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.example.agentclient"
|
||||
minSdk 26
|
||||
targetSdk 34
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_17
|
||||
targetCompatibility JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
buildFeatures {
|
||||
viewBinding true
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
// Android Core
|
||||
implementation 'androidx.core:core:1.12.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||
implementation 'com.google.android.material:material:1.10.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
|
||||
implementation 'androidx.lifecycle:lifecycle-runtime:2.6.2'
|
||||
implementation 'androidx.activity:activity:1.8.1'
|
||||
|
||||
// Retrofit & OkHttp
|
||||
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
|
||||
implementation 'com.squareup.retrofit2:converter-gson:2.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'com.squareup.okhttp3:logging-interceptor:4.12.0'
|
||||
|
||||
// Gson
|
||||
implementation 'com.google.code.gson:gson:2.10.1'
|
||||
|
||||
// Testing
|
||||
testImplementation 'junit:junit:4.13.2'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||
}
|
||||
33
androidExampleDemo/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
|
||||
# Retrofit
|
||||
-keepattributes Signature, InnerClasses, EnclosingMethod
|
||||
-keepattributes RuntimeVisibleAnnotations, RuntimeVisibleParameterAnnotations
|
||||
-keepclassmembers,allowshrinking,allowobfuscation interface * {
|
||||
@retrofit2.http.* <methods>;
|
||||
}
|
||||
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
|
||||
-dontwarn javax.annotation.**
|
||||
-dontwarn kotlin.Unit
|
||||
-dontwarn retrofit2.KotlinExtensions
|
||||
-dontwarn retrofit2.KotlinExtensions$*
|
||||
|
||||
# OkHttp
|
||||
-dontwarn okhttp3.**
|
||||
-dontwarn okio.**
|
||||
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
|
||||
|
||||
# Gson
|
||||
-keepattributes Signature
|
||||
-keepattributes *Annotation*
|
||||
-dontwarn sun.misc.**
|
||||
-keep class com.google.gson.** { *; }
|
||||
-keep class * implements com.google.gson.TypeAdapter
|
||||
-keep class * implements com.google.gson.TypeAdapterFactory
|
||||
-keep class * implements com.google.gson.JsonSerializer
|
||||
-keep class * implements com.google.gson.JsonDeserializer
|
||||
|
||||
# Keep model classes
|
||||
-keep class com.example.agentclient.models.** { *; }
|
||||
@@ -0,0 +1,26 @@
|
||||
package com.example.obd;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.example.obd", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
29
androidExampleDemo/app/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<!-- 网络权限 -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.AppCompat.Light.DarkActionBar"
|
||||
android:usesCleartextTraffic="true"
|
||||
tools:targetApi="31">
|
||||
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,452 @@
|
||||
package com.example.agentclient;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.ScrollView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import com.example.agentclient.models.*;
|
||||
import com.example.agentclient.utils.ApiClient;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import retrofit2.Call;
|
||||
import retrofit2.Callback;
|
||||
import retrofit2.Response;
|
||||
|
||||
/**
|
||||
* 主Activity - 调用情感分析Agent示例
|
||||
*
|
||||
* 功能:
|
||||
* 1. 自动登录
|
||||
* 2. 通过Agent名称查找Agent ID
|
||||
* 3. 发送文本进行情感分析
|
||||
* 4. 轮询获取执行结果
|
||||
*/
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
// TODO: 修改为你的配置
|
||||
private static final String USERNAME = "admin";
|
||||
private static final String PASSWORD = "123456";
|
||||
private static final String AGENT_NAME = "情感分析Agent"; // Agent名称
|
||||
|
||||
private TextView tvStatus;
|
||||
private TextView tvMessages;
|
||||
private EditText etInput;
|
||||
private Button btnSend;
|
||||
private ProgressBar progressBar;
|
||||
private ScrollView scrollView;
|
||||
|
||||
private String accessToken;
|
||||
private String agentId;
|
||||
private Handler mainHandler;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// 先初始化 Handler,因为 initViews() 中会使用它
|
||||
mainHandler = new Handler(Looper.getMainLooper());
|
||||
|
||||
initViews();
|
||||
|
||||
// 启动时自动登录
|
||||
login();
|
||||
}
|
||||
|
||||
private void initViews() {
|
||||
tvStatus = findViewById(R.id.tvStatus);
|
||||
tvMessages = findViewById(R.id.tvMessages);
|
||||
etInput = findViewById(R.id.etInput);
|
||||
btnSend = findViewById(R.id.btnSend);
|
||||
progressBar = findViewById(R.id.progressBar);
|
||||
scrollView = findViewById(R.id.scrollView);
|
||||
|
||||
btnSend.setOnClickListener(v -> {
|
||||
String input = etInput.getText().toString().trim();
|
||||
if (input.isEmpty()) {
|
||||
Toast.makeText(this, "请输入要分析的文本", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
sendMessage(input);
|
||||
});
|
||||
|
||||
updateStatus("准备登录...");
|
||||
addMessage("系统", "正在连接服务器...");
|
||||
}
|
||||
|
||||
/**
|
||||
* 登录
|
||||
*/
|
||||
private void login() {
|
||||
updateStatus("正在登录...");
|
||||
addMessage("系统", "正在登录...");
|
||||
|
||||
ApiClient.getService().login(USERNAME, PASSWORD).enqueue(new Callback<TokenResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<TokenResponse> call, Response<TokenResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
accessToken = "Bearer " + response.body().getAccessToken();
|
||||
updateStatus("登录成功");
|
||||
addMessage("系统", "登录成功!正在查找Agent...");
|
||||
|
||||
// 登录成功后查找Agent
|
||||
findAgentByName(AGENT_NAME);
|
||||
} else {
|
||||
String errorMsg = "登录失败: " + response.code();
|
||||
try {
|
||||
if (response.errorBody() != null) {
|
||||
errorMsg += "\n" + response.errorBody().string();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
updateStatus("登录失败");
|
||||
addMessage("系统", errorMsg);
|
||||
Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<TokenResponse> call, Throwable t) {
|
||||
String errorMsg = "登录失败: " + t.getMessage();
|
||||
updateStatus("登录失败");
|
||||
addMessage("系统", errorMsg);
|
||||
Toast.makeText(MainActivity.this, errorMsg, Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过名称查找Agent
|
||||
*/
|
||||
private void findAgentByName(String agentName) {
|
||||
updateStatus("正在查找Agent: " + agentName);
|
||||
|
||||
ApiClient.getService().getAgents(agentName, 100, accessToken)
|
||||
.enqueue(new Callback<List<Agent>>() {
|
||||
@Override
|
||||
public void onResponse(Call<List<Agent>> call, Response<List<Agent>> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
List<Agent> agents = response.body();
|
||||
|
||||
// 精确匹配名称
|
||||
Agent foundAgent = null;
|
||||
for (Agent agent : agents) {
|
||||
if (agentName.equals(agent.getName())) {
|
||||
foundAgent = agent;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (foundAgent != null) {
|
||||
agentId = foundAgent.getId();
|
||||
String status = foundAgent.getStatus();
|
||||
updateStatus("已找到Agent: " + agentName);
|
||||
addMessage("系统", String.format(
|
||||
"找到Agent: %s\nID: %s\n状态: %s",
|
||||
foundAgent.getName(),
|
||||
agentId,
|
||||
status
|
||||
));
|
||||
|
||||
if (!"published".equals(status) && !"running".equals(status)) {
|
||||
addMessage("系统", "警告: Agent状态为 '" + status + "',可能无法执行");
|
||||
}
|
||||
|
||||
addMessage("系统", "可以开始发送文本进行情感分析了!");
|
||||
} else {
|
||||
updateStatus("未找到Agent");
|
||||
addMessage("系统", "未找到名称为 '" + agentName + "' 的Agent");
|
||||
if (!agents.isEmpty()) {
|
||||
addMessage("系统", "找到以下相似的Agent:");
|
||||
for (int i = 0; i < Math.min(5, agents.size()); i++) {
|
||||
Agent agent = agents.get(i);
|
||||
addMessage("系统", String.format(
|
||||
" - %s (ID: %s, 状态: %s)",
|
||||
agent.getName(),
|
||||
agent.getId(),
|
||||
agent.getStatus()
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
String errorMsg = "查找Agent失败: " + response.code();
|
||||
updateStatus("查找Agent失败");
|
||||
addMessage("系统", errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<List<Agent>> call, Throwable t) {
|
||||
String errorMsg = "查找Agent失败: " + t.getMessage();
|
||||
updateStatus("查找Agent失败");
|
||||
addMessage("系统", errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 发送消息到Agent
|
||||
*/
|
||||
private void sendMessage(String userInput) {
|
||||
if (agentId == null || agentId.isEmpty()) {
|
||||
Toast.makeText(this, "Agent未找到,请先查找Agent", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (accessToken == null || accessToken.isEmpty()) {
|
||||
Toast.makeText(this, "未登录,请先登录", Toast.LENGTH_SHORT).show();
|
||||
login();
|
||||
return;
|
||||
}
|
||||
|
||||
// 禁用发送按钮
|
||||
btnSend.setEnabled(false);
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
// 显示用户输入
|
||||
addMessage("我", userInput);
|
||||
updateStatus("正在发送请求...");
|
||||
|
||||
// 构建请求数据
|
||||
Map<String, Object> inputData = new HashMap<>();
|
||||
inputData.put("query", userInput);
|
||||
inputData.put("USER_INPUT", userInput);
|
||||
|
||||
AgentExecutionRequest request = new AgentExecutionRequest(agentId, inputData);
|
||||
|
||||
// 执行Agent
|
||||
ApiClient.getService().executeAgent(request, accessToken)
|
||||
.enqueue(new Callback<ExecutionResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<ExecutionResponse> call, Response<ExecutionResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
ExecutionResponse execution = response.body();
|
||||
String executionId = execution.getId();
|
||||
updateStatus("请求已发送,执行ID: " + executionId);
|
||||
addMessage("系统", "正在处理,请稍候...");
|
||||
|
||||
// 轮询获取结果
|
||||
pollExecutionResult(executionId);
|
||||
} else {
|
||||
String errorMsg = "执行失败: " + response.code();
|
||||
try {
|
||||
if (response.errorBody() != null) {
|
||||
errorMsg += "\n" + response.errorBody().string();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
updateStatus("执行失败");
|
||||
addMessage("系统", errorMsg);
|
||||
btnSend.setEnabled(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ExecutionResponse> call, Throwable t) {
|
||||
String errorMsg = "执行失败: " + t.getMessage();
|
||||
updateStatus("执行失败");
|
||||
addMessage("系统", errorMsg);
|
||||
btnSend.setEnabled(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 轮询获取执行结果
|
||||
*/
|
||||
private void pollExecutionResult(String executionId) {
|
||||
ApiClient.getService().getExecutionStatus(executionId, accessToken)
|
||||
.enqueue(new Callback<ExecutionStatusResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<ExecutionStatusResponse> call, Response<ExecutionStatusResponse> response) {
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
ExecutionStatusResponse statusResponse = response.body();
|
||||
String status = statusResponse.getStatus();
|
||||
|
||||
// 显示当前节点信息
|
||||
if (statusResponse.getCurrentNode() != null) {
|
||||
ExecutionStatusResponse.CurrentNode node = statusResponse.getCurrentNode();
|
||||
updateStatus(String.format("执行中: %s (%s)",
|
||||
node.getNodeName() != null ? node.getNodeName() : node.getNodeId(),
|
||||
node.getNodeType()));
|
||||
}
|
||||
|
||||
if ("completed".equals(status)) {
|
||||
// 执行完成,获取结果
|
||||
getExecutionResult(executionId);
|
||||
} else if ("failed".equals(status) || "error".equals(status)) {
|
||||
// 执行失败
|
||||
String errorMsg = statusResponse.getError();
|
||||
if (errorMsg == null || errorMsg.isEmpty()) {
|
||||
errorMsg = "执行失败";
|
||||
}
|
||||
updateStatus("执行失败");
|
||||
addMessage("系统", "执行失败: " + errorMsg);
|
||||
btnSend.setEnabled(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
} else {
|
||||
// 继续轮询
|
||||
mainHandler.postDelayed(() -> pollExecutionResult(executionId), 1000);
|
||||
}
|
||||
} else {
|
||||
// 继续轮询
|
||||
mainHandler.postDelayed(() -> pollExecutionResult(executionId), 1000);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ExecutionStatusResponse> call, Throwable t) {
|
||||
// 继续轮询
|
||||
mainHandler.postDelayed(() -> pollExecutionResult(executionId), 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取执行结果
|
||||
*/
|
||||
private void getExecutionResult(String executionId) {
|
||||
ApiClient.getService().getExecutionResult(executionId, accessToken)
|
||||
.enqueue(new Callback<ExecutionResponse>() {
|
||||
@Override
|
||||
public void onResponse(Call<ExecutionResponse> call, Response<ExecutionResponse> response) {
|
||||
btnSend.setEnabled(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
if (response.isSuccessful() && response.body() != null) {
|
||||
ExecutionResponse execution = response.body();
|
||||
Object outputData = execution.getOutputData();
|
||||
|
||||
updateStatus("执行完成");
|
||||
|
||||
// 格式化输出
|
||||
String result = formatOutput(outputData);
|
||||
addMessage("Agent", result);
|
||||
} else {
|
||||
String errorMsg = "获取结果失败: " + response.code();
|
||||
updateStatus("获取结果失败");
|
||||
addMessage("系统", errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(Call<ExecutionResponse> call, Throwable t) {
|
||||
btnSend.setEnabled(true);
|
||||
progressBar.setVisibility(View.GONE);
|
||||
String errorMsg = "获取结果失败: " + t.getMessage();
|
||||
updateStatus("获取结果失败");
|
||||
addMessage("系统", errorMsg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 格式化输出数据
|
||||
*/
|
||||
private String formatOutput(Object outputData) {
|
||||
if (outputData == null) {
|
||||
return "无输出";
|
||||
}
|
||||
|
||||
if (outputData instanceof String) {
|
||||
return (String) outputData;
|
||||
}
|
||||
|
||||
if (outputData instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = (Map<String, Object>) outputData;
|
||||
|
||||
// 优先提取output字段
|
||||
if (map.containsKey("output") && map.get("output") instanceof String) {
|
||||
return (String) map.get("output");
|
||||
}
|
||||
|
||||
// 如果只有一个key,直接返回其值
|
||||
if (map.size() == 1) {
|
||||
Object value = map.values().iterator().next();
|
||||
if (value instanceof String) {
|
||||
return (String) value;
|
||||
}
|
||||
}
|
||||
|
||||
// 否则转换为字符串
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (Map.Entry<String, Object> entry : map.entrySet()) {
|
||||
if (!entry.getKey().startsWith("_")) {
|
||||
sb.append(entry.getKey()).append(": ").append(entry.getValue()).append("\n");
|
||||
}
|
||||
}
|
||||
return sb.toString().trim();
|
||||
}
|
||||
|
||||
return outputData.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新状态栏
|
||||
*/
|
||||
private void updateStatus(String status) {
|
||||
if (mainHandler == null) {
|
||||
// 如果 Handler 还未初始化,直接在主线程更新
|
||||
if (tvStatus != null) {
|
||||
tvStatus.setText("状态: " + status);
|
||||
}
|
||||
return;
|
||||
}
|
||||
mainHandler.post(() -> {
|
||||
if (tvStatus != null) {
|
||||
tvStatus.setText("状态: " + status);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加消息到消息列表
|
||||
*/
|
||||
private void addMessage(String sender, String message) {
|
||||
if (mainHandler == null) {
|
||||
// 如果 Handler 还未初始化,直接在主线程更新
|
||||
if (tvMessages != null) {
|
||||
String newMessage = String.format("[%s] %s\n\n", sender, message);
|
||||
tvMessages.append(newMessage);
|
||||
|
||||
// 自动滚动到底部
|
||||
if (scrollView != null) {
|
||||
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
mainHandler.post(() -> {
|
||||
if (tvMessages != null) {
|
||||
String currentText = tvMessages.getText().toString();
|
||||
String newMessage = String.format("[%s] %s\n\n", sender, message);
|
||||
tvMessages.append(newMessage);
|
||||
|
||||
// 自动滚动到底部
|
||||
if (scrollView != null) {
|
||||
scrollView.post(() -> scrollView.fullScroll(View.FOCUS_DOWN));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
package com.example.agentclient.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Agent模型
|
||||
*/
|
||||
public class Agent {
|
||||
private String id;
|
||||
private String name;
|
||||
private String description;
|
||||
private String status;
|
||||
|
||||
@SerializedName("created_at")
|
||||
private String createdAt;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
package com.example.agentclient.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Agent执行请求模型
|
||||
*/
|
||||
public class AgentExecutionRequest {
|
||||
@SerializedName("agent_id")
|
||||
private String agentId;
|
||||
|
||||
@SerializedName("input_data")
|
||||
private Map<String, Object> inputData;
|
||||
|
||||
public AgentExecutionRequest(String agentId, Map<String, Object> inputData) {
|
||||
this.agentId = agentId;
|
||||
this.inputData = inputData;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public void setAgentId(String agentId) {
|
||||
this.agentId = agentId;
|
||||
}
|
||||
|
||||
public Map<String, Object> getInputData() {
|
||||
return inputData;
|
||||
}
|
||||
|
||||
public void setInputData(Map<String, Object> inputData) {
|
||||
this.inputData = inputData;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,84 @@
|
||||
package com.example.agentclient.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 执行记录响应模型
|
||||
*/
|
||||
public class ExecutionResponse {
|
||||
private String id;
|
||||
|
||||
@SerializedName("agent_id")
|
||||
private String agentId;
|
||||
|
||||
@SerializedName("workflow_id")
|
||||
private String workflowId;
|
||||
|
||||
private String status;
|
||||
|
||||
@SerializedName("input_data")
|
||||
private Map<String, Object> inputData;
|
||||
|
||||
@SerializedName("output_data")
|
||||
private Object outputData;
|
||||
|
||||
@SerializedName("created_at")
|
||||
private String createdAt;
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(String id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public String getAgentId() {
|
||||
return agentId;
|
||||
}
|
||||
|
||||
public void setAgentId(String agentId) {
|
||||
this.agentId = agentId;
|
||||
}
|
||||
|
||||
public String getWorkflowId() {
|
||||
return workflowId;
|
||||
}
|
||||
|
||||
public void setWorkflowId(String workflowId) {
|
||||
this.workflowId = workflowId;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public Map<String, Object> getInputData() {
|
||||
return inputData;
|
||||
}
|
||||
|
||||
public void setInputData(Map<String, Object> inputData) {
|
||||
this.inputData = inputData;
|
||||
}
|
||||
|
||||
public Object getOutputData() {
|
||||
return outputData;
|
||||
}
|
||||
|
||||
public void setOutputData(Object outputData) {
|
||||
this.outputData = outputData;
|
||||
}
|
||||
|
||||
public String getCreatedAt() {
|
||||
return createdAt;
|
||||
}
|
||||
|
||||
public void setCreatedAt(String createdAt) {
|
||||
this.createdAt = createdAt;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package com.example.agentclient.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* 执行状态响应模型
|
||||
*/
|
||||
public class ExecutionStatusResponse {
|
||||
private String status;
|
||||
private int progress = 0;
|
||||
|
||||
@SerializedName("current_node")
|
||||
private CurrentNode currentNode;
|
||||
|
||||
private String error;
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public int getProgress() {
|
||||
return progress;
|
||||
}
|
||||
|
||||
public void setProgress(int progress) {
|
||||
this.progress = progress;
|
||||
}
|
||||
|
||||
public CurrentNode getCurrentNode() {
|
||||
return currentNode;
|
||||
}
|
||||
|
||||
public void setCurrentNode(CurrentNode currentNode) {
|
||||
this.currentNode = currentNode;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当前执行节点
|
||||
*/
|
||||
public static class CurrentNode {
|
||||
@SerializedName("node_id")
|
||||
private String nodeId;
|
||||
|
||||
@SerializedName("node_name")
|
||||
private String nodeName;
|
||||
|
||||
@SerializedName("node_type")
|
||||
private String nodeType;
|
||||
|
||||
public String getNodeId() {
|
||||
return nodeId;
|
||||
}
|
||||
|
||||
public void setNodeId(String nodeId) {
|
||||
this.nodeId = nodeId;
|
||||
}
|
||||
|
||||
public String getNodeName() {
|
||||
return nodeName;
|
||||
}
|
||||
|
||||
public void setNodeName(String nodeName) {
|
||||
this.nodeName = nodeName;
|
||||
}
|
||||
|
||||
public String getNodeType() {
|
||||
return nodeType;
|
||||
}
|
||||
|
||||
public void setNodeType(String nodeType) {
|
||||
this.nodeType = nodeType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.example.agentclient.models;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
/**
|
||||
* Token响应模型
|
||||
*/
|
||||
public class TokenResponse {
|
||||
@SerializedName("access_token")
|
||||
private String accessToken;
|
||||
|
||||
@SerializedName("token_type")
|
||||
private String tokenType = "bearer";
|
||||
|
||||
public String getAccessToken() {
|
||||
return accessToken;
|
||||
}
|
||||
|
||||
public void setAccessToken(String accessToken) {
|
||||
this.accessToken = accessToken;
|
||||
}
|
||||
|
||||
public String getTokenType() {
|
||||
return tokenType;
|
||||
}
|
||||
|
||||
public void setTokenType(String tokenType) {
|
||||
this.tokenType = tokenType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package com.example.agentclient.utils;
|
||||
|
||||
import com.example.agentclient.models.*;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.logging.HttpLoggingInterceptor;
|
||||
import retrofit2.Retrofit;
|
||||
import retrofit2.converter.gson.GsonConverterFactory;
|
||||
import retrofit2.http.*;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* API客户端配置
|
||||
*
|
||||
* 使用说明:
|
||||
* 1. 修改 BASE_URL 为你的服务器地址
|
||||
* 2. 确保服务器允许跨域请求(CORS)
|
||||
*/
|
||||
public class ApiClient {
|
||||
// TODO: 修改为你的服务器地址
|
||||
private static final String BASE_URL = "http://101.43.95.130:8037";
|
||||
|
||||
private static Retrofit retrofit;
|
||||
private static AgentService agentService;
|
||||
|
||||
static {
|
||||
// 创建OkHttp客户端
|
||||
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
|
||||
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
|
||||
|
||||
OkHttpClient okHttpClient = new OkHttpClient.Builder()
|
||||
.connectTimeout(30, TimeUnit.SECONDS)
|
||||
.readTimeout(60, TimeUnit.SECONDS)
|
||||
.writeTimeout(60, TimeUnit.SECONDS)
|
||||
.addInterceptor(logging)
|
||||
.build();
|
||||
|
||||
// 创建Retrofit实例
|
||||
retrofit = new Retrofit.Builder()
|
||||
.baseUrl(BASE_URL)
|
||||
.client(okHttpClient)
|
||||
.addConverterFactory(GsonConverterFactory.create())
|
||||
.build();
|
||||
|
||||
// 创建API服务
|
||||
agentService = retrofit.create(AgentService.class);
|
||||
}
|
||||
|
||||
public static AgentService getService() {
|
||||
return agentService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Agent API接口
|
||||
*/
|
||||
public interface AgentService {
|
||||
/**
|
||||
* 用户登录
|
||||
*
|
||||
* @param username 用户名
|
||||
* @param password 密码
|
||||
* @return Token响应
|
||||
*/
|
||||
@FormUrlEncoded
|
||||
@POST("/api/v1/auth/login")
|
||||
retrofit2.Call<TokenResponse> login(
|
||||
@Field("username") String username,
|
||||
@Field("password") String password
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取Agent列表(支持搜索)
|
||||
*
|
||||
* @param search 搜索关键词(Agent名称)
|
||||
* @param limit 返回数量限制
|
||||
* @param token 认证Token
|
||||
* @return Agent列表
|
||||
*/
|
||||
@GET("/api/v1/agents")
|
||||
retrofit2.Call<List<Agent>> getAgents(
|
||||
@Query("search") String search,
|
||||
@Query("limit") Integer limit,
|
||||
@Header("Authorization") String token
|
||||
);
|
||||
|
||||
/**
|
||||
* 执行Agent
|
||||
*
|
||||
* @param request Agent执行请求
|
||||
* @param token 认证Token
|
||||
* @return 执行记录
|
||||
*/
|
||||
@POST("/api/v1/executions")
|
||||
retrofit2.Call<ExecutionResponse> executeAgent(
|
||||
@Body AgentExecutionRequest request,
|
||||
@Header("Authorization") String token
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取执行状态
|
||||
*
|
||||
* @param executionId 执行ID
|
||||
* @param token 认证Token
|
||||
* @return 执行状态
|
||||
*/
|
||||
@GET("/api/v1/executions/{execution_id}/status")
|
||||
retrofit2.Call<ExecutionStatusResponse> getExecutionStatus(
|
||||
@Path("execution_id") String executionId,
|
||||
@Header("Authorization") String token
|
||||
);
|
||||
|
||||
/**
|
||||
* 获取执行结果
|
||||
*
|
||||
* @param executionId 执行ID
|
||||
* @param token 认证Token
|
||||
* @return 执行详情
|
||||
*/
|
||||
@GET("/api/v1/executions/{execution_id}")
|
||||
retrofit2.Call<ExecutionResponse> getExecutionResult(
|
||||
@Path("execution_id") String executionId,
|
||||
@Header("Authorization") String token
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/transparent" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="2dp"
|
||||
android:color="@color/primary_color" />
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/primary_color" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="@color/primary_color" />
|
||||
</shape>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/accent_color" />
|
||||
<corners android:radius="8dp" />
|
||||
<stroke
|
||||
android:width="0dp"
|
||||
android:color="@color/accent_color" />
|
||||
</shape>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@android:color/white" />
|
||||
<corners android:radius="12dp" />
|
||||
<stroke
|
||||
android:width="1dp"
|
||||
android:color="@color/divider_color" />
|
||||
<padding
|
||||
android:left="16dp"
|
||||
android:top="16dp"
|
||||
android:right="16dp"
|
||||
android:bottom="16dp" />
|
||||
</shape>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#3DDC84"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
@@ -0,0 +1,30 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path android:pathData="M31,63.928c0,0 6.4,-11 12.1,-13.1c7.2,-2.6 26,-1.4 26,-1.4l38.1,38.1L107,108.928l-32,-1L31,63.928z">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="85.84757"
|
||||
android:endY="92.4963"
|
||||
android:startX="42.9492"
|
||||
android:startY="49.59793"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M65.3,45.828l3.8,-6.6c0.2,-0.4 0.1,-0.9 -0.3,-1.1c-0.4,-0.2 -0.9,-0.1 -1.1,0.3l-3.9,6.7c-6.3,-2.8 -13.4,-2.8 -19.7,0l-3.9,-6.7c-0.2,-0.4 -0.7,-0.5 -1.1,-0.3C38.8,38.328 38.7,38.828 38.9,39.228l3.8,6.6C36.2,49.428 31.7,56.028 31,63.928h46C76.3,56.028 71.8,49.428 65.3,45.828zM43.4,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2c-0.3,-0.7 -0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C45.3,56.528 44.5,57.328 43.4,57.328L43.4,57.328zM64.6,57.328c-0.8,0 -1.5,-0.5 -1.8,-1.2s-0.1,-1.5 0.4,-2.1c0.5,-0.5 1.4,-0.7 2.1,-0.4c0.7,0.3 1.2,1 1.2,1.8C66.5,56.528 65.6,57.328 64.6,57.328L64.6,57.328z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -0,0 +1,94 @@
|
||||
<?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/background_color">
|
||||
|
||||
<!-- 标题 -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发现OBD设备"
|
||||
android:textSize="24sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/primary_text"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="24dp" />
|
||||
|
||||
<!-- 状态信息 -->
|
||||
<TextView
|
||||
android:id="@+id/status_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="点击扫描按钮开始搜索OBD设备"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@color/secondary_text"
|
||||
android:gravity="center"
|
||||
android:layout_marginBottom="16dp" />
|
||||
|
||||
<!-- 扫描控制按钮 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_scan"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_weight="1"
|
||||
android:text="开始扫描"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@android:color/white"
|
||||
android:background="@drawable/button_primary"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:elevation="4dp" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btn_stop_scan"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="60dp"
|
||||
android:layout_weight="1"
|
||||
android:text="停止扫描"
|
||||
android:textSize="16sp"
|
||||
android:textColor="@android:color/white"
|
||||
android:background="@drawable/button_secondary"
|
||||
android:layout_marginStart="8dp"
|
||||
android:elevation="4dp"
|
||||
android:enabled="false" />
|
||||
</LinearLayout>
|
||||
|
||||
<!-- 设备列表 -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发现的设备:"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
android:textColor="@color/primary_text"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/device_list"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:background="@drawable/data_card_background"
|
||||
android:divider="@color/divider_color"
|
||||
android:dividerHeight="1dp"
|
||||
android:padding="8dp" />
|
||||
|
||||
<!-- 提示信息 -->
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="点击设备名称进行连接"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/secondary_text"
|
||||
android:gravity="center"
|
||||
android:layout_marginTop="16dp" />
|
||||
|
||||
</LinearLayout>
|
||||
75
androidExampleDemo/app/src/main/res/layout/activity_main.xml
Normal file
@@ -0,0 +1,75 @@
|
||||
<?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">
|
||||
|
||||
<!-- 状态栏 -->
|
||||
<TextView
|
||||
android:id="@+id/tvStatus"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="状态: 准备中..."
|
||||
android:textSize="14sp"
|
||||
android:textColor="#666666"
|
||||
android:padding="8dp"
|
||||
android:background="#F5F5F5"
|
||||
android:layout_marginBottom="8dp" />
|
||||
|
||||
<!-- 消息显示区域 -->
|
||||
<ScrollView
|
||||
android:id="@+id/scrollView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="0dp"
|
||||
android:layout_weight="1"
|
||||
android:background="#FFFFFF"
|
||||
android:padding="12dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMessages"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="14sp"
|
||||
android:textColor="#333333"
|
||||
android:lineSpacingExtra="4dp" />
|
||||
</ScrollView>
|
||||
|
||||
<!-- 进度条 -->
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<!-- 输入区域 -->
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:layout_marginTop="8dp">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/etInput"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:hint="请输入要分析的文本..."
|
||||
android:minHeight="48dp"
|
||||
android:padding="12dp"
|
||||
android:background="@android:drawable/edit_text"
|
||||
android:maxLines="5"
|
||||
android:gravity="top|start" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/btnSend"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="发送"
|
||||
android:layout_marginStart="8dp"
|
||||
android:minWidth="80dp"
|
||||
android:minHeight="48dp" />
|
||||
</LinearLayout>
|
||||
|
||||
</LinearLayout>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
<monochrome android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
BIN
androidExampleDemo/app/src/main/res/mipmap-hdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-mdpi/ic_launcher.webp
Normal file
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 184 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 2.5 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/icon_next.png
Normal file
|
After Width: | Height: | Size: 924 B |
|
After Width: | Height: | Size: 351 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 1.2 MiB |
|
After Width: | Height: | Size: 57 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/me_normal.png
Normal file
|
After Width: | Height: | Size: 2.1 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/me_press.png
Normal file
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.3 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/member_bg.png
Normal file
|
After Width: | Height: | Size: 570 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/qr_code.png
Normal file
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 149 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/s_renzhen.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/shiyong.png
Normal file
|
After Width: | Height: | Size: 9.7 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/tixing.png
Normal file
|
After Width: | Height: | Size: 389 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/work.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
androidExampleDemo/app/src/main/res/mipmap-xxhdpi/work_press.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
20
androidExampleDemo/app/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<!-- 系统基础颜色 -->
|
||||
<color name="purple_200">#FFBB86FC</color>
|
||||
<color name="purple_500">#FF6200EE</color>
|
||||
<color name="purple_700">#FF3700B3</color>
|
||||
<color name="teal_200">#FF03DAC5</color>
|
||||
<color name="teal_700">#FF018786</color>
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
|
||||
<!-- 应用自定义颜色 -->
|
||||
<color name="primary_color">#2196F3</color>
|
||||
<color name="primary_dark">#1976D2</color>
|
||||
<color name="accent_color">#FF4081</color>
|
||||
<color name="background_color">#F5F5F5</color>
|
||||
<color name="primary_text">#212121</color>
|
||||
<color name="secondary_text">#757575</color>
|
||||
<color name="divider_color">#BDBDBD</color>
|
||||
</resources>
|
||||
4
androidExampleDemo/app/src/main/res/values/strings.xml
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Agent客户端</string>
|
||||
</resources>
|
||||
16
androidExampleDemo/app/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,16 @@
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
<!-- Base application theme. -->
|
||||
<style name="Theme.Obd" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<!-- Primary brand color. -->
|
||||
<item name="colorPrimary">@color/purple_500</item>
|
||||
<item name="colorPrimaryVariant">@color/purple_700</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<!-- Secondary brand color. -->
|
||||
<item name="colorSecondary">@color/teal_200</item>
|
||||
<item name="colorSecondaryVariant">@color/teal_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<!-- Status bar color. -->
|
||||
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
</resources>
|
||||
13
androidExampleDemo/app/src/main/res/xml/backup_rules.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample backup rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/guide/topics/data/autobackup
|
||||
for details.
|
||||
Note: This file is ignored for devices older that API 31
|
||||
See https://developer.android.com/about/versions/12/backup-restore
|
||||
-->
|
||||
<full-backup-content>
|
||||
<!--
|
||||
<include domain="sharedpref" path="."/>
|
||||
<exclude domain="sharedpref" path="device.xml"/>
|
||||
-->
|
||||
</full-backup-content>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
Sample data extraction rules file; uncomment and customize as necessary.
|
||||
See https://developer.android.com/about/versions/12/backup-restore#xml-changes
|
||||
for details.
|
||||
-->
|
||||
<data-extraction-rules>
|
||||
<cloud-backup>
|
||||
<!-- TODO: Use <include> and <exclude> to control what is backed up.
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
-->
|
||||
</cloud-backup>
|
||||
<!--
|
||||
<device-transfer>
|
||||
<include .../>
|
||||
<exclude .../>
|
||||
</device-transfer>
|
||||
-->
|
||||
</data-extraction-rules>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<network-security-config>
|
||||
<!-- 允许HTTP连接(仅用于开发,生产环境应使用HTTPS) -->
|
||||
<base-config cleartextTrafficPermitted="true">
|
||||
<trust-anchors>
|
||||
<certificates src="system" />
|
||||
</trust-anchors>
|
||||
</base-config>
|
||||
</network-security-config>
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.example.obd;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Example local unit test, which will execute on the development machine (host).
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
public class ExampleUnitTest {
|
||||
@Test
|
||||
public void addition_isCorrect() {
|
||||
assertEquals(4, 2 + 2);
|
||||
}
|
||||
}
|
||||
9
androidExampleDemo/build.gradle
Normal file
@@ -0,0 +1,9 @@
|
||||
// Top-level build file where you can add configuration options common to all sub-projects/modules.
|
||||
plugins {
|
||||
alias(libs.plugins.android.application) apply false
|
||||
id 'org.jetbrains.kotlin.android' version '1.9.0' apply false
|
||||
}
|
||||
|
||||
task clean(type: Delete) {
|
||||
delete rootProject.buildDir
|
||||
}
|
||||
4
androidExampleDemo/gradle.properties
Normal file
@@ -0,0 +1,4 @@
|
||||
# Project-wide Gradle settings.
|
||||
org.gradle.jvmargs=-Xmx2048m -Dfile.encoding=UTF-8
|
||||
android.useAndroidX=true
|
||||
android.enableJetifier=true
|
||||
39
androidExampleDemo/gradle/libs.versions.toml
Normal file
@@ -0,0 +1,39 @@
|
||||
[versions]
|
||||
agp = "8.7.3"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
appcompat = "1.6.1"
|
||||
material = "1.10.0"
|
||||
# OBD应用依赖版本
|
||||
lifecycle = "2.7.0"
|
||||
room = "2.6.1"
|
||||
retrofit = "2.9.0"
|
||||
okhttp = "4.12.0"
|
||||
hilt = "2.48.1"
|
||||
work = "2.9.0"
|
||||
ble = "2.7.1"
|
||||
|
||||
[libraries]
|
||||
junit = { group = "junit", name = "junit", version.ref = "junit" }
|
||||
ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "junitVersion" }
|
||||
espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
|
||||
appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "appcompat" }
|
||||
material = { group = "com.google.android.material", name = "material", version.ref = "material" }
|
||||
|
||||
# OBD应用依赖库
|
||||
lifecycle-viewmodel = { group = "androidx.lifecycle", name = "lifecycle-viewmodel", version.ref = "lifecycle" }
|
||||
lifecycle-livedata = { group = "androidx.lifecycle", name = "lifecycle-livedata", version.ref = "lifecycle" }
|
||||
work-runtime = { group = "androidx.work", name = "work-runtime", version.ref = "work" }
|
||||
room-runtime = { group = "androidx.room", name = "room-runtime", version.ref = "room" }
|
||||
room-compiler = { group = "androidx.room", name = "room-compiler", version.ref = "room" }
|
||||
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }
|
||||
retrofit-gson = { group = "com.squareup.retrofit2", name = "converter-gson", version.ref = "retrofit" }
|
||||
okhttp-logging = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okhttp" }
|
||||
hilt-android = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" }
|
||||
hilt-compiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" }
|
||||
ble = { group = "no.nordicsemi.android", name = "ble", version.ref = "ble" }
|
||||
|
||||
[plugins]
|
||||
android-application = { id = "com.android.application", version.ref = "agp" }
|
||||
|
||||
BIN
androidExampleDemo/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
7
androidExampleDemo/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
#Tue Jan 20 13:02:26 CST 2026
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
|
||||
networkTimeout=10000
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
185
androidExampleDemo/gradlew
vendored
Normal file
@@ -0,0 +1,185 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
##
|
||||
##############################################################################
|
||||
|
||||
# Attempt to set APP_HOME
|
||||
# Resolve links: $0 may be a link
|
||||
PRG="$0"
|
||||
# Need this for relative symlinks.
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG=`dirname "$PRG"`"/$link"
|
||||
fi
|
||||
done
|
||||
SAVED="`pwd`"
|
||||
cd "`dirname \"$PRG\"`/" >/dev/null
|
||||
APP_HOME="`pwd -P`"
|
||||
cd "$SAVED" >/dev/null
|
||||
|
||||
APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
||||
warn () {
|
||||
echo "$*"
|
||||
}
|
||||
|
||||
die () {
|
||||
echo
|
||||
echo "$*"
|
||||
echo
|
||||
exit 1
|
||||
}
|
||||
|
||||
# OS specific support (must be 'true' or 'false').
|
||||
cygwin=false
|
||||
msys=false
|
||||
darwin=false
|
||||
nonstop=false
|
||||
case "`uname`" in
|
||||
CYGWIN* )
|
||||
cygwin=true
|
||||
;;
|
||||
Darwin* )
|
||||
darwin=true
|
||||
;;
|
||||
MINGW* )
|
||||
msys=true
|
||||
;;
|
||||
NONSTOP* )
|
||||
nonstop=true
|
||||
;;
|
||||
esac
|
||||
|
||||
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# Increase the maximum file descriptors if we can.
|
||||
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
|
||||
MAX_FD_LIMIT=`ulimit -H -n`
|
||||
if [ $? -eq 0 ] ; then
|
||||
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
|
||||
MAX_FD="$MAX_FD_LIMIT"
|
||||
fi
|
||||
ulimit -n $MAX_FD
|
||||
if [ $? -ne 0 ] ; then
|
||||
warn "Could not set maximum file descriptor limit: $MAX_FD"
|
||||
fi
|
||||
else
|
||||
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
|
||||
fi
|
||||
fi
|
||||
|
||||
# For Darwin, add options to specify how the application appears in the dock
|
||||
if $darwin; then
|
||||
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
|
||||
fi
|
||||
|
||||
# For Cygwin or MSYS, switch paths to Windows format before running java
|
||||
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
|
||||
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
|
||||
|
||||
JAVACMD=`cygpath --unix "$JAVACMD"`
|
||||
|
||||
# We build the pattern for arguments to be converted via cygpath
|
||||
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
|
||||
SEP=""
|
||||
for dir in $ROOTDIRSRAW ; do
|
||||
ROOTDIRS="$ROOTDIRS$SEP$dir"
|
||||
SEP="|"
|
||||
done
|
||||
OURCYGPATTERN="(^($ROOTDIRS))"
|
||||
# Add a user-defined pattern to the cygpath arguments
|
||||
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
|
||||
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
|
||||
fi
|
||||
# Now convert the arguments - kludge to limit ourselves to /bin/sh
|
||||
i=0
|
||||
for arg in "$@" ; do
|
||||
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
|
||||
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
|
||||
|
||||
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
|
||||
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Escape application args
|
||||
save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
89
androidExampleDemo/gradlew.bat
vendored
Normal file
@@ -0,0 +1,89 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@rem Gradle startup script for Windows
|
||||
@rem
|
||||
@rem ##########################################################################
|
||||
|
||||
@rem Set local scope for the variables with windows NT shell
|
||||
if "%OS%"=="Windows_NT" setlocal
|
||||
|
||||
set DIRNAME=%~dp0
|
||||
if "%DIRNAME%" == "" set DIRNAME=.
|
||||
set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
|
||||
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
set JAVA_EXE=java.exe
|
||||
%JAVA_EXE% -version >NUL 2>&1
|
||||
if "%ERRORLEVEL%" == "0" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:findJavaFromJavaHome
|
||||
set JAVA_HOME=%JAVA_HOME:"=%
|
||||
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
|
||||
|
||||
if exist "%JAVA_EXE%" goto execute
|
||||
|
||||
echo.
|
||||
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
|
||||
echo.
|
||||
echo Please set the JAVA_HOME variable in your environment to match the
|
||||
echo location of your Java installation.
|
||||
|
||||
goto fail
|
||||
|
||||
:execute
|
||||
@rem Setup the command line
|
||||
|
||||
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
|
||||
|
||||
|
||||
@rem Execute Gradle
|
||||
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
|
||||
|
||||
:end
|
||||
@rem End local scope for the variables with windows NT shell
|
||||
if "%ERRORLEVEL%"=="0" goto mainEnd
|
||||
|
||||
:fail
|
||||
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
|
||||
rem the _cmd.exe /c_ return code!
|
||||
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
|
||||
exit /b 1
|
||||
|
||||
:mainEnd
|
||||
if "%OS%"=="Windows_NT" endlocal
|
||||
|
||||
:omega
|
||||
18
androidExampleDemo/settings.gradle
Normal file
@@ -0,0 +1,18 @@
|
||||
pluginManagement {
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
}
|
||||
}
|
||||
|
||||
dependencyResolutionManagement {
|
||||
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
|
||||
repositories {
|
||||
google()
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
|
||||
rootProject.name = "AgentClient"
|
||||
include ':app'
|
||||