Compare commits

..

5 Commits

Author SHA1 Message Date
lzh 71579d369a 10.30 项目源码
1 year ago
chenhaochi a68e7a7472 需求文档
1 year ago
chenhaochi e8b267c84e 需求文档UML模型
1 year ago
lzh 2b347f7015 lzh修改10.28 01
1 year ago
lzh 636a793246 李子涵10.23上传
1 year ago

@ -1,38 +0,0 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

@ -1,8 +0,0 @@
# 默认忽略的文件
/shelf/
/workspace.xml
# 基于编辑器的 HTTP 客户端请求
/httpRequests/
# Datasource local storage ignored files
/dataSources/
/dataSources.local.xml

@ -1,7 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="Encoding">
<file url="file://$PROJECT_DIR$/src/main/java" charset="UTF-8" />
<file url="file://$PROJECT_DIR$/src/main/resources" charset="UTF-8" />
</component>
</project>

@ -1,14 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="MavenProjectsManager">
<option name="originalFiles">
<list>
<option value="$PROJECT_DIR$/pom.xml" />
</list>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/out" />
</component>
</project>

@ -1,24 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>chatgpt-java</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.15.3</version> <!-- 确保版本存在 -->
</dependency>
</dependencies>
</project>

@ -1,117 +0,0 @@
package org.example;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
public class ChatGPTMultiTurn {
private static final String API_KEY = "sk-ZoGHErXVBPukGFAW0f4f88C51cD84717AfEaBd70A9B7E49d"; //API 密钥
private static final String API_URL = "https://openkey.cloud/v1/chat/completions"; //URL
private static final ObjectMapper mapper = new ObjectMapper();
private static final HttpClient client = HttpClient.newHttpClient();
private static final List<ObjectNode> messages = new ArrayList<>();
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
try {
// 初始化对话,系统提示
ObjectNode systemMessage = mapper.createObjectNode();
systemMessage.put("role", "system");
systemMessage.put("content", "你是一个乐于助人的助手。");
messages.add(systemMessage);
System.out.println("与 ChatGPT 对话。输入 'exit' 以结束对话。");
while (true) {
System.out.print("你: ");
String userInput = scanner.nextLine();
if (userInput.equalsIgnoreCase("exit")) {
System.out.println("对话结束。再见!");
break;
}
addUserMessage(userInput);
String response = getResponse();
System.out.println("ChatGPT 的回复: " + response);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
scanner.close();
}
}
private static void addUserMessage(String content) {
ObjectNode userMessage = mapper.createObjectNode();
userMessage.put("role", "user");
userMessage.put("content", content);
messages.add(userMessage);
}
private static String getResponse() throws Exception {
//JSON 请求体
ObjectNode requestBody = mapper.createObjectNode();
requestBody.put("model", "gpt-3.5-turbo");
requestBody.put("temperature", 0.7);
requestBody.set("messages", mapper.valueToTree(messages));
String requestBodyString = mapper.writeValueAsString(requestBody);
// 创建 HTTP 请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(API_URL))
.header("Content-Type", "application/json")
.header("Authorization", "Bearer " + API_KEY)
.POST(HttpRequest.BodyPublishers.ofString(requestBodyString, StandardCharsets.UTF_8))
.build();
// 发送请求并获取响应
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
// 调试
/*
System.out.println("请求方法: " + request.method());
System.out.println("请求URI: " + request.uri());
System.out.println("请求体: " + requestBodyString);
System.out.println("响应状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());
*/
// 检查响应状态码
if (response.statusCode() != 200) {
throw new RuntimeException("请求失败,状态码:" + response.statusCode() + ",响应体:" + response.body());
}
// 解析响应 JSON
JsonNode jsonResponse = mapper.readTree(response.body());
JsonNode choices = jsonResponse.get("choices");
if (choices != null && choices.isArray() && choices.size() > 0) {
JsonNode firstChoice = choices.get(0);
JsonNode messageNode = firstChoice.get("message");
if (messageNode != null) {
// 将助手的回复添加到消息列表中
ObjectNode assistantMessage = mapper.createObjectNode();
assistantMessage.put("role", "assistant");
assistantMessage.put("content", messageNode.get("content").asText());
messages.add(assistantMessage);
return messageNode.get("content").asText();
}
}
throw new RuntimeException("无法解析响应内容");
}
}

@ -1,17 +0,0 @@
package org.example;
//TIP 要<b>运行</b>代码,请按 <shortcut actionId="Run"/> 或
// 点击装订区域中的 <icon src="AllIcons.Actions.Execute"/> 图标。
public class Main {
public static void main(String[] args) {
//TIP 当文本光标位于高亮显示的文本处时按 <shortcut actionId="ShowIntentionActions"/>
// 查看 IntelliJ IDEA 建议如何修正。
System.out.printf("Hello and welcome!");
for (int i = 1; i <= 5; i++) {
//TIP 按 <shortcut actionId="Debug"/> 开始调试代码。我们已经设置了一个 <icon src="AllIcons.Debugger.Db_set_breakpoint"/> 断点
// 但您始终可以通过按 <shortcut actionId="ToggleLineBreakpoint"/> 添加更多断点。
System.out.println("i = " + i);
}
}
}

Binary file not shown.

Binary file not shown.

@ -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

@ -0,0 +1,3 @@
# 默认忽略的文件
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="CompilerConfiguration">
<bytecodeTargetLevel target="11" />
</component>
</project>

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleMigrationSettings" migrationVersion="1" />
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleHome" value="D:/gradle-8.6" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" default="true" project-jdk-name="Android Studio default JDK" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1,66 @@
plugins {
id 'com.android.application'
}
android {
namespace 'com.example.elderlycaresystem2'
compileSdk 33
defaultConfig {
applicationId "com.example.elderlycaresystem2"
minSdk 24
targetSdk 33
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_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'com.google.android.material:material:1.5.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.navigation:navigation-fragment:2.4.1'
implementation 'androidx.navigation:navigation-ui:2.4.1'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.3'
implementation 'com.fasterxml.jackson.core:jackson-core:2.15.3'
implementation 'com.fasterxml.jackson.core:jackson-annotations:2.15.3'
// RecyclerView
implementation 'androidx.recyclerview:recyclerview:1.2.1'
// Retrofit
implementation 'com.squareup.retrofit2:retrofit:2.9.0'
implementation 'com.squareup.retrofit2:converter-jackson:2.9.0'
implementation 'com.fasterxml.jackson.core:jackson-databind:2.15.2' // 使
// OkHttp
implementation 'com.squareup.okhttp3:logging-interceptor:4.9.1'
// Glide Picasso
implementation 'com.github.bumptech.glide:glide:4.12.0'
// kapt 'com.github.bumptech.glide:compiler:4.12.0'y
implementation 'com.google.code.gson:gson:2.8.9'
//
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,26 @@
package com.example.elderlycaresystem2;
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.elderlycaresystem2", appContext.getPackageName());
}
}

