diff --git a/doc/智能病人陪护系统——软件需求分析报告.docx b/doc/智能病人陪护系统——软件需求分析报告.docx deleted file mode 100644 index a6f7ffe..0000000 Binary files a/doc/智能病人陪护系统——软件需求分析报告.docx and /dev/null differ diff --git a/doc/智能病人陪护系统——软件需求规格说明书.pdf b/doc/智能病人陪护系统——软件需求规格说明书.pdf deleted file mode 100644 index 6f83fce..0000000 Binary files a/doc/智能病人陪护系统——软件需求规格说明书.pdf and /dev/null differ diff --git a/doc/跌倒检测系统-软件设计规格说明书.doc b/doc/跌倒检测系统-软件设计规格说明书.doc deleted file mode 100644 index 3769c78..0000000 Binary files a/doc/跌倒检测系统-软件设计规格说明书.doc and /dev/null differ diff --git a/doc/跌倒检测系统——软件设计规格说明书 .doc b/doc/跌倒检测系统——软件设计规格说明书 .doc new file mode 100644 index 0000000..6239cd0 Binary files /dev/null and b/doc/跌倒检测系统——软件设计规格说明书 .doc differ diff --git a/doc/跌倒检测系统——软件需求分析报告.docx b/doc/跌倒检测系统——软件需求分析报告.docx new file mode 100644 index 0000000..05f6ce8 Binary files /dev/null and b/doc/跌倒检测系统——软件需求分析报告.docx differ diff --git a/model/1.txt b/model/1.txt deleted file mode 100644 index cd08755..0000000 --- a/model/1.txt +++ /dev/null @@ -1 +0,0 @@ -Hello world! diff --git a/model/Architecture.svg b/model/Architecture.svg new file mode 100644 index 0000000..0990c05 --- /dev/null +++ b/model/Architecture.svg @@ -0,0 +1 @@ +界面层MonitoringUICamCtrlUILoginUIGsensorUISettingUIGuidingUI业务逻辑层MonitorManagerCamCtrlManagerLoginManagerGsensorManagerSettingManagerGuidingManager基础服务层<<OSS>>AndroidCamRosNode请求/应答通知请求/应答通知<<subsystem>>MotionDetection \ No newline at end of file diff --git a/model/UseCase.svg b/model/UseCase.svg new file mode 100644 index 0000000..f321a79 --- /dev/null +++ b/model/UseCase.svg @@ -0,0 +1 @@ +用户跌倒检测系统登录目标追踪跌倒检测摄像头报警等应急反《包含》传感器系统管理员系统设置 \ No newline at end of file diff --git a/model/deploy.svg b/model/deploy.svg new file mode 100644 index 0000000..ae1d17d --- /dev/null +++ b/model/deploy.svg @@ -0,0 +1 @@ +<<device>>前端<<artifact>>MonitorApp.apk<<OS>>Android<<server>>后端计算节点 <<artifact>>Hmtracking<<artifact>>G-sensor<<OSL>>OpenCV<<OS>>Yolov5<<OSS>>Pytorch<<device>>摄像头Cam摄像头 \ No newline at end of file diff --git a/model/interaction.svg b/model/interaction.svg new file mode 100644 index 0000000..92b23ce --- /dev/null +++ b/model/interaction.svg @@ -0,0 +1 @@ +StuDBOpenposerequestresponseMonitoringUIisDBValidStuResultDalalTriggsG-sensorUIresponseresponseresponse \ No newline at end of file diff --git a/model/order.svg b/model/order.svg new file mode 100644 index 0000000..6168944 --- /dev/null +++ b/model/order.svg @@ -0,0 +1 @@ +<<controller>>FallSensorManager<<controller>>Fall<<entity>>MainActivity<<controller>>Emergence发送传感器参数调用跌倒检测算法获取目标检测数据判断是否存在跌倒特征 \ No newline at end of file diff --git a/model/system.svg b/model/system.svg new file mode 100644 index 0000000..ce787ea --- /dev/null +++ b/model/system.svg @@ -0,0 +1 @@ +<<subsystem>>MonitorApp<<subsystem>>G-sensor<<subsystem>>MotionDetection<<subsystem>>TerminalInteraction<<subsystem>>CamCtrl请求获取人体行为状态以及通过内置重力加速度传感器展示人体重心变化等的状况信息,也可通过云端对摄像头进行控制旋转或者指定自动巡航检测人体是否存在摔倒特征,进而结合前者手机重力传感器综合检测分析人体摔倒的发生,在摔倒发生后主动与手机交互,手机实现自动报警或拨打就医电话等用于实现终端和摄像头进行交互 \ No newline at end of file diff --git a/model/需求规格说明书/pc端界面图.png b/model/需求规格说明书/pc端界面图.png new file mode 100644 index 0000000..b290257 Binary files /dev/null and b/model/需求规格说明书/pc端界面图.png differ diff --git a/model/需求规格说明书/主界面.png b/model/需求规格说明书/主界面.png new file mode 100644 index 0000000..4dc8434 Binary files /dev/null and b/model/需求规格说明书/主界面.png differ diff --git a/model/需求规格说明书/引导界面.jpg b/model/需求规格说明书/引导界面.jpg new file mode 100644 index 0000000..b9f61fd Binary files /dev/null and b/model/需求规格说明书/引导界面.jpg differ diff --git a/model/需求规格说明书/添加联系人界面.png b/model/需求规格说明书/添加联系人界面.png new file mode 100644 index 0000000..2985b0d Binary files /dev/null and b/model/需求规格说明书/添加联系人界面.png differ diff --git a/model/需求规格说明书/联系人界面图.png b/model/需求规格说明书/联系人界面图.png new file mode 100644 index 0000000..d76c16d Binary files /dev/null and b/model/需求规格说明书/联系人界面图.png differ diff --git a/model/需求规格说明书/跌倒提醒界面图 - 副本.png b/model/需求规格说明书/跌倒提醒界面图 - 副本.png new file mode 100644 index 0000000..aa76dd6 Binary files /dev/null and b/model/需求规格说明书/跌倒提醒界面图 - 副本.png differ diff --git a/src/FallSafety/.gitignore b/src/FallSafety/.gitignore new file mode 100644 index 0000000..603b140 --- /dev/null +++ b/src/FallSafety/.gitignore @@ -0,0 +1,14 @@ +*.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 diff --git a/src/FallSafety/.idea/.gitignore b/src/FallSafety/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/src/FallSafety/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/src/FallSafety/.idea/codeStyles/Project.xml b/src/FallSafety/.idea/codeStyles/Project.xml new file mode 100644 index 0000000..681f41a --- /dev/null +++ b/src/FallSafety/.idea/codeStyles/Project.xml @@ -0,0 +1,116 @@ + + + + + + + +
+ + + + xmlns:android + + ^$ + + + +
+
+ + + + xmlns:.* + + ^$ + + + BY_NAME + +
+
+ + + + .*:id + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + .*:name + + http://schemas.android.com/apk/res/android + + + +
+
+ + + + name + + ^$ + + + +
+
+ + + + style + + ^$ + + + +
+
+ + + + .* + + ^$ + + + BY_NAME + +
+
+ + + + .* + + http://schemas.android.com/apk/res/android + + + ANDROID_ATTRIBUTE_ORDER + +
+
+ + + + .* + + .* + + + BY_NAME + +
+
+
+
+
+
\ No newline at end of file diff --git a/src/FallSafety/.idea/compiler.xml b/src/FallSafety/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/src/FallSafety/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/deploymentTargetDropDown.xml b/src/FallSafety/.idea/deploymentTargetDropDown.xml new file mode 100644 index 0000000..eaec1b9 --- /dev/null +++ b/src/FallSafety/.idea/deploymentTargetDropDown.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/gradle.xml b/src/FallSafety/.idea/gradle.xml new file mode 100644 index 0000000..526b4c2 --- /dev/null +++ b/src/FallSafety/.idea/gradle.xml @@ -0,0 +1,20 @@ + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/jarRepositories.xml b/src/FallSafety/.idea/jarRepositories.xml new file mode 100644 index 0000000..a5f05cd --- /dev/null +++ b/src/FallSafety/.idea/jarRepositories.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/misc.xml b/src/FallSafety/.idea/misc.xml new file mode 100644 index 0000000..4cae896 --- /dev/null +++ b/src/FallSafety/.idea/misc.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/render.experimental.xml b/src/FallSafety/.idea/render.experimental.xml new file mode 100644 index 0000000..8ec256a --- /dev/null +++ b/src/FallSafety/.idea/render.experimental.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/src/FallSafety/.idea/sonarlint/issuestore/0/5/05efc8b1657769a27696d478ded1e95f38737233 b/src/FallSafety/.idea/sonarlint/issuestore/0/5/05efc8b1657769a27696d478ded1e95f38737233 new file mode 100644 index 0000000..e69de29 diff --git a/src/FallSafety/.idea/sonarlint/issuestore/0/7/0712df971a99ac4d2fccb8e0fb19f377f3374cca b/src/FallSafety/.idea/sonarlint/issuestore/0/7/0712df971a99ac4d2fccb8e0fb19f377f3374cca new file mode 100644 index 0000000..e69de29 diff --git a/src/FallSafety/.idea/sonarlint/issuestore/1/b/1bde2df39dafd6172c4acd09bb6ab162d1b564f3 b/src/FallSafety/.idea/sonarlint/issuestore/1/b/1bde2df39dafd6172c4acd09bb6ab162d1b564f3 new file mode 100644 index 0000000..e95c11d --- /dev/null +++ b/src/FallSafety/.idea/sonarlint/issuestore/1/b/1bde2df39dafd6172c4acd09bb6ab162d1b564f3 @@ -0,0 +1,15 @@ + +f +java:S1301*"KReplace this "switch" statement by "if" statements to increase readability.(ד +P java:S110" +O java:S106"9Replace this use of System.out or System.err by a logger.( + +java:S1186"Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.( +V java:S110"Declare "y" and all following declarations on a separate line.(ԕ +W +java:S1659%"ADeclare "medY" and all following declarations on a separate line.(ߞ +o +java:S1450#"YRemove the "mSensorAcc" field and declare it as a local variable in the relevant methods.( +` +java:S1124="EReorder the modifiers to comply with the Java Language Specification.(䊮 +[ +java:S1124>"EReorder the modifiers to comply with the Java Language Specification.(݊ +N java:S106V"9Replace this use of System.out or System.err by a logger.(ِ +S java:S106^"9Replace this use of System.out or System.err by a logger.(Ϻ +N java:S106z"9Replace this use of System.out or System.err by a logger.(л +O +java:S1854"8Remove this useless assignment to local variable "acel".( +@ +java:S1481")Remove this unused "acel" local variable.( +K +java:S1144"/Remove this unused private "crearNotif" method.(ˡ +W +java:S1144";Remove this unused private "crearCanalNotificacion" method.(É \ No newline at end of file diff --git a/src/FallSafety/.idea/sonarlint/issuestore/9/7/976d53529601c2301bf234ecaf0dfa80efd4d05f b/src/FallSafety/.idea/sonarlint/issuestore/9/7/976d53529601c2301bf234ecaf0dfa80efd4d05f new file mode 100644 index 0000000..e69de29 diff --git a/src/FallSafety/.idea/sonarlint/issuestore/9/e/9e08934d811afe28fbc77aaa3c0d747b94348db9 b/src/FallSafety/.idea/sonarlint/issuestore/9/e/9e08934d811afe28fbc77aaa3c0d747b94348db9 new file mode 100644 index 0000000..e69de29 diff --git a/src/FallSafety/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302 b/src/FallSafety/.idea/sonarlint/issuestore/a/5/a5cc2925ca8258af241be7e5b0381edf30266302 new file mode 100644 index 0000000..e69de29 diff --git a/src/FallSafety/.idea/sonarlint/issuestore/b/9/b985de2409fd2f293c2d4c9b033860b3f0fb6816 b/src/FallSafety/.idea/sonarlint/issuestore/b/9/b985de2409fd2f293c2d4c9b033860b3f0fb6816 new file mode 100644 index 0000000..207d55e --- /dev/null +++ b/src/FallSafety/.idea/sonarlint/issuestore/b/9/b985de2409fd2f293c2d4c9b033860b3f0fb6816 @@ -0,0 +1,9 @@ + +V java:S110"Remove this unused import 'android.content.pm.PackageManager'.( +F +java:S1659"+Declare "mTelefonoText" on a separate line.( +F +java:S1172v"+Remove this unused method parameter "view".( +H +java:S1128 +"-Remove this unused import 'android.os.Build'.(Ǥ +F +java:S1172k"+Remove this unused method parameter "view".( +M +java:S1481("2Remove this unused "confirmButton" local variable.( +J +java:S1066V"/Merge this if statement with the enclosing one.( \ No newline at end of file diff --git a/src/FallSafety/.idea/sonarlint/issuestore/e/a/ea375f37886bafe63f95ef39e765923c1380607f b/src/FallSafety/.idea/sonarlint/issuestore/e/a/ea375f37886bafe63f95ef39e765923c1380607f new file mode 100644 index 0000000..87d7578 --- /dev/null +++ b/src/FallSafety/.idea/sonarlint/issuestore/e/a/ea375f37886bafe63f95ef39e765923c1380607f @@ -0,0 +1,20 @@ + +P +java:S1161x":Add the "@Override" annotation above this method signature( +B +java:S1172"+Remove this unused method parameter "view".( +d java:S100"NRename this method name to match the regular expression '^[a-z][a-zA-Z0-9]*$'.( +D +java:S1066|"/Merge this if statement with the enclosing one.(Ƕ( + +java:S1186&"Add a nested comment explaining why this method is empty, throw an UnsupportedOperationException or complete the implementation.( +U +java:S1854;":Remove this useless assignment to local variable "mRowId".( +Q java:S110"app/src/main/java/com/example/fallsafety/PostFallDetected.java,1\b\1bde2df39dafd6172c4acd09bb6ab162d1b564f3 +j +:app/src/main/java/com/example/fallsafety/EditActivity.java,d\d\dd1ca85ccab4875ceabface9e43219792c8be9c3 +T +$.idea/modules/app/FallSafety.app.iml,9\7\976d53529601c2301bf234ecaf0dfa80efd4d05f +r +B.idea/libraries/Gradle__androidx_appcompat_appcompat_1_2_0_aar.xml,b\a\ba1ffd1a9040a917162df3da1563e36410b4a33b +m +=app/src/test/java/com/example/fallsafety/ExampleUnitTest.java,5\6\568a87091bc33befac86bcc677e70c7e9868c5ff +L +.idea/codeStyles/Project.xml,6\e\6ecd6000a7b6f4a2884412ff19f74193ed089648 +p +@.idea/libraries/Gradle__androidx_activity_activity_1_0_0_aar.xml,4\8\48fd53478cffefbba80fa711af4c2c369c8641fd +n +>app/src/main/java/com/example/fallsafety/ContactsActivity.java,b\9\b985de2409fd2f293c2d4c9b033860b3f0fb6816 +: + +.gitignore,a\5\a5cc2925ca8258af241be7e5b0381edf30266302 +A +gradle.properties,2\a\2afbb999f001938c88fa43fc2ef52abf0f8213e4 +7 +gradlew,5\b\5bbfa66edb4db3c7c33c5181f43510990d3307f9 +; + gradlew.bat,2\a\2a45a911a8f1836b0b6c5b758962572012d8f8c3 +@ +local.properties,0\7\0712df971a99ac4d2fccb8e0fb19f377f3374cca +? +settings.gradle,0\5\05efc8b1657769a27696d478ded1e95f38737233 +> +app/.gitignore,5\1\51e1c5d383dfaa35e0e7e5873a0a99355a86880f +F +app/proguard-rules.pro,9\e\9e08934d811afe28fbc77aaa3c0d747b94348db9 +g +7app/src/main/java/com/example/fallsafety/AppWidget.java,3\9\39a15e2d95c0634318403cc36976da21b44cbdfe +@ +app/build.gradle,f\4\f4a01d6a4fcb971362ec00a83903fd3902f52164 +< + build.gradle,f\0\f07866736216be0ee2aba49e392191aeae700a35 +k +;app/src/main/java/com/example/fallsafety/ActiveService.java,8\d\8dfb3e76c976382683b78bf748cdcdc30f45b844 \ No newline at end of file diff --git a/src/FallSafety/.idea/vcs.xml b/src/FallSafety/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/src/FallSafety/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/src/FallSafety/app/.gitignore b/src/FallSafety/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/src/FallSafety/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/src/FallSafety/app/build.gradle b/src/FallSafety/app/build.gradle new file mode 100644 index 0000000..55dae4b --- /dev/null +++ b/src/FallSafety/app/build.gradle @@ -0,0 +1,31 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 29 + buildToolsVersion "29.0.3" + defaultConfig { + applicationId "com.example.fallsafety" + minSdkVersion 23 + targetSdkVersion 29 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'androidx.appcompat:appcompat:1.2.0' + implementation 'androidx.constraintlayout:constraintlayout:1.1.3' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'androidx.test.ext:junit:1.1.1' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0' + implementation 'com.google.android.material:material:1.2.0' + +} diff --git a/src/FallSafety/app/src/androidTest/java/com/example/fallsafety/ExampleInstrumentedTest.java b/src/FallSafety/app/src/androidTest/java/com/example/fallsafety/ExampleInstrumentedTest.java new file mode 100644 index 0000000..d33eec3 --- /dev/null +++ b/src/FallSafety/app/src/androidTest/java/com/example/fallsafety/ExampleInstrumentedTest.java @@ -0,0 +1,27 @@ +package com.example.fallsafety; + +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 Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + + assertEquals("com.example.fallsafety", appContext.getPackageName()); + } +} diff --git a/src/FallSafety/app/src/main/AndroidManifest.xml b/src/FallSafety/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..9725a63 --- /dev/null +++ b/src/FallSafety/app/src/main/AndroidManifest.xml @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/app/src/main/ic_launcher-web.png b/src/FallSafety/app/src/main/ic_launcher-web.png new file mode 100644 index 0000000..1cd9245 Binary files /dev/null and b/src/FallSafety/app/src/main/ic_launcher-web.png differ diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/ActiveService.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/ActiveService.java new file mode 100644 index 0000000..7fb8535 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/ActiveService.java @@ -0,0 +1,243 @@ +package com.example.fallsafety; + +import android.Manifest; +import android.app.Notification; +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.app.Service; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.hardware.Sensor; +import android.hardware.SensorEvent; +import android.hardware.SensorEventListener; +import android.hardware.SensorManager; +import android.os.Build; +import android.os.CountDownTimer; +import android.os.IBinder; +import android.speech.tts.TextToSpeech; +import android.widget.Toast; +import androidx.annotation.Nullable; +import androidx.core.app.NotificationCompat; +import androidx.core.content.ContextCompat; + + +//X +//通过传感器实现跌倒检测 + +public class ActiveService extends Service implements SensorEventListener, TextToSpeech.OnInitListener { + + /* + * 传感器管理 + */ + private SensorManager mSensorManager; + private Sensor mSensorAcc; + double x, y, z; + double medX, medY, medZ; + + int i = 0; + + boolean min = false; + boolean max = false; + boolean vertical = false; + + + /* + 变量tts + */ + private TextToSpeech tts = null; + + + + double totalX = 0; + double totalY = 0; + double totalZ = 0; + + /* + * 信息通知 + */ + + private final static String CHANNEL_ID = "NOTIFICACION"; + public final static int NOTIFICACION_ID = 0; + + + static CountDownTimer countDownTimer; + Emergencia emergencia; + + + public ActiveService() { + + } + + @Override + public void onCreate() { + + + // 传感器加速度计初始化 + + //得到系统服务(传感器服务),得到senorManger对象 + mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); + //获得加速度传感器服务 + mSensorAcc = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); + //调用SensorManager 的 registerListener() 方法来注册SensorEventListener 才能使其生效 + mSensorManager.registerListener(this, mSensorAcc, SensorManager.SENSOR_DELAY_NORMAL); + + System.out.println("主动服务"); + Toast.makeText(this, "服务激活", Toast.LENGTH_SHORT).show(); + + emergencia = new Emergencia(); + emergencia.getLocation(); + + if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { + + System.out.println("没有手机读权限"); + } + + //文字转语音 + tts = new TextToSpeech(this, this); + + + } + + @Nullable + @Override + public IBinder onBind(Intent intent) { + return null; + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + return Service.START_NOT_STICKY; + } + + + @Override + public void onDestroy() { + /* + 当调用方法时,服务停止,它被销毁。 + */ + super.onDestroy(); + mSensorManager.unregisterListener(this); + System.out.println("停用服务"); + Toast.makeText(this, "服务已禁用", Toast.LENGTH_SHORT).show(); + + + countDownTimer.cancel(); + + if (tts != null) { + tts.stop(); + tts.shutdown(); + } + + } + + + @Override + public void onInit(int status) { + //检查实例化是否成功 + if (status == TextToSpeech.SUCCESS) { + tts.setPitch(0.8f); + tts.setSpeechRate(1.1f); + } else if (status == TextToSpeech.ERROR) { + Toast.makeText(this, " 文本到语音转换失败 ", Toast.LENGTH_LONG).show(); + } + + } + + @Override + public void onSensorChanged(SensorEvent event) { + + synchronized (this) { + if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) { + + + /* + 当传感器发生变化时,收集值并将其保存在X、Y、Z中. + */ + + x = event.values[0]; + y = event.values[1]; + z = event.values[2]; + + double sum = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2) + Math.pow(z, 2)); + double acel = sum / SensorManager.GRAVITY_EARTH; + + /* + 包含检测算法 + */ + + + } + } + } + + + public void fallDetected() { + + /* + 实现在检测到跌倒时要执行的操作 + 系统声音提示发生事故: + 等待20秒的取消时间 + 调用每个数据库中的联系人 + 如果没有任何反应,则开始发送消息 + */ + + + Toast.makeText(this, "跌倒", Toast.LENGTH_LONG).show(); + String textCaida = getResources().getString(R.string.textCaida); + textSpoken(textCaida); + + + } + + + + + private void crearNotif() { + //应用程序按钮的创建意图和挂起意图 + Intent intentCancelar = new Intent(this, PostFallDetected.class); + PendingIntent pendingIntentCancelar = PendingIntent.getActivity(this, 0, intentCancelar, 0); + + + NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), CHANNEL_ID); + builder.setSmallIcon(R.mipmap.ic_launcher_foreground); + builder.setContentTitle("检测到坠落"); + builder.setContentText("他们会打电话给你的紧急联系人"); + builder.setPriority(NotificationCompat.PRIORITY_HIGH); + builder.setVibrate(new long[]{1000, 1000, 2000, 1000}); + builder.setDefaults(Notification.DEFAULT_SOUND); + builder.setContentIntent(pendingIntentCancelar); + builder.setAutoCancel(true); + + + NotificationManager mNotifyMgr = + (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + mNotifyMgr.notify(NOTIFICACION_ID, builder.build()); + + + } + + private void crearCanalNotificacion() { + + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + CharSequence name = "Notification"; + NotificationChannel notificationChannel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_HIGH); + NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); + notificationManager.createNotificationChannel(notificationChannel); + } + + } + + private void textSpoken(String text) { + + tts.speak(text, TextToSpeech.QUEUE_ADD, null, "speak"); + } + + + @Override + public void onAccuracyChanged(Sensor sensor, int accuracy) { + + } + +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/AppWidget.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/AppWidget.java new file mode 100644 index 0000000..a2f4f91 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/AppWidget.java @@ -0,0 +1,50 @@ +package com.example.fallsafety; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.Context; +import android.content.Intent; +import android.widget.RemoteViews; + + +//Y + +//应用程序小部件功能的实现。 + +public class AppWidget extends AppWidgetProvider { + + static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, + int appWidgetId) { + + Intent intent= new Intent(context, Emergencia.class); + PendingIntent pendingIntent= PendingIntent.getActivity(context,0,intent,0); + + + // 构造RemoteView对象 + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.app_widget); + views.setOnClickPendingIntent(R.id.btnadvicewidget, pendingIntent); + + // 指示小部件管理器更新小部件 + appWidgetManager.updateAppWidget(appWidgetId, views); + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // 可能有多个窗口小部件处于活动状态,因此请更新所有窗口小部件 + for (int appWidgetId : appWidgetIds) { + updateAppWidget(context, appWidgetManager, appWidgetId); + } + } + + @Override + public void onEnabled(Context context) { + // 输入创建第一个小部件时的相关功能 + } + + @Override + public void onDisabled(Context context) { + // 输入最后一个小部件被禁用时的相关功能 + } +} + diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/CallHelper.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/CallHelper.java new file mode 100644 index 0000000..3b32f24 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/CallHelper.java @@ -0,0 +1,65 @@ +package com.example.fallsafety; + + import java.lang.reflect.Method; + import android.content.BroadcastReceiver; + import android.content.Context; + import android.content.Intent; + import android.telephony.TelephonyManager; + import android.util.Log; + //Y + //拨号及辅助功能 + + + public class CallHelper extends BroadcastReceiver { + public static String TAG="PhoneStateReceiver"; + @Override + public void onReceive(Context context, Intent intent) { + if (intent.getAction().equals("android.intent.action.PHONE_STATE")) { + String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE); + Log.d(TAG,"PhoneStateReceiver**Call State=" + state); + if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) { + Log.d(TAG,"PhoneStateReceiver**Idle"); + } else if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { + // 来电 + String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER); + Log.d(TAG,"PhoneStateReceiver**Incoming call " + incomingNumber); + if (!killCall(context)) { + // 使用先前定义的方法 + Log.d(TAG,"PhoneStateReceiver **Unable to kill incoming call"); + } + } else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) { + Log.d(TAG,"PhoneStateReceiver **Offhook"); + } + } else if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) { + // 去电 + String outgoingNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); + Log.d(TAG,"PhoneStateReceiver **Outgoing call " + outgoingNumber); + setResultData(null); + // 杀死去电进程 + } else { + Log.d(TAG,"PhoneStateReceiver **unexpected intent.action=" + intent.getAction()); + } + } + public boolean killCall(Context context) { + try { + // Get the boring old TelephonyManager(电话管理员寻址) + TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + // 获取getITelephony()方法 + Class classTelephony = Class.forName(telephonyManager.getClass().getName()); + Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony"); + // 忽略方法应该是私有的 + methodGetITelephony.setAccessible(true); + //调用getITelephony()以获取ITelephony接口 + Object telephonyInterface = methodGetITelephony.invoke(telephonyManager); + // 从ITelephony获取endCall方法 + Class telephonyInterfaceClass = Class.forName(telephonyInterface.getClass().getName()); + Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall"); + //调用endCall( + methodEndCall.invoke(telephonyInterface); + } catch (Exception ex) { + // 反射呼叫可能会导致错误 + Log.d(TAG,"PhoneStateReceiver **" + ex.toString()); + return false; + } return true; + } + } diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsActivity.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsActivity.java new file mode 100644 index 0000000..fd24ca3 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsActivity.java @@ -0,0 +1,86 @@ +package com.example.fallsafety; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.database.Cursor; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; +import android.widget.SimpleCursorAdapter; + +//X +//有关建立便笺及编辑(应用于添加联系人的初始界面) +public class ContactsActivity extends AppCompatActivity { + + private ContactsDbAdapter dbAdapter; + private ListView m_listview; + + // 指示是否要创建新便笺或编辑现有便笺 + private static final int ACTIVITY_CREATE=0; + private static final int ACTIVITY_EDIT=1; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_contacts); + + //创建BD适配器并打开它 + dbAdapter = new ContactsDbAdapter(this); + dbAdapter.open(); + + //我们创建一个ListView,它将包含所有注释的标题和 + //当我们点击一个标题时,我们会启动一个编辑活动 + //具有相应ID的便笺 + m_listview = (ListView) findViewById(R.id.id_list_view); + m_listview.setOnItemClickListener( + new AdapterView.OnItemClickListener() + { + @Override + public void onItemClick(AdapterView arg0, View view, int position, long id) + { + Intent i = new Intent(view.getContext(), EditActivity.class); + i.putExtra(ContactsDbAdapter.KEY_ROWID, id); + startActivityForResult(i, ACTIVITY_EDIT); + } + } + ); + + //我们用BD中所有注释的标题填充ListView + fillData(); + } + private void fillData() { + Cursor contactsCursor = dbAdapter.fetchAllContacts(); + + //创建一个数组,其中包含要在ListView中显示的字段(仅限于注释标题) + String[] from = new String[]{ContactsDbAdapter.KEY_NOMBRE, ContactsDbAdapter.KEY_TELEFONO}; + + //数组,其中包含要绑定到前一行数组中的字段 + int[] to = new int[]{R.id.text1, R.id.text2}; + + //创建了一个SimpleCursorAdapter并将其分配给ListView以显示它 + SimpleCursorAdapter contacts = + new SimpleCursorAdapter(this, R.layout.contacts_row, contactsCursor, from, to, 0); + m_listview.setAdapter(contacts); + } + + + + public void createContact(View view) { + Intent i = new Intent(this, EditActivity.class); + startActivityForResult(i, ACTIVITY_CREATE); + } + + + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent intent) { + super.onActivityResult(requestCode, resultCode, intent); + fillData(); + } + +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsDbAdapter.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsDbAdapter.java new file mode 100644 index 0000000..1be2107 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/ContactsDbAdapter.java @@ -0,0 +1,179 @@ +package com.example.fallsafety; + + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; +import android.util.Log; +//X +//数据库类 +//类适配器,方便我们使用BD +public class ContactsDbAdapter { + private static final String TAG = "APMOV: NotesDbAdapter"; //用于日志消息 + + //数据库名称、表(在本例中为a)和版本 + private static final String DATABASE_NAME = "data"; + private static final String DATABASE_TABLE = "CONTACTS"; + private static final int DATABASE_VERSION = 1; + + //数据库表字段 + public static final String KEY_NOMBRE = "NOMBRE"; + public static final String KEY_TELEFONO = "TELEFONO"; + public static final String KEY_PRIORIDAD = "PRIORIDAD"; + public static final String KEY_ROWID = "_id"; + + //创建数据库表的SQL语句 + private static final String DATABASE_CREATE = "create table " + DATABASE_TABLE + " (" + + KEY_ROWID +" integer primary key autoincrement, " + + KEY_NOMBRE +" text not null, " + + KEY_TELEFONO +" text not null, " + + KEY_PRIORIDAD + " integer not null);"; + + private DatabaseHelper mDbHelper; + private SQLiteDatabase mDb; + private final Context mCtx; + private static class DatabaseHelper extends SQLiteOpenHelper { + + DatabaseHelper(Context context) { + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(DATABASE_CREATE); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + Log.w(TAG, "Upgrading database from version " + oldVersion + " to " + + newVersion + ", which will destroy all old data"); + db.execSQL("DROP TABLE IF EXISTS " + DATABASE_TABLE); + onCreate(db); + } + } + + /** + * 构造函数-获取上下文以允许数据库打开/创建 + * + * @param ctx the Context within which to work + */ + + public ContactsDbAdapter(Context ctx) { + this.mCtx = ctx; + } + + /** + * 打开notes数据库。如果无法打开,请尝试创建一个新窗口 + * 数据库的实例。如果无法创建,则向 + * 发出失败的信号 + * + * @return this (self reference, allowing this to be chained in an + * initialization call) + * @throws SQLException if the database could be neither opened or created + */ + public ContactsDbAdapter open() throws SQLException { + mDbHelper = new DatabaseHelper(mCtx); + mDb = mDbHelper.getWritableDatabase(); + return this; + } + + public void close() { + mDbHelper.close(); + } + + + /** + *使用提供的标题和正文创建新注释。如果纸条是 + *已成功创建并返回该便笺的新rowId,否则返回 + * a-1表示失败。 + * + * @param nombre the name of the contact + * @param telefono the number of the contact + * @return rowId or -1 if failed + */ + public long createContact(String nombre, String telefono, int prioridad) { + ContentValues initialValues = new ContentValues(); + initialValues.put(KEY_NOMBRE, nombre); + initialValues.put(KEY_TELEFONO, telefono); + initialValues.put(KEY_PRIORIDAD, prioridad); + + return mDb.insert(DATABASE_TABLE, null, initialValues); + } + + /** + * 删除具有给定rowId的注释 + * + * @param rowId id of note to delete + * @return true if deleted, false otherwise + */ + public boolean deleteContact(long rowId) { + + return mDb.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; + } + + /** + * 在数据库中所有注释的列表上返回一个光标 + * + * @return Cursor over all notes + */ + public Cursor fetchAllContacts() { + + return mDb.query(DATABASE_TABLE, new String[] {KEY_ROWID, KEY_NOMBRE, + KEY_TELEFONO, KEY_PRIORIDAD}, null, null, null, null, KEY_PRIORIDAD+" ASC"); + } + + /** + * 返回一个光标,该光标位于与给定rowId匹配的注释处 + * + * @param rowId id of note to retrieve + * @return Cursor positioned to matching note, if found + * @throws SQLException if note could not be found/retrieved + */ + public Cursor fetchContact(long rowId) throws SQLException { + + Cursor mCursor = + + mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, + KEY_NOMBRE, KEY_TELEFONO, KEY_PRIORIDAD}, KEY_ROWID + "=" + rowId, null, + null, null, null, null); + if (mCursor != null) { + mCursor.moveToFirst(); + } + return mCursor; + + } + + public Cursor fetchContactPriority(int priority) throws SQLException{ + Cursor mCursor = + + mDb.query(true, DATABASE_TABLE, new String[] {KEY_ROWID, + KEY_NOMBRE, KEY_TELEFONO, KEY_PRIORIDAD}, KEY_PRIORIDAD + "=" + priority, null, + null, null, null, null); + if (mCursor != null) { + mCursor.moveToFirst(); + } + return mCursor; + } + + /** + * 使用提供的详细信息更新注释。需要更新的注释如下: + *使用rowId指定,并更改为使用标题和正文 + *传入的值 + * + * @param rowId id of note to update + * @param nombre value to set note title to + * @param telefono value to set note body to + * @return true if the note was successfully updated, false otherwise + */ + public boolean updateContact(long rowId, String nombre, String telefono, int prioridad) { + ContentValues args = new ContentValues(); + args.put(KEY_NOMBRE, nombre); + args.put(KEY_TELEFONO, telefono); + args.put(KEY_PRIORIDAD,prioridad); + + return mDb.update(DATABASE_TABLE, args, KEY_ROWID + "=" + rowId, null) > 0; + } +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/EditActivity.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/EditActivity.java new file mode 100644 index 0000000..6628ad2 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/EditActivity.java @@ -0,0 +1,155 @@ +package com.example.fallsafety; + +import androidx.appcompat.app.AppCompatActivity; + +import android.Manifest; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Bundle; +import android.provider.ContactsContract; +import android.view.View; +import android.widget.Button; +import android.widget.EditText; +import android.widget.Toast; + +import com.google.android.material.floatingactionbutton.FloatingActionButton; + +//X +//创建三元素的列表相关(应用于添加联系人的编辑界面) +public class EditActivity extends AppCompatActivity { + + + private EditText mNombreText, mTelefonoText, mPrioridadText; + private Long mRowId; + private ContactsDbAdapter dbAdapter; + private static final int PICK_CONTACT_REQUEST=1; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // infla el layout(充气布局) + setContentView(R.layout.activity_edit); + + // 获取对构成布局的三个视图的引用。 + mNombreText = (EditText) findViewById(R.id.nombreContacto); + mTelefonoText = (EditText) findViewById(R.id.numeroContacto); + mPrioridadText= (EditText) findViewById(R.id.prioridadContacto); + Button confirmButton = (Button) findViewById(R.id.guardar); + + //我们创建了BD适配器并打开它 + dbAdapter = new ContactsDbAdapter(this); + dbAdapter.open(); + + // 获取传递给它的表的行ID(单击联系人编辑0) + mRowId = (savedInstanceState == null) ? null : + (Long) savedInstanceState.getSerializable(ContactsDbAdapter.KEY_ROWID); + if (mRowId == null) { + Bundle extras = getIntent().getExtras(); + mRowId = extras != null ? extras.getLong(ContactsDbAdapter.KEY_ROWID) : null; + } + + // 如果您传递了一个ID(不是空的),则用保存在BD中的字段填充,否则留空 + if (mRowId != null) { + Cursor contact = dbAdapter.fetchContact(mRowId); + mNombreText.setText(contact.getString( + contact.getColumnIndexOrThrow(ContactsDbAdapter.KEY_NOMBRE))); + mTelefonoText.setText(contact.getString( + contact.getColumnIndexOrThrow(ContactsDbAdapter.KEY_TELEFONO))); + mPrioridadText.setText(contact.getString( + contact.getColumnIndexOrThrow(ContactsDbAdapter.KEY_PRIORIDAD))); + } + + FloatingActionButton fab= (FloatingActionButton) findViewById(R.id.fab); + fab.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + seleccionarContacto(); + } + }); + + } + + private void seleccionarContacto() { + Intent selectContacto = new Intent(Intent.ACTION_PICK, Uri.parse("content://contacts")); + selectContacto.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE); + startActivityForResult(selectContacto, PICK_CONTACT_REQUEST); + + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == PICK_CONTACT_REQUEST) { + if (resultCode == RESULT_OK) { + Uri uri = data.getData(); + + Cursor cursor = getContentResolver().query(uri, null, null, null, null); + + if(cursor.moveToFirst()){ + int columnaNombre=cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME); + int columnaNumero=cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER); + + String nombre= cursor.getString(columnaNombre); + String numero= cursor.getString(columnaNumero); + + mNombreText.setText(nombre); + mTelefonoText.setText(numero); + + } + + } + } + } + + public void deleteContact(View view){ + if (mRowId != null) { + dbAdapter.deleteContact(mRowId); + } + setResult(RESULT_OK); + dbAdapter.close(); + finish(); + } + + //添加联系人 + + public void saveNote(View view) { + String nombre = mNombreText.getText().toString(); + String telefono = mTelefonoText.getText().toString(); + String prioridad= mPrioridadText.getText().toString(); + + + + + + + if (telefono.length()!=9 && telefono.length()!=12 && telefono.length()!=16 && telefono.length()==0){ + Toast.makeText(this,"无效号码", Toast.LENGTH_LONG).show(); + } else if(nombre.length() == 0){ + Toast.makeText(this, "输入一个名字", Toast.LENGTH_LONG).show(); + } else if(prioridad.length() == 0 ){ + Toast.makeText(this, "优先级错误", Toast.LENGTH_LONG).show(); + } else { + int priority= Integer.parseInt(prioridad); + + if (mRowId == null) { + long id = dbAdapter.createContact(nombre, telefono,priority); + if (id > 0) { + mRowId = id; + } + } else { + dbAdapter.updateContact(mRowId, nombre, telefono,priority); + } + Toast.makeText(this,"联系人添加正确", Toast.LENGTH_LONG).show(); + setResult(RESULT_OK); + dbAdapter.close(); + finish(); + + + + } + } +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/Emergencia.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/Emergencia.java new file mode 100644 index 0000000..ca24bb9 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/Emergencia.java @@ -0,0 +1,214 @@ +package com.example.fallsafety; + + +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.content.ContextCompat; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.location.Criteria; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.net.Uri; +import android.os.Bundle; +import android.telephony.SmsManager; +import android.util.Log; +import android.widget.Toast; + + +//X +//紧急情况响应 +public class Emergencia extends AppCompatActivity{ + /* + 短信变量 + */ + + SmsManager smsManager; + String phoneNumber; + String textMsg; + + /* + 位置变量 + */ + + double latitude, longitude; + + + /* + 数据库变量 + */ + private ContactsDbAdapter dbAdapter; + + public Emergencia(){ + + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.emergencia_activity); + + getLocation(); + + Toast.makeText(this, "clase emergencia", Toast.LENGTH_LONG).show(); + String smsEmergencia=getResources().getString(R.string.smsEmergencia); + sendSMS(this, smsEmergencia); + makeCall(this); + + + + } + + + public void sendSMS(Context context, String txt){ + + getLocation(); + + smsManager= SmsManager.getDefault(); + //textMsg=txt + "https://maps.google.com/?q="+String.valueOf(latitude)+","+String.valueOf(longitude) ; + textMsg=txt + "https://maps.google.com/?q=40.332853,-3.765089" ; + + Toast.makeText(context,"ENVIADO SMS", Toast.LENGTH_LONG).show(); + + /* + 遍历数据库 + */ + + //我们创建了BD适配器并打开它 + dbAdapter = new ContactsDbAdapter(context); + dbAdapter.open(); + + Cursor contactsCursor= dbAdapter.fetchAllContacts(); + if (contactsCursor.getCount()!=0){ + contactsCursor.moveToFirst(); + do{ + System.out.println("NOMBRE: " + contactsCursor.getString(1)); + System.out.println("TELEFONO: " + contactsCursor.getString(2)); + phoneNumber= contactsCursor.getString(2); + System.out.println("PHONE NUMBER A MANDAR SMS: " + phoneNumber); + System.out.println(textMsg); + smsManager.sendTextMessage(phoneNumber, null, textMsg, null, null); + + } while (contactsCursor.moveToNext()); + } + + } + + public void makeCall(Context context){ + + + //我们创建了BD适配器并打开它 + dbAdapter = new ContactsDbAdapter(context); + dbAdapter.open(); + + Cursor contactsCursor= dbAdapter.fetchAllContacts(); + if (contactsCursor.getCount()!=0){ + contactsCursor.moveToFirst(); + + System.out.println("NOMBRE: " + contactsCursor.getString(1)); + System.out.println("TELEFONO: " + contactsCursor.getString(2)); + phoneNumber=contactsCursor.getString(2); + + try{ + + System.out.println("OK"); + + if(ContextCompat.checkSelfPermission(context, Manifest.permission.CALL_PHONE) + != PackageManager.PERMISSION_GRANTED){ + + System.out.println("没有呼叫权限"); + + } + + Intent intentLlamada = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"+phoneNumber)); + intentLlamada.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intentLlamada); + + } catch (Exception e){ + System.out.println("错误"); + e.printStackTrace(); + } + + } + + + + } + + + public void getLocation(){ + try{ + + String serviceString= Context.LOCATION_SERVICE; + LocationManager locationManager = (LocationManager) getSystemService(serviceString); + + LocationListener locationListener= new LocationListener() { + @Override + public void onLocationChanged(Location location) { + latitude= location.getLatitude(); + longitude= location.getLongitude(); + + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + + } + + @Override + public void onProviderEnabled(String provider) { + + } + + @Override + public void onProviderDisabled(String provider) { + + } + }; + + // 检查访问位置的权限 + if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) + != PackageManager.PERMISSION_GRANTED){ + //ActivityCompat.requestPermissions(MainActivity.this.getApplicationContext(), new String[]{Manifest.permission.SEND_SMS}, REQUEST_PERMISSION_ACCESS_FINE_LOCATION); + + Toast.makeText(this.getApplicationContext(), "没有位置权限", Toast.LENGTH_SHORT).show(); + + } + + locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, locationListener); + + Criteria criteria= new Criteria(); + + + String provider= String.valueOf(locationManager.getBestProvider(criteria, true)).toString(); + + System.out.println("provider: " + provider); + + Location location= locationManager.getLastKnownLocation(provider); + if(location!=null){ + Log.e("TAG", "GPS ON"); + latitude=location.getLatitude(); + longitude=location.getLongitude(); + } else{ + locationManager.requestLocationUpdates(provider, 1000,0, locationListener ); + } + + locationManager.requestLocationUpdates(provider, 5000, 0, locationListener); + + System.out.println("lat" + latitude + "lon " + longitude); + + } catch (Exception e){ + e.printStackTrace(); + } + + + + + } + + +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/MainActivity.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/MainActivity.java new file mode 100644 index 0000000..f2297f6 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/MainActivity.java @@ -0,0 +1,164 @@ +package com.example.fallsafety; + +import androidx.appcompat.app.AppCompatActivity; + +import android.Manifest; +import android.content.Context; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.database.Cursor; +import android.os.Build; +import android.os.Bundle; +import android.speech.tts.TextToSpeech; +import android.view.View; +import android.widget.ImageButton; +import android.widget.Switch; +import android.widget.TextView; +import android.widget.Toast; + + +//X +//有关主界面的内部逻辑 +public class MainActivity extends AppCompatActivity implements View.OnClickListener { + private Context mCtx =this; + + /* + 变量TTS + */ + private static int TTS_DATA_CHECK=1; + + private TextView textEstado; + private Switch aSwitch; + + static ContactsDbAdapter dbAdapter; + + + private ImageButton btnAdvice; + + public MainActivity(){ + + } + + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + checkPermissions(); + + textEstado= (TextView) findViewById(R.id.textEstado); + aSwitch= (Switch) findViewById(R.id.btnswitch); + + // 我们创建了BD适配器并打开它 + dbAdapter = new ContactsDbAdapter(this); + dbAdapter.open(); + + // 获取传递给它的表的行ID(单击联系人编辑0) + Long mRowId = (savedInstanceState == null) ? null : + (Long) savedInstanceState.getSerializable(ContactsDbAdapter.KEY_ROWID); + + + btnAdvice= (ImageButton) findViewById(R.id.btnadvice); + btnAdvice.setOnClickListener(this); + + Emergencia emergencia = new Emergencia(); + emergencia.getLocation(); + + /* + TTS验证 + */ + + Intent checkTTs= new Intent(); + checkTTs.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA); + startActivityForResult(checkTTs, TTS_DATA_CHECK); + } + + @Override + public void onClick(View v){ + + Cursor contactsCursor = dbAdapter.fetchAllContacts(); + + if(contactsCursor.getCount()==0) { + + Toast.makeText(this, getResources().getString(R.string.noContactos), Toast.LENGTH_SHORT).show(); + } else { + + if (v.getId() == btnAdvice.getId()) { + Toast.makeText(this, "紧急按钮", Toast.LENGTH_LONG).show(); + + Intent intent= new Intent(this, Emergencia.class); + startActivity(intent); + + } + } + } + + public void clickSwitch(View view){ + + Cursor contactsCursor = dbAdapter.fetchAllContacts(); + + if(contactsCursor.getCount()==0) { + aSwitch.setChecked(false); + Toast.makeText(this, getResources().getString(R.string.noContactos), Toast.LENGTH_SHORT).show(); + } else{ + if(view.getId() == R .id.btnswitch){ + + if(aSwitch.isChecked()){ + textEstado.setText(getResources().getString(R.string.estadoOn)); + startService(new Intent(mCtx, ActiveService.class)); + } else { + textEstado.setText(getResources().getString(R.string.estadoOff)); + stopService(new Intent(mCtx, ActiveService.class)); + } + } + + } + } + + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + super.onActivityResult(requestCode, resultCode, data); + if (requestCode == TTS_DATA_CHECK) { + + if (resultCode != TextToSpeech.Engine.CHECK_VOICE_DATA_PASS) { + // 无数据-立即安装 + Intent installTTSIntent = new Intent(); + installTTSIntent.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA); + startActivity(installTTSIntent); + } + } + } + + + + + + public void Contact(View view){ + Intent contact= new Intent(this, ContactsActivity.class); + startActivity(contact); + } + + public void checkPermissions(){ + + if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){ + + int permsRequestCode = 100; + String[] perms = {Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS, Manifest.permission.READ_PHONE_STATE, Manifest.permission.READ_CONTACTS}; + int accessFinePermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION); + int accessCoarsePermission = checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION); + int callPermission = checkSelfPermission(Manifest.permission.CALL_PHONE); + int smsPermission= checkSelfPermission(Manifest.permission.SEND_SMS); + int readPhonePermission= checkSelfPermission(Manifest.permission.READ_PHONE_STATE); + int readContacts = checkSelfPermission(Manifest.permission.READ_CONTACTS); + + + if (callPermission == PackageManager.PERMISSION_GRANTED && accessFinePermission == PackageManager.PERMISSION_GRANTED && accessCoarsePermission == PackageManager.PERMISSION_GRANTED && smsPermission==PackageManager.PERMISSION_GRANTED && readPhonePermission==PackageManager.PERMISSION_GRANTED && readContacts==PackageManager.PERMISSION_GRANTED) { + + } else { + requestPermissions(perms, permsRequestCode); + + } + } + } +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/PostFallDetected.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/PostFallDetected.java new file mode 100644 index 0000000..8d4afb6 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/PostFallDetected.java @@ -0,0 +1,79 @@ +package com.example.fallsafety; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.CountDownTimer; +import android.view.Gravity; +import android.view.View; + +import android.widget.ImageButton; +import android.widget.Toast; + +//Y +//故障后检测 +public class PostFallDetected extends AppCompatActivity implements View.OnClickListener { + + private Context mCtx =this; + private ImageButton btnNoCaida; + private ImageButton btnSiCaida; + private CountDownTimer count; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_post_fall_detected); + + + btnNoCaida = (ImageButton) findViewById(R.id.btnNoCaida); + btnNoCaida.setOnClickListener(this); + btnSiCaida= (ImageButton) findViewById(R.id.btnSiCaida); + btnSiCaida.setOnClickListener(this); + + + } + + @Override + public void onClick(View v) { + switch (v.getId()){ + case R.id.btnNoCaida: + + cancelarServicio(); + + Toast toast = Toast.makeText(this, "AVISO CANCELADO", Toast.LENGTH_LONG); + toast.setGravity(Gravity.CENTER,0,0); + toast.show(); + + break; + + case R.id.btnSiCaida: + + cancelarServicio(); + Intent intent= new Intent(this, Emergencia.class); + startActivity(intent); + + break; + + } + } + + public void cancelarServicio(){ + stopService(new Intent(mCtx, ActiveService.class)); + + count = new CountDownTimer( 30000,1000) { + @Override + public void onTick(long millisUntilFinished) { + + } + + @Override + public void onFinish() { + startService(new Intent(mCtx, ActiveService.class)); + } + }.start(); + + } +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/SplashScreen.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/SplashScreen.java new file mode 100644 index 0000000..a73381d --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/SplashScreen.java @@ -0,0 +1,36 @@ +package com.example.fallsafety; + +import androidx.appcompat.app.AppCompatActivity; + +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +//X +//初始化界面的设计 + +public class SplashScreen extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_splash_screen); + + int time=2000; + + + + // 输入一个延迟时间,使活动持续运行运行几秒钟。 + new Handler().postDelayed(new Runnable() { + @Override + //在一段时间后运行下面的内容 + public void run() { + Intent intent = new Intent (SplashScreen.this, MainActivity.class); + startActivity(intent); + } + },time); //暂定4秒 + + } + + + +} diff --git a/src/FallSafety/app/src/main/java/com/example/fallsafety/TelephonyReceiver.java b/src/FallSafety/app/src/main/java/com/example/fallsafety/TelephonyReceiver.java new file mode 100644 index 0000000..67f0569 --- /dev/null +++ b/src/FallSafety/app/src/main/java/com/example/fallsafety/TelephonyReceiver.java @@ -0,0 +1,40 @@ +package com.example.fallsafety; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.media.AudioManager; +import android.telephony.TelephonyManager; +import android.widget.Toast; + +//Y +//收电话 + +public class TelephonyReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + TelephonyManager telephonyManager= (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + switch (telephonyManager.getCallState()){ + case TelephonyManager.CALL_STATE_RINGING: + + break; + case TelephonyManager.CALL_STATE_IDLE: + + AudioManager man= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + man.setSpeakerphoneOn(false); + break; + case TelephonyManager.CALL_STATE_OFFHOOK: + + + + AudioManager manager= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); + manager.setMode(AudioManager.MODE_IN_COMMUNICATION); + manager.setStreamVolume(AudioManager.STREAM_VOICE_CALL,manager.getStreamMaxVolume(AudioManager.STREAM_VOICE_CALL),0); + manager.setSpeakerphoneOn(true); + + + break; + + } + } +} diff --git a/src/FallSafety/app/src/main/res/color/switch_color.xml b/src/FallSafety/app/src/main/res/color/switch_color.xml new file mode 100644 index 0000000..8ed686d --- /dev/null +++ b/src/FallSafety/app/src/main/res/color/switch_color.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/src/FallSafety/app/src/main/res/drawable/backbtn.xml b/src/FallSafety/app/src/main/res/drawable/backbtn.xml new file mode 100644 index 0000000..961aab1 --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/backbtn.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/src/FallSafety/app/src/main/res/drawable/bg_color.xml b/src/FallSafety/app/src/main/res/drawable/bg_color.xml new file mode 100644 index 0000000..0575b8b --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/bg_color.xml @@ -0,0 +1,9 @@ + + + + + + \ No newline at end of file diff --git a/src/FallSafety/app/src/main/res/drawable/ic_contact.xml b/src/FallSafety/app/src/main/res/drawable/ic_contact.xml new file mode 100644 index 0000000..b2cb337 --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/ic_contact.xml @@ -0,0 +1,9 @@ + + + diff --git a/src/FallSafety/app/src/main/res/drawable/ic_person_add_white_60dp.xml b/src/FallSafety/app/src/main/res/drawable/ic_person_add_white_60dp.xml new file mode 100644 index 0000000..e3fe3da --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/ic_person_add_white_60dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/src/FallSafety/app/src/main/res/drawable/ic_thumb_down_red_150dp.xml b/src/FallSafety/app/src/main/res/drawable/ic_thumb_down_red_150dp.xml new file mode 100644 index 0000000..6832c3c --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/ic_thumb_down_red_150dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/src/FallSafety/app/src/main/res/drawable/ic_thumb_up_black_150dp.xml b/src/FallSafety/app/src/main/res/drawable/ic_thumb_up_black_150dp.xml new file mode 100644 index 0000000..7a58718 --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/ic_thumb_up_black_150dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/src/FallSafety/app/src/main/res/drawable/ic_warning_black_24dp.xml b/src/FallSafety/app/src/main/res/drawable/ic_warning_black_24dp.xml new file mode 100644 index 0000000..a5cd89e --- /dev/null +++ b/src/FallSafety/app/src/main/res/drawable/ic_warning_black_24dp.xml @@ -0,0 +1,5 @@ + + + diff --git a/src/FallSafety/app/src/main/res/drawable/icon.png b/src/FallSafety/app/src/main/res/drawable/icon.png new file mode 100644 index 0000000..7b6c88a Binary files /dev/null and b/src/FallSafety/app/src/main/res/drawable/icon.png differ diff --git a/src/FallSafety/app/src/main/res/drawable/image.png b/src/FallSafety/app/src/main/res/drawable/image.png new file mode 100644 index 0000000..6e84b2b Binary files /dev/null and b/src/FallSafety/app/src/main/res/drawable/image.png differ diff --git a/src/FallSafety/app/src/main/res/drawable/widget_preview.png b/src/FallSafety/app/src/main/res/drawable/widget_preview.png new file mode 100644 index 0000000..57ad74c Binary files /dev/null and b/src/FallSafety/app/src/main/res/drawable/widget_preview.png differ diff --git a/src/FallSafety/app/src/main/res/font/quicksand.xml b/src/FallSafety/app/src/main/res/font/quicksand.xml new file mode 100644 index 0000000..982b40a --- /dev/null +++ b/src/FallSafety/app/src/main/res/font/quicksand.xml @@ -0,0 +1,7 @@ + + + diff --git a/src/FallSafety/app/src/main/res/font/quicksand_medium.xml b/src/FallSafety/app/src/main/res/font/quicksand_medium.xml new file mode 100644 index 0000000..2d98b27 --- /dev/null +++ b/src/FallSafety/app/src/main/res/font/quicksand_medium.xml @@ -0,0 +1,7 @@ + + + diff --git a/src/FallSafety/app/src/main/res/layout/activity_contacts.xml b/src/FallSafety/app/src/main/res/layout/activity_contacts.xml new file mode 100644 index 0000000..341cd55 --- /dev/null +++ b/src/FallSafety/app/src/main/res/layout/activity_contacts.xml @@ -0,0 +1,23 @@ + + + +