@ -0,0 +1,32 @@
<?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.CALL_PHONE" />
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/Theme.Elderlycaresystem2.NoActionBar"
tools:targetApi="31">
<activity
android:name=".DetectionActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Elderlycaresystem2.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".UserActivity" />
<!-- <activity android:name=".DetectionActivity" />-->
<activity android:name=".TalkActivity" />
<activity android:name=".ContactActivity" />
</application>
</manifest>

@ -0,0 +1,40 @@
package com.example.elderlycaresystem2; // 请替换为您的实际包名
import java.util.List;
public class AIRequest {
private String model;
private double temperature;
private List<Message> messages;
public AIRequest(String model, double temperature, List<Message> messages) {
this.model = model;
this.temperature = temperature;
this.messages = messages;
}
// Getters 和 Setters
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public double getTemperature() {
return temperature;
}
public void setTemperature(double temperature) {
this.temperature = temperature;
}
public List<Message> getMessages() {
return messages;
}
public void setMessages(List<Message> messages) {
this.messages = messages;
}
}

@ -0,0 +1,130 @@
package com.example.elderlycaresystem2;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public class AIResponse {
private String id;
private String object;
private long created;
private String model;
private List<Choice> choices;
private Usage usage;
// Getter 和 Setter 方法
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getObject() {
return object;
}
public void setObject(String object) {
this.object = object;
}
public long getCreated() {
return created;
}
public void setCreated(long created) {
this.created = created;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public List<Choice> getChoices() {
return choices;
}
public void setChoices(List<Choice> choices) {
this.choices = choices;
}
public Usage getUsage() {
return usage;
}
public void setUsage(Usage usage) {
this.usage = usage;
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Choice {
private int index;
private Message message;
private String finish_reason;
// Getter 和 Setter 方法
public int getIndex() {
return index;
}
public void setIndex(int index) {
this.index = index;
}
public Message getMessage() {
return message;
}
public void setMessage(Message message) {
this.message = message;
}
public String getFinish_reason() {
return finish_reason;
}
public void setFinish_reason(String finish_reason) {
this.finish_reason = finish_reason;
}
}
@JsonIgnoreProperties(ignoreUnknown = true)
public static class Usage {
private int prompt_tokens;
private int completion_tokens;
private int total_tokens;
// Getter 和 Setter 方法
public int getPrompt_tokens() {
return prompt_tokens;
}
public void setPrompt_tokens(int prompt_tokens) {
this.prompt_tokens = prompt_tokens;
}
public int getCompletion_tokens() {
return completion_tokens;
}
public void setCompletion_tokens(int completion_tokens) {
this.completion_tokens = completion_tokens;
}
public int getTotal_tokens() {
return total_tokens;
}
public void setTotal_tokens(int total_tokens) {
this.total_tokens = total_tokens;
}
}
}

@ -0,0 +1,10 @@
package com.example.elderlycaresystem2; // 请替换为您的实际包名
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.POST;
public interface ApiService {
@POST("v1/chat/completions") // 定义相对路径
Call<AIResponse> getAIReply(@Body AIRequest request);
}

@ -0,0 +1,80 @@
// src/main/java/com/example/elderlycaresystem2/ContactActivity.java
package com.example.elderlycaresystem2;
import android.os.Bundle;
import android.text.TextUtils;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class ContactActivity extends AppCompatActivity {
private EditText etName, etPhone;
private Button btnConfirm;
private ContactManager contactManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_contact); // 确保布局文件名为 activity_contact.xml
// 初始化 ContactManager
contactManager = new ContactManager(this);
// 绑定视图
etName = findViewById(R.id.et_name);
etPhone = findViewById(R.id.et_phone);
btnConfirm = findViewById(R.id.btn_queding);
// 加载当前联系人信息
loadContactInfo();
// 设置确认按钮点击事件
btnConfirm.setOnClickListener(view -> {
String name = etName.getText().toString().trim();
String phone = etPhone.getText().toString().trim();
if (validateInput(name, phone)) {
// 保存联系人信息
contactManager.setContactName(name);
contactManager.setContactPhone(phone);
Toast.makeText(ContactActivity.this, "紧急联系人已更新", Toast.LENGTH_SHORT).show();
// 结束当前活动,返回上一页
finish();
}
});
}
// 加载当前联系人信息到输入框
private void loadContactInfo() {
String currentName = contactManager.getContactName();
String currentPhone = contactManager.getContactPhone();
etName.setText(currentName);
etPhone.setText(currentPhone);
}
// 验证用户输入
private boolean validateInput(String name, String phone) {
if (TextUtils.isEmpty(name)) {
Toast.makeText(this, "联系人名字不能为空", Toast.LENGTH_SHORT).show();
return false;
}
if (TextUtils.isEmpty(phone)) {
Toast.makeText(this, "电话号码不能为空", Toast.LENGTH_SHORT).show();
return false;
}
if (!phone.matches("\\d{11}")) { // 简单验证11位数字
Toast.makeText(this, "请输入有效的11位电话号码", Toast.LENGTH_SHORT).show();
return false;
}
return true;
}
}

@ -0,0 +1,4 @@
package com.example.elderlycaresystem2;
public class ContactData {
}

@ -0,0 +1,37 @@
// src/main/java/com/example/elderlycaresystem2/ContactManager.java
package com.example.elderlycaresystem2;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
public class ContactManager {
private static final String KEY_CONTACT_NAME = "contact_name";
private static final String KEY_CONTACT_PHONE = "contact_phone";
private SharedPreferences sharedPreferences;
public ContactManager(Context context) {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
}
// 获取联系人名字
public String getContactName() {
return sharedPreferences.getString(KEY_CONTACT_NAME, "紧急联系人");
}
// 获取联系人电话
public String getContactPhone() {
return sharedPreferences.getString(KEY_CONTACT_PHONE, "110");
}
// 设置联系人名字
public void setContactName(String name) {
sharedPreferences.edit().putString(KEY_CONTACT_NAME, name).apply();
}
// 设置联系人电话
public void setContactPhone(String phone) {
sharedPreferences.edit().putString(KEY_CONTACT_PHONE, phone).apply();
}
}

@ -0,0 +1,363 @@
// src/main/java/com/example/elderlycaresystem2/MainActivity.java
package com.example.elderlycaresystem2;
import android.Manifest;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class DetectionActivity extends AppCompatActivity implements SensorEventListener,View.OnClickListener {
private LinearLayout btn_talk;
private LinearLayout btn_main;
private LinearLayout btn_user;
private static final String TAG = "MainActivity";
private static final int REQUEST_CALL_PERMISSION = 100;
private SensorManager sensorManager;
private Sensor accelerometer;
private Sensor gyroscope;
private TextView statusTextView;
private Button buttonToggleDetection;
// 阈值参数
private final double FALL_THRESHOLD_LOW = 2.0; // 加速度低阈值
private final double FALL_THRESHOLD_HIGH = 12.0; // 加速度高阈值
private final double ROTATION_THRESHOLD = 5.0; // 陀螺仪旋转变化阈值
private boolean isFalling = false; // 跌倒标志位
private boolean hasFallen = false; // 防止多次触发
private boolean isDetectionEnabled = true; // 跌倒检测是否开启
// 倒计时相关
private Handler handler = new Handler(Looper.getMainLooper());
private Runnable autoCallRunnable;
private int countdownSeconds = 10; // 倒计时秒数
// 紧急联系人管理
private ContactManager contactManager;
// 用于标记权限请求是否是由跌倒检测触发
private boolean isPermissionRequestedForFall = false;
// SharedPreferences 键
private static final String PREF_DETECTION_ENABLED = "pref_detection_enabled";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detection); // 确保布局文件名为 activity_main.xml
// 初始化 ContactManager
contactManager = new ContactManager(this);
// 初始化TextView用于显示状态
statusTextView = findViewById(R.id.statusTextView); // 确保 ID 一致
// 初始化按钮
buttonToggleDetection = findViewById(R.id.switch_toggle_detection);
// 初始化传感器管理器
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
btn_talk = findViewById(R.id.btn_talk);
btn_main = findViewById(R.id.btn_main);
btn_user = findViewById(R.id.btn_user);
// 给开关按钮设置选择监听器一旦用户点击它就触发监听器的onCheckedChanged方法
//底部导航栏
btn_talk.setOnClickListener(this);
btn_main.setOnClickListener(this);
btn_user.setOnClickListener(this);
// 获取加速度计和陀螺仪传感器
if (sensorManager != null) {
accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
gyroscope = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
}
// 读取检测状态
SharedPreferences sharedPreferences = getSharedPreferences("app_prefs", MODE_PRIVATE);
isDetectionEnabled = sharedPreferences.getBoolean(PREF_DETECTION_ENABLED, true);
updateDetectionUI();
// 设置按钮点击事件
buttonToggleDetection.setOnClickListener(view -> {
isDetectionEnabled = !isDetectionEnabled;
// 保存检测状态
sharedPreferences.edit().putBoolean(PREF_DETECTION_ENABLED, isDetectionEnabled).apply();
// 更新UI和传感器监听器
updateDetectionUI();
});
}
@Override
protected void onResume() {
super.onResume();
// 根据检测状态注册传感器监听器
if (isDetectionEnabled) {
registerSensorListeners();
}
}
@Override
protected void onPause() {
super.onPause();
// 取消注册监听器
sensorManager.unregisterListener(this);
}
@Override
public void onSensorChanged(SensorEvent event) {
if (!isDetectionEnabled || hasFallen) {
// 检测未开启或已检测到跌倒,避免处理
return;
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
handleAccelerometerData(event.values);
} else if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
handleGyroscopeData(event.values);
}
}
private void handleAccelerometerData(float[] values) {
// 获取加速度数据
float x = values[0];
float y = values[1];
float z = values[2];
// 计算加速度的模
double totalAcceleration = Math.sqrt(x * x + y * y + z * z);
Log.d(TAG, "加速度模: " + totalAcceleration);
// 判断是否进入自由落体阶段
if (totalAcceleration < FALL_THRESHOLD_LOW) {
isFalling = true; // 标记为正在摔倒
runOnUiThread(() -> statusTextView.setText("正在摔倒... 自由落体检测到"));
} else if (isFalling && totalAcceleration > FALL_THRESHOLD_HIGH) {
// 如果之前进入自由落体阶段,且现在检测到冲击,认为是摔倒
isFalling = false; // 重置摔倒标志位
hasFallen = true; // 防止重复触发
runOnUiThread(() -> {
statusTextView.setText("摔倒检测到!正在处理...");
showFallDialog();
});
}
}
private void handleGyroscopeData(float[] values) {
// 获取陀螺仪数据
float rotationX = values[0];
float rotationY = values[1];
float rotationZ = values[2];
Log.d(TAG, "陀螺仪旋转: X=" + rotationX + ", Y=" + rotationY + ", Z=" + rotationZ);
// 判断旋转变化是否过大
if (Math.abs(rotationX) > ROTATION_THRESHOLD || Math.abs(rotationY) > ROTATION_THRESHOLD || Math.abs(rotationZ) > ROTATION_THRESHOLD) {
runOnUiThread(() -> statusTextView.setText("陀螺仪检测到异常旋转!"));
showFallDialog();
}
}
private void showFallDialog() {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("跌倒警报");
builder.setMessage("检测到跌倒,是否拨打紧急联系人电话?");
builder.setPositiveButton("是", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 取消自动拨打
handler.removeCallbacks(autoCallRunnable);
// 拨打电话
makeEmergencyCall();
}
});
builder.setNegativeButton("否", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
// 取消自动拨打
handler.removeCallbacks(autoCallRunnable);
dialog.dismiss();
hasFallen = false; // 允许再次触发
runOnUiThread(() -> statusTextView.setText("摔倒检测取消"));
}
});
builder.setCancelable(false); // 不允许点击外部取消
AlertDialog alertDialog = builder.create();
alertDialog.show();
// 启动倒计时任务,倒计时结束后自动拨打电话
startAutoCallCountdown();
}
private void startAutoCallCountdown() {
autoCallRunnable = new Runnable() {
int remainingSeconds = countdownSeconds;
@Override
public void run() {
if (remainingSeconds > 0) {
runOnUiThread(() -> statusTextView.setText("倒计时 " + remainingSeconds + " 秒后自动拨打紧急电话"));
remainingSeconds--;
handler.postDelayed(this, 1000);
} else {
makeEmergencyCall();
}
}
};
handler.post(autoCallRunnable);
}
private void makeEmergencyCall() {
String emergencyNumber = contactManager.getContactPhone(); // 使用 ContactManager 获取号码
if (emergencyNumber == null || emergencyNumber.isEmpty()) {
Toast.makeText(this, "紧急联系人号码未设置", Toast.LENGTH_SHORT).show();
return;
}
// 检查拨打电话权限
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "未授予拨打电话权限", Toast.LENGTH_SHORT).show();
// 仅在跌倒检测触发时请求权限
isPermissionRequestedForFall = true;
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CALL_PHONE}, REQUEST_CALL_PERMISSION);
return;
}
// 拨打电话
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + emergencyNumber));
callIntent.putExtra("com.android.phone.extra.slot", 0); // simSlotIndex为0或1
try {
startActivity(callIntent);
} catch (SecurityException e) {
Log.e(TAG, "拨打电话失败: " + e.getMessage());
Toast.makeText(this, "拨打电话失败,请检查权限设置", Toast.LENGTH_SHORT).show();
}
}
// 处理权限请求结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_CALL_PERMISSION) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (isPermissionRequestedForFall) {
isPermissionRequestedForFall = false;
// 权限授予后,尝试拨打电话
makeEmergencyCall();
}
} else {
Toast.makeText(this, "未授予拨打电话权限,无法自动拨打紧急电话", Toast.LENGTH_SHORT).show();
}
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
// 可根据需要处理传感器精度变化
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// 不需要处理
}
// 菜单相关代码
@Override
public boolean onCreateOptionsMenu(android.view.Menu menu) {
// Inflate the menu; 这将把 menu_main.xml 添加到 ActionBar
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(@NonNull android.view.MenuItem item) {
// 处理 ActionBar 的项目点击事件
int id = item.getItemId();
if (id == R.id.action_settings) {
// 启动 ContactActivity
Intent intent = new Intent(this, ContactActivity.class);
startActivity(intent);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
*
*/
private void registerSensorListeners() {
if (accelerometer != null) {
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
if (gyroscope != null) {
sensorManager.registerListener(this, gyroscope, SensorManager.SENSOR_DELAY_NORMAL);
}
Toast.makeText(this, "跌倒检测已开启", Toast.LENGTH_SHORT).show();
buttonToggleDetection.setText("关闭跌倒检测");
statusTextView.setText("跌倒检测已开启");
}
/**
*
*/
private void unregisterSensorListeners() {
sensorManager.unregisterListener(this);
Toast.makeText(this, "跌倒检测已关闭", Toast.LENGTH_SHORT).show();
buttonToggleDetection.setText("开启跌倒检测");
statusTextView.setText("跌倒检测已关闭");
}
/**
* UI
*/
private void updateDetectionUI() {
if (isDetectionEnabled) {
registerSensorListeners();
} else {
unregisterSensorListeners();
}
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_talk) {
Intent intent = new Intent(DetectionActivity.this, TalkActivity.class);
startActivity(intent);
finish();
} else if (v.getId() == R.id.btn_main) {
return;
}else {
Intent intent = new Intent(DetectionActivity.this,UserActivity.class);
startActivity(intent);
finish();
}
}
}

@ -0,0 +1,4 @@
package com.example.elderlycaresystem2;
public class DialogueData {
}

@ -0,0 +1,4 @@
package com.example.elderlycaresystem2;
public class FallData {
}

@ -0,0 +1,164 @@
package com.example.elderlycaresystem2;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.preference.PreferenceManager;
import android.telephony.SmsManager;
import android.util.Log;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
import android.content.pm.PackageManager;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import java.util.Timer;
import java.util.TimerTask;
public class FallManager extends BroadcastReceiver {
private TextView countingView;
private Dialog dialog;
private Timer timer;
private SharedPreferences sharedPreferences;
private Vibrator vibrator;
private boolean isVibrate;
private MediaPlayer mediaPlayer;
private Context context;
private final String TAG = "FallLocalReceiver";
public FallManager() {
}
@Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "FallLocalReceiver.onReceive()");
this.context = context;
showAlertDialog();
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
isVibrate = sharedPreferences.getBoolean("pre_key_vibrate", true);
if (isVibrate) {
startVibrate();
}
startAlarm();
}
private void showAlertDialog() {
countingView = new TextView(context);
AlertDialog.Builder builder = new AlertDialog.Builder(context.getApplicationContext());
builder.setTitle("跌倒警报");
builder.setView(countingView);
builder.setMessage("检测到跌倒发生,是否发出警报?");
// builder.setIcon(R.drawable.ic_warning); 《图标资源》
builder.setNegativeButton("取消", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
timer.cancel();
dialog.dismiss();
if (isVibrate) {
stopVibrate();
}
stopAlarm();
}
});
dialog = builder.create();
dialog.setCanceledOnTouchOutside(false);
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
countDown();
dialog.show();
Log.d(TAG, "dialog.create()");
}
private void countDown() {
timer = new Timer();
TimerTask timerTask = new TimerTask() {
int countTime = 10;
@Override
public void run() {
if (countTime > 0) {
countTime--;
}
Message msgTime = handler.obtainMessage();
msgTime.arg1 = countTime;
handler.sendMessage(msgTime);
}
};
timer.schedule(timerTask, 50, 1000);
}
public Handler handler = new Handler() {
@SuppressLint("HandlerLeak")
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
if (msg.arg1 > 0) {
countingView.setText(msg.arg1 + "秒后自动拨打紧急联系人电话");
} else {
if (dialog != null) {
dialog.dismiss();
if (isVibrate) {
stopVibrate();
}
stopAlarm();
checkCallPermission(); // 倒计时结束自动拨打电话
}
timer.cancel();
}
}
};
private void startVibrate() {
vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
long[] pattern = {100, 500, 100, 500};
vibrator.vibrate(pattern, 2);
}
private void stopVibrate() {
vibrator.cancel();
}
private void startAlarm() {
String ringtone = sharedPreferences.getString("pre_key_alarm", null);
Uri ringtoneUri = Uri.parse(ringtone);
mediaPlayer = MediaPlayer.create(context, ringtoneUri);
mediaPlayer.setLooping(true); // 设置循环
mediaPlayer.start();
}
private void stopAlarm() {
if (mediaPlayer != null) {
mediaPlayer.stop();
mediaPlayer.release();
}
}
private void checkCallPermission() {
String phoneNum = sharedPreferences.getString("pre_key_phone", null);
if (phoneNum != null && !phoneNum.isEmpty()) {
Intent callIntent = new Intent(Intent.ACTION_CALL);
callIntent.setData(Uri.parse("tel:" + phoneNum));
// 检查权限
if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.CALL_PHONE) == PackageManager.PERMISSION_GRANTED) {
context.startActivity(callIntent);
} else {
Toast.makeText(context, "请授予拨打电话权限", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(context, "没有设置紧急联系人号码", Toast.LENGTH_SHORT).show();
}
}
}

@ -0,0 +1,47 @@
package com.example.elderlycaresystem2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.elderlycaresystem2.databinding.FragmentFirstBinding;
public class FirstFragment extends Fragment {
private FragmentFirstBinding binding;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentFirstBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonFirst.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(FirstFragment.this)
.navigate(R.id.action_FirstFragment_to_SecondFragment);
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,76 @@
package com.example.elderlycaresystem2;
import android.os.Bundle;
import com.google.android.material.snackbar.Snackbar;
import androidx.appcompat.app.AppCompatActivity;
import android.view.View;
import androidx.navigation.NavController;
import androidx.navigation.Navigation;
import androidx.navigation.ui.AppBarConfiguration;
import androidx.navigation.ui.NavigationUI;
import com.example.elderlycaresystem2.databinding.ActivityMainBinding;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
private AppBarConfiguration appBarConfiguration;
private ActivityMainBinding binding;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
setSupportActionBar(binding.toolbar);
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public boolean onSupportNavigateUp() {
NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
return NavigationUI.navigateUp(navController, appBarConfiguration)
|| super.onSupportNavigateUp();
}
}

@ -0,0 +1,34 @@
package com.example.elderlycaresystem2;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Message {
private String role;
private String content;
public Message() {
}
public Message(String role, String content) {
this.role = role;
this.content = content;
}
// Getters 和 Setters
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}

@ -0,0 +1,4 @@
package com.example.elderlycaresystem2;
public class MessageManager {
}

@ -0,0 +1,115 @@
package com.example.elderlycaresystem2; // 请替换为您的实际包名
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import java.util.List;
public class MessagesAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
private List<Message> messages;
private static final int VIEW_TYPE_USER = 1;
private static final int VIEW_TYPE_ASSISTANT = 2;
private static final int VIEW_TYPE_SYSTEM = 3;
public MessagesAdapter(List<Message> messages) {
this.messages = messages;
}
@Override
public int getItemViewType(int position) {
String role = messages.get(position).getRole();
switch (role) {
case "user":
return VIEW_TYPE_USER;
case "assistant":
return VIEW_TYPE_ASSISTANT;
case "system":
return VIEW_TYPE_SYSTEM;
default:
return VIEW_TYPE_ASSISTANT;
}
}
@NonNull
@Override
public RecyclerView.ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
View view;
if(viewType == VIEW_TYPE_USER){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_sent, parent, false);
return new UserMessageViewHolder(view);
} else if(viewType == VIEW_TYPE_ASSISTANT){
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_received, parent, false);
return new AssistantMessageViewHolder(view);
} else { // VIEW_TYPE_SYSTEM
view = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_message_system, parent, false);
return new SystemMessageViewHolder(view);
}
}
@Override
public void onBindViewHolder(@NonNull RecyclerView.ViewHolder holder, int position) {
Message message = messages.get(position);
if(holder.getItemViewType() == VIEW_TYPE_USER){
((UserMessageViewHolder) holder).bind(message);
} else if(holder.getItemViewType() == VIEW_TYPE_ASSISTANT){
((AssistantMessageViewHolder) holder).bind(message);
} else { // VIEW_TYPE_SYSTEM
((SystemMessageViewHolder) holder).bind(message);
}
}
@Override
public int getItemCount() {
return messages.size();
}
// ViewHolder for user messages
public class UserMessageViewHolder extends RecyclerView.ViewHolder {
TextView textViewMessage;
public UserMessageViewHolder(@NonNull View itemView) {
super(itemView);
textViewMessage = itemView.findViewById(R.id.textViewMessage);
}
void bind(Message message){
textViewMessage.setText(message.getContent());
}
}
// ViewHolder for assistant messages
public class AssistantMessageViewHolder extends RecyclerView.ViewHolder {
TextView textViewMessage;
public AssistantMessageViewHolder(@NonNull View itemView) {
super(itemView);
textViewMessage = itemView.findViewById(R.id.textViewMessage);
}
void bind(Message message){
textViewMessage.setText(message.getContent());
}
}
// ViewHolder for system messages
public class SystemMessageViewHolder extends RecyclerView.ViewHolder {
TextView textViewMessage;
public SystemMessageViewHolder(@NonNull View itemView) {
super(itemView);
textViewMessage = itemView.findViewById(R.id.textViewMessage);
}
void bind(Message message){
textViewMessage.setText(message.getContent());
// 可以设置不同的样式,例如居中显示,淡色等
}
}
}

@ -0,0 +1,65 @@
package com.example.elderlycaresystem2; // 请替换为您的实际包名
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.logging.HttpLoggingInterceptor;
import retrofit2.Retrofit;
import retrofit2.converter.jackson.JacksonConverterFactory;
import java.io.IOException;
public class RetrofitClient {
private static final String BASE_URL = "https://openkey.cloud/"; // 确保以斜杠结尾
private static RetrofitClient instance;
private ApiService apiService;
private static final String API_KEY = "sk-ZoGHErXVBPukGFAW0f4f88C51cD84717AfEaBd70A9B7E49d"; // 请替换为您的新API密钥
private RetrofitClient() {
// 日志拦截器(可选,用于调试)
HttpLoggingInterceptor logging = new HttpLoggingInterceptor();
logging.setLevel(HttpLoggingInterceptor.Level.BODY);
// 添加 Authorization 拦截器
Interceptor authorizationInterceptor = new Interceptor() {
@Override
public Response intercept(Chain chain) throws IOException {
Request originalRequest = chain.request();
Request.Builder builder = originalRequest.newBuilder()
.header("Authorization", "Bearer " + API_KEY)
.header("Content-Type", "application/json");
Request newRequest = builder.build();
return chain.proceed(newRequest);
}
};
// 创建 OkHttpClient
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(authorizationInterceptor)
.addInterceptor(logging)
.build();
// 创建 Retrofit 实例
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(JacksonConverterFactory.create())
.client(client)
.build();
// 创建 API 服务
apiService = retrofit.create(ApiService.class);
}
public static synchronized RetrofitClient getInstance(){
if(instance == null){
instance = new RetrofitClient();
}
return instance;
}
public ApiService getApiService(){
return apiService;
}
}

@ -0,0 +1,47 @@
package com.example.elderlycaresystem2;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.navigation.fragment.NavHostFragment;
import com.example.elderlycaresystem2.databinding.FragmentSecondBinding;
public class SecondFragment extends Fragment {
private FragmentSecondBinding binding;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState
) {
binding = FragmentSecondBinding.inflate(inflater, container, false);
return binding.getRoot();
}
public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
binding.buttonSecond.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
NavHostFragment.findNavController(SecondFragment.this)
.navigate(R.id.action_SecondFragment_to_FirstFragment);
}
});
}
@Override
public void onDestroyView() {
super.onDestroyView();
binding = null;
}
}

@ -0,0 +1,155 @@
package com.example.elderlycaresystem2;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.example.elderlycaresystem2.MessageManager;
import java.util.ArrayList;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class TalkActivity extends AppCompatActivity implements View.OnClickListener{
private RecyclerView recyclerViewMessages;
private EditText editTextMessage;
private Button buttonSend;
private MessagesAdapter adapter;
private ArrayList<Message> messagesList;
private ApiService apiService;
private LinearLayout btn_talk;
private LinearLayout btn_main;
private LinearLayout btn_user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_talk); // 确保布局文件名正确
recyclerViewMessages = findViewById(R.id.recyclerViewMessages);
editTextMessage = findViewById(R.id.editTextMessage);
buttonSend = findViewById(R.id.buttonSend);
messagesList = new ArrayList<>();
adapter = new MessagesAdapter(messagesList);
recyclerViewMessages.setAdapter(adapter);
recyclerViewMessages.setLayoutManager(new LinearLayoutManager(this));
apiService = RetrofitClient.getInstance().getApiService();
btn_talk = findViewById(R.id.btn_talk);
btn_main = findViewById(R.id.btn_main);
btn_user = findViewById(R.id.btn_user);
// 给开关按钮设置选择监听器一旦用户点击它就触发监听器的onCheckedChanged方法
//底部导航栏
btn_talk.setOnClickListener(this);
btn_main.setOnClickListener(this);
btn_user.setOnClickListener(this);
// 初始化对话,系统提示
addSystemMessage("这是一个专注于老人的助手,可以帮助你解决一些问题。");
buttonSend.setOnClickListener(view -> {
String messageText = editTextMessage.getText().toString().trim();
if(!TextUtils.isEmpty(messageText)){
sendMessage(messageText);
editTextMessage.setText("");
}
});
}
private void addSystemMessage(String content) {
Message systemMessage = new Message("system", content);
messagesList.add(systemMessage);
adapter.notifyItemInserted(messagesList.size() - 1);
recyclerViewMessages.scrollToPosition(messagesList.size() - 1);
Log.d("TalkActivity", "系统消息添加: " + content); // 添加日志
}
private void sendMessage(String messageText){
// 添加发送的消息到列表
Message userMessage = new Message("user", messageText);
messagesList.add(userMessage);
adapter.notifyItemInserted(messagesList.size() - 1);
recyclerViewMessages.scrollToPosition(messagesList.size() - 1);
Log.d("TalkActivity", "用户消息添加: " + messageText); // 添加日志
// 隐藏键盘
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm != null) {
imm.hideSoftInputFromWindow(editTextMessage.getWindowToken(), 0);
}
// 创建 AIRequest 对象
AIRequest request = new AIRequest("gpt-3.5-turbo", 0.7, messagesList);
// 发送请求
Call<AIResponse> call = apiService.getAIReply(request);
call.enqueue(new Callback<AIResponse>() {
@Override
public void onResponse(Call<AIResponse> call, Response<AIResponse> response) {
if(response.isSuccessful() && response.body() != null){
AIResponse aiResponse = response.body();
if(aiResponse.getChoices() != null && !aiResponse.getChoices().isEmpty()){
String reply = aiResponse.getChoices().get(0).getMessage().getContent();
Log.d("TalkActivity", "AI 回复: " + reply); // 添加日志
// 添加助手的回复到消息列表
Message assistantMessage = new Message("assistant", reply);
messagesList.add(assistantMessage);
// 确保在主线程中更新 UI
runOnUiThread(() -> {
adapter.notifyItemInserted(messagesList.size() - 1);
recyclerViewMessages.scrollToPosition(messagesList.size() - 1);
Log.d("TalkActivity", "AI 回复已添加到列表"); // 添加日志
});
} else {
showError("AI 回复为空。");
Log.e("TalkActivity", "AI 回复为空。");
}
} else {
showError("AI 回复失败,请稍后再试。");
Log.e("TalkActivity", "AI 回复失败,状态码:" + response.code() + ",响应体:" + response.body());
}
}
@Override
public void onFailure(Call<AIResponse> call, Throwable t) {
showError("网络错误,请检查连接。");
Log.e("TalkActivity", "网络错误", t);
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_talk) {
return;
} else if (v.getId() == R.id.btn_main) {
Intent intent = new Intent(TalkActivity.this,DetectionActivity.class);
startActivity(intent);
finish();
}else {
Intent intent = new Intent(TalkActivity.this, UserActivity.class);
startActivity(intent);
finish();
}
}
private void showError(String message){
Toast.makeText(TalkActivity.this, message, Toast.LENGTH_SHORT).show();
}
}

@ -0,0 +1,69 @@
package com.example.elderlycaresystem2;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
public class UserActivity extends AppCompatActivity implements View.OnClickListener {
private LinearLayout btn_talk;
private LinearLayout btn_main;
private LinearLayout btn_user;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user);
Button modifyContactButton = findViewById(R.id.modify_contact_button);
Button logoutButton = findViewById(R.id.logout_button);
btn_talk = findViewById(R.id.btn_talk);
btn_main = findViewById(R.id.btn_main);
btn_user = findViewById(R.id.btn_user);
// 给开关按钮设置选择监听器一旦用户点击它就触发监听器的onCheckedChanged方法
//底部导航栏
btn_talk.setOnClickListener(this);
btn_main.setOnClickListener(this);
btn_user.setOnClickListener(this);
modifyContactButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 处理修改紧急联系人逻辑
Toast.makeText(UserActivity.this, "修改紧急联系人", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(UserActivity.this, ContactActivity.class);
startActivity(intent);
}
});
logoutButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 处理退出软件逻辑
Toast.makeText(UserActivity.this, "退出软件", Toast.LENGTH_SHORT).show();
finish();
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn_talk) {
Intent intent = new Intent(UserActivity.this, TalkActivity.class);
startActivity(intent);
finish();
} else if (v.getId() == R.id.btn_main) {
Intent intent = new Intent(UserActivity.this,DetectionActivity.class);
startActivity(intent);
finish();
}else {
return;
}
}
}

@ -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,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#E5E5EA"/>
<corners android:radius="16dp"/>
</shape>

@ -0,0 +1,5 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#0084FF"/>
<corners android:radius="16dp"/>
</shape>

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#F0F0F0"/> <!-- 灰色背景 -->
<corners android:radius="8dp"/> <!-- 圆角半径 -->
</shape>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="#FFFFFF"/> <!-- 背景颜色 -->
<stroke android:width="1dp" android:color="#CCCCCC"/> <!-- 边框 -->
<corners android:radius="8dp"/> <!-- 圆角半径 -->
<padding
android:left="10dp"
android:top="10dp"
android:right="10dp"
android:bottom="10dp" />
</shape>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_focused="true" android:drawable="@drawable/shape_edit_focus"/>
<item android:drawable="@drawable/shape_edit_normal"/>
</selector>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.0 KiB

@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#ffffff" />
<stroke
android:width="3dp"
android:color="#ff0000ff" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android" >
<solid android:color="#ffffff" />
<stroke
android:width="3dp"
android:color="#ffaaaaaa" />
<corners
android:bottomLeftRadius="5dp"
android:bottomRightRadius="5dp"
android:topLeftRadius="5dp"
android:topRightRadius="5dp" />
<padding
android:bottom="2dp"
android:left="2dp"
android:right="2dp"
android:top="2dp" />
</shape>

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

@ -0,0 +1,70 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="0dp"
android:textColor="@color/black"
android:background="@color/white">
<!-- 顶部的标题栏 -->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="16dp"
android:text="紧急联系人管理"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold" />
<View
android:layout_width="match_parent"
android:layout_height="20dp" />
<EditText
android:id="@+id/et_name"
style="@style/text_normal"
android:hint="请输入联系人名字"
android:textColor="@color/black"
android:inputType="text"
android:layout_height="50dp"
android:background="@drawable/editext_selector" />
<View
android:layout_width="match_parent"
android:layout_height="20dp" />
<EditText
android:id="@+id/et_phone"
style="@style/text_normal"
android:hint="请输入电话号码"
android:textColor="@color/black"
android:inputType="number"
android:layout_height="50dp"
android:background="@drawable/editext_selector" />
<Button
android:id="@+id/btn_queding"
android:layout_width="match_parent"
android:layout_height="60dp"
android:layout_marginTop="90dp"
android:text="确认修改"
android:backgroundTint="@color/purple_500"
android:textColor="@android:color/white"
/>
<!-- 中间的功能按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
<!-- 底部导航栏 -->
</LinearLayout>

@ -0,0 +1,159 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/black"
android:background="@color/white">
<!-- 顶部的标题栏 -->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="16dp"
android:text="摔倒检测"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
android:background="#E8E8E8"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:text="跌倒检测控制"
android:textColor="@color/primary_text"
android:textSize="25sp" />
<ImageView
android:layout_width="210dp"
android:layout_height="210dp"
android:layout_gravity="center_horizontal"
android:layout_marginTop="30dp"
android:layout_marginBottom="50dp"
android:src="@drawable/home_main" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="79dp"
android:background="#BFB06C"
android:orientation="horizontal"
android:gravity="center_vertical">
<!-- 状态显示 -->
<TextView
android:id="@+id/statusTextView"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="等待跌倒检测..."
android:textSize="18sp" />
<!-- 控制跌倒检测的 Switch 按钮 -->
<Switch
android:id="@+id/switch_toggle_detection"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="开启跌倒检测"
android:textSize="20dp" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical">
</LinearLayout>
<!-- 底部导航栏 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E8E8E8"
android:orientation="horizontal"
android:weightSum="3"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/btn_talk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/talk2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聊天"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/main2"
app:tint="@android:color/holo_red_light"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主页"
android:textColor="@android:color/holo_red_light"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_user"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/user2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.material.appbar.AppBarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:theme="@style/Theme.Elderlycaresystem2.AppBarOverlay">
<androidx.appcompat.widget.Toolbar
android:id="@+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
app:popupTheme="@style/Theme.Elderlycaresystem2.PopupOverlay" />
</com.google.android.material.appbar.AppBarLayout>
<include layout="@layout/content_main" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="@+id/fab"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="bottom|end"
android:layout_marginEnd="@dimen/fab_margin"
android:layout_marginBottom="16dp"
app:srcCompat="@android:drawable/ic_dialog_email" />
</androidx.coordinatorlayout.widget.CoordinatorLayout>

@ -0,0 +1,148 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/black"
android:background="@color/white">
<!-- 顶部的标题栏 -->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="16dp"
android:text="聊天"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
android:background="#E8E8E8"
/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="2"
android:gravity="center"
android:orientation="vertical">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerViewMessages"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:padding="8dp" />
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<EditText
android:id="@+id/editTextMessage"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:hint="输入消息"
android:textColor="@color/black"
android:padding="8dp"
android:background="@drawable/edit_text_background"/>
<Button
android:id="@+id/buttonSend"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送"
android:layout_marginStart="8dp"/>
</LinearLayout>
</LinearLayout>
<!-- 底部导航栏 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E8E8E8"
android:orientation="horizontal"
android:weightSum="3"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/btn_talk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/talk2"
app:tint="@android:color/holo_red_light"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聊天"
android:textColor="@android:color/holo_red_light"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/main2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主页"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_user"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/user2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,136 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/black"
android:background="@color/white">
<!-- 顶部的标题栏 -->
<TextView
android:id="@+id/title"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="16dp"
android:text="我的"
android:textColor="@color/black"
android:textSize="20sp"
android:textStyle="bold"
android:background="#E8E8E8"
/>
<!-- 中间的功能按钮 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:gravity="center"
android:background="@color/white"
android:orientation="vertical">
<!-- 修改紧急联系人按钮 -->
<!-- 添加设备按钮 -->
<Button
android:id="@+id/modify_contact_button"
android:layout_width="350dp"
android:layout_height="80dp"
android:backgroundTint="@color/purple_500"
android:text="修改紧急联系人"
android:textSize="30dp"
android:textColor="@android:color/white" />
<!-- 退出软件按钮 -->
<Button
android:id="@+id/logout_button"
android:layout_width="350dp"
android:layout_height="80dp"
android:layout_marginTop="200dp"
android:text="退出软件"
android:textSize="30dp"
android:backgroundTint="@color/purple_500"
android:textColor="@android:color/white" />
</LinearLayout>
<!-- 底部导航栏 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#E8E8E8"
android:orientation="horizontal"
android:weightSum="3"
android:layout_alignParentBottom="true">
<LinearLayout
android:id="@+id/btn_talk"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/talk2"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="聊天"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_main"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/main2"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="主页"
android:textColor="@color/black"
android:textSize="12sp" />
</LinearLayout>
<LinearLayout
android:id="@+id/btn_user"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center"
android:orientation="vertical"
android:padding="8dp">
<ImageView
android:layout_width="24dp"
android:layout_height="24dp"
android:src="@drawable/user2"
app:tint="@android:color/holo_red_light"
/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="我的"
android:textColor="@android:color/holo_red_light"
android:textSize="12sp" />
</LinearLayout>
</LinearLayout>
</LinearLayout>

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<fragment
android:id="@+id/nav_host_fragment_content_main"
android:name="androidx.navigation.fragment.NavHostFragment"
android:layout_width="0dp"
android:layout_height="0dp"
app:defaultNavHost="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:navGraph="@navigation/nav_graph" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".FirstFragment">
<TextView
android:id="@+id/textview_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_first_fragment"
app:layout_constraintBottom_toTopOf="@id/button_first"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_first"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/next"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_first" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".SecondFragment">
<TextView
android:id="@+id/textview_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toTopOf="@id/button_second"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/button_second"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/previous"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/textview_second" />
</androidx.constraintlayout.widget.ConstraintLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@+id/textViewMessage"
android:background="@drawable/bg_message_received"
android:textColor="#000000"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="end"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@+id/textViewMessage"
android:background="@drawable/bg_message_sent"
android:textColor="#FFFFFF"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="8dp">
<TextView
android:id="@+id/textViewMessage"
android:background="@drawable/bg_system_message"
android:textColor="#888888"
android:padding="10dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>

@ -0,0 +1,10 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="com.example.elderlycaresystem2.MainActivity">
<item
android:id="@+id/action_settings"
android:orderInCategory="100"
android:title="@string/action_settings"
app:showAsAction="never" />
</menu>

@ -0,0 +1,5 @@
<?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" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?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" />
</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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/nav_graph"
app:startDestination="@id/FirstFragment">
<fragment
android:id="@+id/FirstFragment"
android:name="com.example.elderlycaresystem2.FirstFragment"
android:label="@string/first_fragment_label"
tools:layout="@layout/fragment_first">
<action
android:id="@+id/action_FirstFragment_to_SecondFragment"
app:destination="@id/SecondFragment" />
</fragment>
<fragment
android:id="@+id/SecondFragment"
android:name="com.example.elderlycaresystem2.SecondFragment"
android:label="@string/second_fragment_label"
tools:layout="@layout/fragment_second">
<action
android:id="@+id/action_SecondFragment_to_FirstFragment"
app:destination="@id/FirstFragment" />
</fragment>
</navigation>

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

@ -0,0 +1,16 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Elderlycaresystem2" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
<!-- Primary brand color. -->
<item name="colorPrimary">@color/purple_200</item>
<item name="colorPrimaryVariant">@color/purple_700</item>
<item name="colorOnPrimary">@color/black</item>
<!-- Secondary brand color. -->
<item name="colorSecondary">@color/teal_200</item>
<item name="colorSecondaryVariant">@color/teal_200</item>
<item name="colorOnSecondary">@color/black</item>
<!-- Status bar color. -->
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
</resources>

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">200dp</dimen>
</resources>

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">48dp</dimen>
</resources>

@ -0,0 +1,22 @@
<?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">#009688</color>
<color name="primary_dark">#00897b</color>
<color name="primary_light">#B2DFDB</color>
<color name="accent">#ffb74d</color>
<color name="primary_text">#212121</color>
<color name="secondary_text">#727272</color>
<color name="icons">#FFFFFF</color>
<color name="divider">#B6B6B6</color>
<color name="window_background">#FFF5F5F5</color>
<color name="tab_bgcolor">#eeeeee</color>
<color name="home_back">#f7d280</color>
<color name="about_content">#f9cf72</color>
</resources>

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

@ -0,0 +1,12 @@
<resources>
<string name="app_name">Elderlycaresystem2</string>
<string name="action_settings">Settings</string>
<!-- Strings used for fragments for navigation -->
<string name="first_fragment_label">First Fragment</string>
<string name="second_fragment_label">Second Fragment</string>
<string name="next">Next</string>
<string name="previous">Previous</string>
<string name="hello_first_fragment">Hello first fragment</string>
<string name="hello_second_fragment">Hello second fragment. Arg: %1$s</string>
</resources>

@ -0,0 +1,18 @@
<resources>
<style name="AppTheme" parent="Theme.AppCompat.Light.NoActionBar"/>
<style name="btn_relative">
<item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:gravity">center</item>
<item name="android:textColor">@color/black</item>
<item name="android:textSize">17sp</item>
</style>
<style name="text_normal">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
<item name="android:padding">3dp</item>
</style>
</resources>

@ -0,0 +1,25 @@
<resources xmlns:tools="http://schemas.android.com/tools">
<!-- Base application theme. -->
<style name="Theme.Elderlycaresystem2" 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>
<style name="Theme.Elderlycaresystem2.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="Theme.Elderlycaresystem2.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
<style name="Theme.Elderlycaresystem2.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
</resources>

@ -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>

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save