Compare commits
61 Commits
native1
...
8e237bd24a
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8e237bd24a | ||
|
|
9f31f12463 | ||
|
|
55cf7196a6 | ||
|
|
fb99e7ecf4 | ||
| f154f30e2d | |||
| 7114e36165 | |||
| 195fb73620 | |||
| 655279a8a1 | |||
| 46385d5358 | |||
| ab0dd2fbf6 | |||
| a9a69ca31b | |||
| 1d54d6aa2a | |||
| 200086301a | |||
| 0d0838d0e1 | |||
| a132cdfd27 | |||
| 96c8cca033 | |||
| 07f634ae05 | |||
| 4819dbce86 | |||
| 6942abca3b | |||
| 02fc928f20 | |||
| b67de551ba | |||
| e28e167085 | |||
| 8cd802a826 | |||
| 7e14dd379a | |||
| 4a584fa7d7 | |||
| a32c165424 | |||
| 9177c00a3c | |||
| e937ce207c | |||
| 4462ba5ba2 | |||
| 0672d762c9 | |||
| efbba44250 | |||
| ef4dfb0307 | |||
| 086f1226a1 | |||
| 5cf30411c1 | |||
| 76e4949dd7 | |||
| 4a16010bd6 | |||
| b55d9a4b38 | |||
| 6a1cfaeda9 | |||
| f57975ef1e | |||
| 548d501a44 | |||
| a997190480 | |||
| 631f9831c3 | |||
| b2c3ed9015 | |||
| 6bd31327db | |||
| 7e362038b3 | |||
| d30c025874 | |||
| 78d2d2cd79 | |||
| 9eb47345fe | |||
| 57188d27cc | |||
| e40403f7db | |||
| 09fdb75644 | |||
| 0f07736d1e | |||
| e7331f64f4 | |||
| 98e7d57c7d | |||
| 3c8ac29398 | |||
| 5f945fe6e3 | |||
| 11ab4e244d | |||
| 5cafd2ac1d | |||
| c2b947c630 | |||
| d60322cbc2 | |||
| 88c791a520 |
11
.idea/deploymentTargetSelector.xml
generated
11
.idea/deploymentTargetSelector.xml
generated
@@ -3,6 +3,17 @@
|
|||||||
<component name="deploymentTargetSelector">
|
<component name="deploymentTargetSelector">
|
||||||
<selectionStates>
|
<selectionStates>
|
||||||
<SelectionState runConfigName="app">
|
<SelectionState runConfigName="app">
|
||||||
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
|
<DropdownSelection timestamp="2026-06-22T08:46:41.014465400Z">
|
||||||
|
<Target type="DEFAULT_BOOT">
|
||||||
|
<handle>
|
||||||
|
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />
|
||||||
|
</handle>
|
||||||
|
</Target>
|
||||||
|
</DropdownSelection>
|
||||||
|
<DialogSelection />
|
||||||
|
</SelectionState>
|
||||||
|
<SelectionState runConfigName="AlarmLogActivity">
|
||||||
<option name="selectionMode" value="DROPDOWN" />
|
<option name="selectionMode" value="DROPDOWN" />
|
||||||
<DropdownSelection timestamp="2026-05-18T09:18:19.023586Z">
|
<DropdownSelection timestamp="2026-05-18T09:18:19.023586Z">
|
||||||
<Target type="DEFAULT_BOOT">
|
<Target type="DEFAULT_BOOT">
|
||||||
|
|||||||
48
.kotlin/errors/errors-1780537656129.log
Normal file
48
.kotlin/errors/errors-1780537656129.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker7700090853507788345.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1780537656460.log
Normal file
48
.kotlin/errors/errors-1780537656460.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker12680940025563006602.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1781138120653.log
Normal file
48
.kotlin/errors/errors-1781138120653.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3894271637508823813.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1782700916835.log
Normal file
48
.kotlin/errors/errors-1782700916835.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker16051875768763165132.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1782787409833.log
Normal file
48
.kotlin/errors/errors-1782787409833.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3580585840179793220.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1782788041845.log
Normal file
48
.kotlin/errors/errors-1782788041845.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker11763075351170172587.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1782888714708.log
Normal file
48
.kotlin/errors/errors-1782888714708.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3368904538941318214.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1782890222939.log
Normal file
48
.kotlin/errors/errors-1782890222939.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker2940944726750836786.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1783384781223.log
Normal file
48
.kotlin/errors/errors-1783384781223.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker13384034999995465012.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1783643668109.log
Normal file
48
.kotlin/errors/errors-1783643668109.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker11134052769962658558.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1783645418169.log
Normal file
48
.kotlin/errors/errors-1783645418169.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker4236714666597388016.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1783645640346.log
Normal file
48
.kotlin/errors/errors-1783645640346.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker12754528945444950713.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
@@ -3,7 +3,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
android {
|
android {
|
||||||
namespace = "com.example.defenseapplication"
|
namespace = "com.ckkj.defense_device"
|
||||||
compileSdk {
|
compileSdk {
|
||||||
version = release(36) {
|
version = release(36) {
|
||||||
minorApiLevel = 1
|
minorApiLevel = 1
|
||||||
@@ -11,9 +11,9 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "com.example.defenseapplication"
|
applicationId = "com.ckkj.defense_device"
|
||||||
minSdk = 24
|
minSdk = 24
|
||||||
targetSdk = 36
|
targetSdk = 30
|
||||||
versionCode = 1
|
versionCode = 1
|
||||||
versionName = "1.0"
|
versionName = "1.0"
|
||||||
|
|
||||||
@@ -36,6 +36,11 @@ android {
|
|||||||
buildFeatures {
|
buildFeatures {
|
||||||
viewBinding=true
|
viewBinding=true
|
||||||
}
|
}
|
||||||
|
lint {
|
||||||
|
disable += "ExpiredTargetSdkVersion"
|
||||||
|
checkReleaseBuilds = false
|
||||||
|
abortOnError = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
@@ -69,14 +74,8 @@ dependencies {
|
|||||||
// Kotlin 协程
|
// Kotlin 协程
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
|
||||||
|
|
||||||
// CameraX 用于相机预览
|
|
||||||
implementation("androidx.camera:camera-camera2:1.3.0")
|
|
||||||
implementation("androidx.camera:camera-lifecycle:1.3.0")
|
|
||||||
implementation("androidx.camera:camera-view:1.3.0")
|
|
||||||
// Google ML Kit 人脸检测
|
// Google ML Kit 人脸检测
|
||||||
implementation("com.google.mlkit:face-detection:16.1.5")
|
implementation("com.google.mlkit:face-detection:16.1.5")
|
||||||
// 图形绘制库(绘制人脸框)
|
|
||||||
implementation("com.github.bumptech.glide:glide:4.15.1")
|
|
||||||
//Glide 依赖
|
//Glide 依赖
|
||||||
implementation("com.github.bumptech.glide:glide:4.16.0")
|
implementation("com.github.bumptech.glide:glide:4.16.0")
|
||||||
// ZXing 二维码扫描库
|
// ZXing 二维码扫描库
|
||||||
@@ -87,8 +86,6 @@ dependencies {
|
|||||||
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
|
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
|
||||||
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
|
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
|
||||||
implementation("androidx.core:core-ktx:1.12.0")
|
implementation("androidx.core:core-ktx:1.12.0")
|
||||||
// Android-PickerView 时间选择器
|
|
||||||
implementation("com.contrarywind:Android-PickerView:4.1.9")
|
|
||||||
//二维码三方库
|
//二维码三方库
|
||||||
implementation("com.github.maning0303:MNMLKitScanner:V1.0.4")
|
implementation("com.github.maning0303:MNMLKitScanner:V1.0.4")
|
||||||
implementation("com.google.mlkit:barcode-scanning:17.0.2")
|
implementation("com.google.mlkit:barcode-scanning:17.0.2")
|
||||||
@@ -101,8 +98,10 @@ dependencies {
|
|||||||
implementation("com.yanzhenjie.recyclerview:x:1.3.2")
|
implementation("com.yanzhenjie.recyclerview:x:1.3.2")
|
||||||
//Android-PickerView-时间弹窗
|
//Android-PickerView-时间弹窗
|
||||||
implementation("com.contrarywind:Android-PickerView:4.1.9")
|
implementation("com.contrarywind:Android-PickerView:4.1.9")
|
||||||
//基于exoPlayer 自定义播放器 JPlayer支持功能
|
// GSYVideoPlayer
|
||||||
implementation("com.ycjiang:VideoPlayModule-Lite:2.3.61")
|
implementation("io.github.carguo:gsyvideoplayer:13.0.0")
|
||||||
|
//下载
|
||||||
|
implementation("io.github.chiclaim:downloader:1.0.2")
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication
|
package com.ckkj.defense_device
|
||||||
|
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import androidx.test.ext.junit.runners.AndroidJUnit4
|
import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||||
@@ -22,17 +22,36 @@
|
|||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/loge"
|
android:icon="@mipmap/logo"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.DefenseApplication">
|
android:theme="@style/Theme.DefenseApplication">
|
||||||
|
<activity
|
||||||
|
android:name=".personal.CancelAccountActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".personal.SettingsMenusActivity"
|
||||||
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".home.StartActivity"
|
||||||
|
android:exported="true">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
|
||||||
|
<category android:name="android.intent.category.LAUNCHER" />
|
||||||
|
</intent-filter>
|
||||||
|
</activity>
|
||||||
<activity
|
<activity
|
||||||
android:name=".personal.LoginPasswordActivity"
|
android:name=".personal.LoginPasswordActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".personal.InvitationCodeActivity"
|
android:name=".personal.InvitationCodeActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".personal.JoinFamilyInviteActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".liveVideo.StrikePositionActivity"
|
android:name=".liveVideo.StrikePositionActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
@@ -90,6 +109,7 @@
|
|||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".liveVideo.LiveVideoActivity"
|
android:name=".liveVideo.LiveVideoActivity"
|
||||||
|
android:configChanges="orientation|screenSize|keyboardHidden"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".home.SetNameActivity"
|
android:name=".home.SetNameActivity"
|
||||||
@@ -126,13 +146,7 @@
|
|||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".login.LoginActivity"
|
android:name=".login.LoginActivity"
|
||||||
android:exported="true">
|
android:exported="false" />
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.MAIN" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.LAUNCHER" />
|
|
||||||
</intent-filter>
|
|
||||||
</activity>
|
|
||||||
|
|
||||||
<provider
|
<provider
|
||||||
android:name="androidx.core.content.FileProvider"
|
android:name="androidx.core.content.FileProvider"
|
||||||
|
|||||||
41
app/src/main/java/com/ckkj/defense_device/MyApplication.kt
Normal file
41
app/src/main/java/com/ckkj/defense_device/MyApplication.kt
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
package com.ckkj.defense_device
|
||||||
|
|
||||||
|
import android.app.Application
|
||||||
|
import android.content.Context
|
||||||
|
import com.blankj.utilcode.util.Utils
|
||||||
|
import com.ckkj.defense_device.utils.LanguageUtil
|
||||||
|
// _ooOoo_
|
||||||
|
// o8888888o
|
||||||
|
// 88" . "88
|
||||||
|
// (| -_- |)
|
||||||
|
// O\ = /O
|
||||||
|
// ____/`---'\____
|
||||||
|
// . ' \\| |// `.
|
||||||
|
// / \\||| : |||// \
|
||||||
|
// / _||||| -:- |||||- \
|
||||||
|
// | | \\\ - /// | |
|
||||||
|
// | \_| ''\---/'' | |
|
||||||
|
// \ .-\__ `-` ___/-. /
|
||||||
|
// ___`. .' /--.--\ `. . __
|
||||||
|
// ."" '< `.___\_<|>_/___.' >'"".
|
||||||
|
// | | : `- \`.;`\ _ /`;.`/ - ` : | |
|
||||||
|
// \ \ `-. \_ __\ /__ _/ .-` / /
|
||||||
|
// ======`-.____`-.___\_____/___.-`____.-'======
|
||||||
|
// `=---='
|
||||||
|
//
|
||||||
|
// 佛祖保佑 永无BUG
|
||||||
|
|
||||||
|
class MyApplication : Application() {
|
||||||
|
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
Utils.init(this) // 初始化 AndroidUtilCode
|
||||||
|
LanguageUtil.init(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun attachBaseContext(base: Context) {
|
||||||
|
// 在应用启动时应用语言设置
|
||||||
|
val context = LanguageUtil.attachBaseContext(base)
|
||||||
|
super.attachBaseContext(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
@@ -6,7 +6,7 @@ import android.view.ViewGroup
|
|||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
|
|
||||||
data class Device(
|
data class Device(
|
||||||
val name: String,
|
val name: String,
|
||||||
@@ -18,6 +18,8 @@ class AddDeviceAdapter(
|
|||||||
private val onItemClick: (Device) -> Unit
|
private val onItemClick: (Device) -> Unit
|
||||||
) : RecyclerView.Adapter<AddDeviceAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<AddDeviceAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private val defaultIcons = listOf(R.mipmap.img1, R.mipmap.img2, R.mipmap.img3)
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2)
|
val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2)
|
||||||
val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2)
|
val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2)
|
||||||
@@ -47,7 +49,9 @@ class AddDeviceAdapter(
|
|||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val device = devices[position]
|
val device = devices[position]
|
||||||
holder.tvName.text = device.name
|
holder.tvName.text = device.name
|
||||||
holder.ivIcon.setImageResource(R.drawable.img)
|
|
||||||
|
val iconResId = defaultIcons[position % defaultIcons.size]
|
||||||
|
holder.ivIcon.setImageResource(iconResId)
|
||||||
|
|
||||||
// 点击事件
|
// 点击事件
|
||||||
holder.itemView.setOnClickListener { onItemClick(device) }
|
holder.itemView.setOnClickListener { onItemClick(device) }
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.databinding.ItemAddLinkedUserBinding
|
||||||
import com.example.defenseapplication.databinding.ItemAddLinkedUserBinding
|
|
||||||
|
|
||||||
data class UserItem(val name: String, val phone: String, val userId: String = "")
|
data class UserItem(val name: String, val phone: String, val userId: String = "")
|
||||||
|
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.bean.DeviceAlarmBean
|
import com.ckkj.defense_device.bean.DeviceAlarmBean
|
||||||
import com.example.defenseapplication.databinding.ItemAlarmLogBinding
|
import com.ckkj.defense_device.databinding.ItemAlarmLogBinding
|
||||||
|
|
||||||
class AlarmLogAdapter(
|
class AlarmLogAdapter(
|
||||||
private val items: List<DeviceAlarmBean>,
|
private val items: List<DeviceAlarmBean>,
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.example.defenseapplication.bean.DeviceAlarmBean
|
import com.ckkj.defense_device.bean.DeviceAlarmBean
|
||||||
import com.example.defenseapplication.databinding.ItemAlarmLogHorizontalBinding
|
import com.ckkj.defense_device.databinding.ItemAlarmLogHorizontalBinding
|
||||||
|
|
||||||
class AlarmLogHorizontalAdapter(
|
class AlarmLogHorizontalAdapter(
|
||||||
private val items: List<DeviceAlarmBean>,
|
private val items: List<DeviceAlarmBean>,
|
||||||
@@ -1,27 +1,20 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.bumptech.glide.Glide
|
||||||
import com.example.defenseapplication.databinding.ItemDeviceBinding
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
data class DeviceUi(
|
import com.ckkj.defense_device.databinding.ItemDeviceBinding
|
||||||
val name: String,
|
|
||||||
val status: String,
|
|
||||||
val deviceId: String = ""
|
|
||||||
) {
|
|
||||||
val isOnline: Boolean
|
|
||||||
get() = status == "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeviceAdapter(
|
class DeviceAdapter(
|
||||||
private val onItemClick: (DeviceUi) -> Unit = {}
|
private val onItemClick: (DeviceBean) -> Unit = {}
|
||||||
) : RecyclerView.Adapter<DeviceAdapter.DeviceViewHolder>() {
|
) : RecyclerView.Adapter<DeviceAdapter.DeviceViewHolder>() {
|
||||||
|
|
||||||
private val items = mutableListOf<DeviceUi>()
|
private val items = mutableListOf<DeviceBean>()
|
||||||
|
|
||||||
fun submitList(deviceList: List<DeviceUi>) {
|
fun submitList(deviceList: List<DeviceBean>) {
|
||||||
items.clear()
|
items.clear()
|
||||||
items.addAll(deviceList)
|
items.addAll(deviceList)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
@@ -33,15 +26,25 @@ class DeviceAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: DeviceViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: DeviceViewHolder, position: Int) {
|
||||||
holder.bind(items[position])
|
holder.bind(items[position], position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
|
private val defaultIcons = listOf(R.mipmap.img1, R.mipmap.img2, R.mipmap.img3)
|
||||||
|
|
||||||
inner class DeviceViewHolder(private val binding: ItemDeviceBinding) :
|
inner class DeviceViewHolder(private val binding: ItemDeviceBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: DeviceUi) {
|
fun bind(item: DeviceBean, position: Int) {
|
||||||
|
if (item.deviceImg.isNullOrEmpty()) {
|
||||||
|
val iconResId = defaultIcons[position % defaultIcons.size]
|
||||||
|
binding.ivDeviceIcon.setImageResource(iconResId)
|
||||||
|
} else {
|
||||||
|
Glide.with(binding.root.context)
|
||||||
|
.load(item.deviceImg)
|
||||||
|
.into(binding.ivDeviceIcon)
|
||||||
|
}
|
||||||
binding.tvDeviceType.text = item.name
|
binding.tvDeviceType.text = item.name
|
||||||
when (item.status) {
|
when (item.status) {
|
||||||
"1" -> {
|
"1" -> {
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.FamilyBean
|
import com.ckkj.defense_device.bean.FamilyBean
|
||||||
import com.example.defenseapplication.databinding.ItemFamilyBinding
|
import com.ckkj.defense_device.databinding.ItemFamilyBinding
|
||||||
|
|
||||||
class FamilyAdapter(
|
class FamilyAdapter(
|
||||||
private val onItemClick: (String) -> Unit
|
private val onItemClick: (String) -> Unit
|
||||||
@@ -64,7 +64,7 @@ class FamilyAdapter(
|
|||||||
binding.tvFamilyName.setTextColor(binding.root.context.getColor(R.color.white))
|
binding.tvFamilyName.setTextColor(binding.root.context.getColor(R.color.white))
|
||||||
binding.tvFamilyRole.setTextColor(binding.root.context.getColor(R.color.white))
|
binding.tvFamilyRole.setTextColor(binding.root.context.getColor(R.color.white))
|
||||||
binding.ivCheck.visibility = View.VISIBLE
|
binding.ivCheck.visibility = View.VISIBLE
|
||||||
binding.ivCheck.setImageResource(R.drawable.ic_check_white)
|
binding.ivCheck.setImageResource(R.mipmap.ic_check_white)
|
||||||
} else {
|
} else {
|
||||||
binding.layoutFamilyItem.setBackgroundResource(0)
|
binding.layoutFamilyItem.setBackgroundResource(0)
|
||||||
binding.tvFamilyName.setTextColor(binding.root.context.getColor(R.color.black))
|
binding.tvFamilyName.setTextColor(binding.root.context.getColor(R.color.black))
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.ItemSwitchFamilyBinding
|
import com.ckkj.defense_device.databinding.ItemSwitchFamilyBinding
|
||||||
import com.example.defenseapplication.model.FamilyItem
|
import com.ckkj.defense_device.model.FamilyItem
|
||||||
|
|
||||||
class FamilySwitchAdapter(
|
class FamilySwitchAdapter(
|
||||||
private var familyList: List<FamilyItem>,
|
private var familyList: List<FamilyItem>,
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.ItemLinkedUserBinding
|
import com.ckkj.defense_device.databinding.ItemLinkedUserBinding
|
||||||
|
|
||||||
data class LinkedUser(
|
data class LinkedUser(
|
||||||
val userId: String,
|
val userId: String,
|
||||||
@@ -1,11 +1,11 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.databinding.ItemMessageGroupTitleBinding
|
import com.ckkj.defense_device.databinding.ItemMessageGroupTitleBinding
|
||||||
import com.example.defenseapplication.databinding.ItemMessageNoticeBinding
|
import com.ckkj.defense_device.databinding.ItemMessageNoticeBinding
|
||||||
|
|
||||||
sealed class MessageListItem {
|
sealed class MessageListItem {
|
||||||
data class Header(val title: String) : MessageListItem()
|
data class Header(val title: String) : MessageListItem()
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.example.defenseapplication.adapter
|
package com.ckkj.defense_device.adapter
|
||||||
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.databinding.ItemWifiBinding
|
import com.ckkj.defense_device.databinding.ItemWifiBinding
|
||||||
|
|
||||||
class WifiListAdapter(
|
class WifiListAdapter(
|
||||||
wifiList: List<String>,
|
wifiList: List<String>,
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.example.defenseapplication.base
|
package com.ckkj.defense_device.base
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.utils.ActivityManager
|
import com.ckkj.defense_device.utils.ActivityManager
|
||||||
import com.example.defenseapplication.utils.LanguageUtil
|
import com.ckkj.defense_device.utils.LanguageUtil
|
||||||
|
|
||||||
open class BaseActivity : AppCompatActivity() {
|
open class BaseActivity : AppCompatActivity() {
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class AddDeviceBean(
|
data class AddDeviceBean(
|
||||||
val deviceEm: String? = null,//设备型号
|
val deviceEm: String? = null,//设备型号
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class AddDeviceUserRequest(
|
data class AddDeviceUserRequest(
|
||||||
val deviceId: String,
|
val deviceId: String,
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 统一返回数据基类(根据你的后端实际字段调整)
|
* 统一返回数据基类(根据你的后端实际字段调整)
|
||||||
*/
|
*/
|
||||||
data class BaseInfo(
|
data class BaseInfo(
|
||||||
val message: String? = null,
|
val msg: String? = null,
|
||||||
val code: Int = 0,
|
val code: Int = 0,
|
||||||
val data: Any? = null
|
val data: Any? = null
|
||||||
)
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
class DeleteBean {
|
class DeleteBean {
|
||||||
var deviceId: String? = null
|
var deviceId: String? = null
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class DeleteDeviceUserRequest(
|
data class DeleteDeviceUserRequest(
|
||||||
val userId: String,
|
val userId: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class DeviceAlarmResponse(
|
data class DeviceAlarmResponse(
|
||||||
val total: Int,
|
val total: Int,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class DeviceBean(
|
data class DeviceBean(
|
||||||
val alertAudio: String? = null,//告警播放
|
val alertAudio: String? = null,//告警播放
|
||||||
@@ -9,11 +9,11 @@ data class DeviceBean(
|
|||||||
val deviceFamilyId: String? = null,
|
val deviceFamilyId: String? = null,
|
||||||
val deviceImg: String? = null,
|
val deviceImg: String? = null,
|
||||||
val deviceName: String? = null,//设备名称
|
val deviceName: String? = null,//设备名称
|
||||||
val deviceNo: String? = null,//设备编号
|
val deviceNo: String = "",//设备编号
|
||||||
val deviceSn: String? = null,//设备序列号
|
val deviceSn: String = "",//设备序列号
|
||||||
val endTime: String? = null,//自动布放结束时间
|
val endTime: String? = null,//自动布放结束时间
|
||||||
val expirationTime: String? = null,
|
val expirationTime: String? = null,
|
||||||
val fwVer: String? = null,//固件版本
|
val fwVer: String= "",//固件版本
|
||||||
val id: String? = null,
|
val id: String? = null,
|
||||||
val light: String? = null,//强光开启
|
val light: String? = null,//强光开启
|
||||||
val patternPerception: String? = null,//识别模式
|
val patternPerception: String? = null,//识别模式
|
||||||
@@ -27,4 +27,13 @@ data class DeviceBean(
|
|||||||
val wifiPassword: String? = null,//WiFi密码
|
val wifiPassword: String? = null,//WiFi密码
|
||||||
val workMode: String? = null,//工作模式 0-自动 1-半自动
|
val workMode: String? = null,//工作模式 0-自动 1-半自动
|
||||||
val optionPassword: String? = null, //操作密码
|
val optionPassword: String? = null, //操作密码
|
||||||
)
|
) {
|
||||||
|
val deviceId: String
|
||||||
|
get() = id ?: ""
|
||||||
|
|
||||||
|
val name: String
|
||||||
|
get() = deviceName ?: ""
|
||||||
|
|
||||||
|
val isOnline: Boolean
|
||||||
|
get() = status == "1"
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class DeviceUserBean(
|
data class DeviceUserBean(
|
||||||
val createDept: Int ? = null, //创建部门
|
val createDept: Int ? = null, //创建部门
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class FamilyBean(
|
data class FamilyBean(
|
||||||
val id: String,
|
val id: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class FamilyMembersBean(
|
data class FamilyMembersBean(
|
||||||
val id: String? = null, // ID
|
val id: String? = null, // ID
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class GetCodeBean<T> (
|
data class GetCodeBean<T> (
|
||||||
val code:Int,
|
val code:Int,
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class InviterInfoBean(
|
||||||
|
val nickName: String? = null,
|
||||||
|
val idCard: String? = null,
|
||||||
|
val phonenumber: String? = null,
|
||||||
|
val avatar: String? = null,
|
||||||
|
val id: String? = null,
|
||||||
|
val parentId: String? = null,
|
||||||
|
val userId: String? = null,
|
||||||
|
val mac: String? = null,
|
||||||
|
val status: String? = null,
|
||||||
|
) {
|
||||||
|
fun resolveParentId(): String? =
|
||||||
|
parentId?.takeIf { it.isNotBlank() }
|
||||||
|
?: userId?.takeIf { it.isNotBlank() }
|
||||||
|
?: id?.takeIf { it.isNotBlank() }
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
|
||||||
|
data class JoinTheFamilyBean(
|
||||||
|
val parentId: String,
|
||||||
|
val inviteCode: String,
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
import android.os.Parcel
|
import android.os.Parcel
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class MessageListResponse(
|
data class MessageListResponse(
|
||||||
val total: Int,
|
val total: Int,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class ObtainInviterInformationBean(
|
data class ObtainInviterInformationBean(
|
||||||
val nickName: String? = null,
|
val nickName: String? = null,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class ObtainInviterInformationRequest(
|
data class ObtainInviterInformationRequest(
|
||||||
val childId: String
|
val childId: String
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class RecommendationCodeBean(
|
||||||
|
val inviteCode: String? = null,
|
||||||
|
val code: String? = null,
|
||||||
|
val expireTime: Long? = null,
|
||||||
|
val expire: Long? = null
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class SelectInviterInfoBean(
|
||||||
|
val code: String
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class SwitchFamilyRequest(
|
data class SwitchFamilyRequest(
|
||||||
val clientId: String,
|
val clientId: String,
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class UpdateFamilyUserRequest(
|
||||||
|
val id: String,
|
||||||
|
val optionPassword: String,
|
||||||
|
val optionStatus: String,
|
||||||
|
val status: String,
|
||||||
|
)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class UpdatePassword(
|
data class UpdatePassword(
|
||||||
val oldPassword: String,
|
val oldPassword: String,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class UpdateUserInfo(
|
data class UpdateUserInfo(
|
||||||
val userId: String?=null,
|
val userId: String?=null,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class UploadResponse(
|
data class UploadResponse(
|
||||||
val code: Int,
|
val code: Int,
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
import java.io.Serializable
|
import java.io.Serializable
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.bean
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
data class VerifyOptionPasswordRequest(
|
data class VerifyOptionPasswordRequest(
|
||||||
val optionPassword: String
|
val optionPassword: String
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class VideoStreamInfo(
|
||||||
|
val deviceNo: String,
|
||||||
|
val streamId: String,
|
||||||
|
val app: String,
|
||||||
|
val online: Boolean,
|
||||||
|
val pushUrl: String,
|
||||||
|
val playToken: String,
|
||||||
|
val expireAt: String,
|
||||||
|
val playUrls:playUrls,
|
||||||
|
val expireSeconds: Int,
|
||||||
|
)
|
||||||
|
class playUrls(
|
||||||
|
val flv: String,
|
||||||
|
val hls: String,
|
||||||
|
val rtmp: String,
|
||||||
|
val rtsp: String,
|
||||||
|
val webrtc: String,
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class VideoStreamRequest(
|
||||||
|
val deviceNo: String
|
||||||
|
)
|
||||||
@@ -1,7 +1,6 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
@@ -14,10 +13,10 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.AddDeviceAdapter
|
import com.ckkj.defense_device.adapter.AddDeviceAdapter
|
||||||
import com.example.defenseapplication.adapter.Device
|
import com.ckkj.defense_device.adapter.Device
|
||||||
import com.example.defenseapplication.databinding.AddDeviceActivityBinding
|
import com.ckkj.defense_device.databinding.AddDeviceActivityBinding
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import com.maning.mlkitscanner.scan.MNScanManager
|
import com.maning.mlkitscanner.scan.MNScanManager
|
||||||
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
@@ -23,10 +23,10 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.WifiListAdapter
|
import com.ckkj.defense_device.adapter.WifiListAdapter
|
||||||
import com.example.defenseapplication.databinding.AddFamilyActivityBinding
|
import com.ckkj.defense_device.databinding.AddFamilyActivityBinding
|
||||||
import com.example.defenseapplication.databinding.DialogWifiListBinding
|
import com.ckkj.defense_device.databinding.DialogWifiListBinding
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
//选择Wi-Fi
|
//选择Wi-Fi
|
||||||
class AddFamilyActivity : AppCompatActivity() {
|
class AddFamilyActivity : AppCompatActivity() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.drawable.AnimationDrawable
|
import android.graphics.drawable.AnimationDrawable
|
||||||
@@ -6,14 +6,9 @@ import android.os.Bundle
|
|||||||
import android.os.Handler
|
import android.os.Handler
|
||||||
import android.os.Looper
|
import android.os.Looper
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import com.ckkj.defense_device.R
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import com.ckkj.defense_device.databinding.ConnectDeviceActivityBinding
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.databinding.AddDeviceActivityBinding
|
|
||||||
import com.example.defenseapplication.databinding.ConnectDeviceActivityBinding
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
//连接设备
|
//连接设备
|
||||||
class ConnectDeviceActivity : AppCompatActivity() {
|
class ConnectDeviceActivity : AppCompatActivity() {
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.base.BaseActivity
|
import com.ckkj.defense_device.base.BaseActivity
|
||||||
import com.example.defenseapplication.databinding.HomeActivityBinding
|
import com.ckkj.defense_device.databinding.HomeActivityBinding
|
||||||
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
|
||||||
|
|
||||||
class HomeActivity : BaseActivity() {
|
class HomeActivity : BaseActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXTRA_REFRESH = "extra_refresh"
|
||||||
|
}
|
||||||
// ViewBinding 核心对象
|
// ViewBinding 核心对象
|
||||||
private lateinit var binding: HomeActivityBinding
|
private lateinit var binding: HomeActivityBinding
|
||||||
|
|
||||||
@@ -37,10 +37,10 @@ class HomeActivity : BaseActivity() {
|
|||||||
binding.tabHome.setOnClickListener {
|
binding.tabHome.setOnClickListener {
|
||||||
switchFragment(homeMenuFragment)
|
switchFragment(homeMenuFragment)
|
||||||
// 切换图标 + 文字颜色
|
// 切换图标 + 文字颜色
|
||||||
binding.ivHome.setImageResource(R.drawable.home_checked)
|
binding.ivHome.setImageResource(R.mipmap.home_checked)
|
||||||
binding.tvHome.setTextColor(resources.getColor(R.color.ic_selected))
|
binding.tvHome.setTextColor(resources.getColor(R.color.ic_selected))
|
||||||
|
|
||||||
binding.ivProfile.setImageResource(R.drawable.profile)
|
binding.ivProfile.setImageResource(R.mipmap.profile)
|
||||||
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_normal))
|
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_normal))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,12 +48,34 @@ class HomeActivity : BaseActivity() {
|
|||||||
binding.tabProfile.setOnClickListener {
|
binding.tabProfile.setOnClickListener {
|
||||||
switchFragment(personalFragment)
|
switchFragment(personalFragment)
|
||||||
// 切换图标 + 文字颜色
|
// 切换图标 + 文字颜色
|
||||||
binding.ivHome.setImageResource(R.drawable.home)
|
binding.ivHome.setImageResource(R.mipmap.home)
|
||||||
binding.tvHome.setTextColor(resources.getColor(R.color.ic_normal))
|
binding.tvHome.setTextColor(resources.getColor(R.color.ic_normal))
|
||||||
|
|
||||||
binding.ivProfile.setImageResource(R.drawable.profile_checked)
|
binding.ivProfile.setImageResource(R.mipmap.profile_checked)
|
||||||
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_selected))
|
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_selected))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleRefreshIntent(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
if (intent != null) {
|
||||||
|
setIntent(intent)
|
||||||
|
handleRefreshIntent(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleRefreshIntent(intent: Intent) {
|
||||||
|
if (intent.getBooleanExtra(EXTRA_REFRESH, false)) {
|
||||||
|
intent.removeExtra(EXTRA_REFRESH)
|
||||||
|
switchFragment(homeMenuFragment)
|
||||||
|
binding.ivHome.setImageResource(R.mipmap.home_checked)
|
||||||
|
binding.tvHome.setTextColor(resources.getColor(R.color.ic_selected))
|
||||||
|
binding.ivProfile.setImageResource(R.mipmap.profile)
|
||||||
|
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_normal))
|
||||||
|
homeMenuFragment.refreshHomeData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
@@ -7,7 +7,7 @@ import android.content.pm.PackageManager
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.graphics.Rect
|
import android.graphics.Rect
|
||||||
import android.graphics.drawable.GradientDrawable
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.util.TypedValue
|
import android.util.TypedValue
|
||||||
@@ -21,23 +21,27 @@ import android.view.ViewGroup
|
|||||||
import androidx.recyclerview.widget.GridLayoutManager
|
import androidx.recyclerview.widget.GridLayoutManager
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.alibaba.sdk.android.emas.g
|
||||||
import com.example.defenseapplication.adapter.DeviceAdapter
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.DeviceUi
|
import com.ckkj.defense_device.adapter.DeviceAdapter
|
||||||
import com.example.defenseapplication.adapter.FamilyAdapter
|
import com.ckkj.defense_device.adapter.FamilyAdapter
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.bean.FamilyBean
|
import com.ckkj.defense_device.bean.FamilyBean
|
||||||
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
import com.ckkj.defense_device.bean.SwitchFamilyRequest
|
||||||
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
import com.ckkj.defense_device.bean.SelectInviterInfoBean
|
||||||
import com.example.defenseapplication.liveVideo.LiveVideoActivity
|
import com.ckkj.defense_device.databinding.HomeMenuFragmentBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.liveVideo.LiveVideoActivity
|
||||||
import com.example.defenseapplication.utils.DeviceUpdateEvent
|
import com.ckkj.defense_device.personal.JoinFamilyInviteActivity
|
||||||
import com.example.defenseapplication.utils.FamilySwitchEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.MessageStatusManager
|
import com.ckkj.defense_device.utils.DeviceUpdateEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.FamilySwitchEvent
|
||||||
import com.example.defenseapplication.utils.UserinfoUtil
|
import com.ckkj.defense_device.utils.MessageStatusManager
|
||||||
import com.example.defenseapplication.view.DefenseDialogs
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.showDefenseDialog
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
|
import com.ckkj.defense_device.view.DefenseDialogs
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.ckkj.defense_device.view.PullRefreshLayout
|
||||||
|
import com.ckkj.defense_device.view.showDefenseDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import com.maning.mlkitscanner.scan.MNScanManager
|
import com.maning.mlkitscanner.scan.MNScanManager
|
||||||
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||||
@@ -45,6 +49,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.json.JSONObject
|
||||||
//主页碎片
|
//主页碎片
|
||||||
class HomeMenuFragment : Fragment() {
|
class HomeMenuFragment : Fragment() {
|
||||||
// ViewBinding
|
// ViewBinding
|
||||||
@@ -59,6 +64,9 @@ class HomeMenuFragment : Fragment() {
|
|||||||
private val pageSize = 10
|
private val pageSize = 10
|
||||||
private var hasMore = true
|
private var hasMore = true
|
||||||
private var isLoading = false
|
private var isLoading = false
|
||||||
|
private var loadingDialog: LoadingDialog? = null
|
||||||
|
private var lastNoMoreToastTime: Long = 0L
|
||||||
|
private val noMoreToastInterval: Long = 1500L
|
||||||
|
|
||||||
private val requestPermissionsLauncher = registerForActivityResult(
|
private val requestPermissionsLauncher = registerForActivityResult(
|
||||||
ActivityResultContracts.RequestMultiplePermissions()
|
ActivityResultContracts.RequestMultiplePermissions()
|
||||||
@@ -122,23 +130,86 @@ class HomeMenuFragment : Fragment() {
|
|||||||
MNScanManager.RESULT_SUCCESS -> {
|
MNScanManager.RESULT_SUCCESS -> {
|
||||||
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
||||||
if (!result.isNullOrEmpty()) {
|
if (!result.isNullOrEmpty()) {
|
||||||
ToastUtils.showToast(requireContext(), "扫码成功: $result")
|
val inviteCode = parseInviteCode(result[0])
|
||||||
|
if (inviteCode.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(requireContext(), "无效的邀请码", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.showToast(requireContext(), "扫码结果为空")
|
fetchInviterInfo(inviteCode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), "扫码结果为空", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MNScanManager.RESULT_FAIL -> {
|
MNScanManager.RESULT_FAIL -> {
|
||||||
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||||
ToastUtils.showToast(requireContext(), "扫码失败: $error")
|
Toast.makeText(requireContext(), "扫码失败: $error", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
MNScanManager.RESULT_CANCLE -> {
|
MNScanManager.RESULT_CANCLE -> {
|
||||||
ToastUtils.showToast(requireContext(), "扫码取消")
|
Toast.makeText(requireContext(), "扫码取消", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun parseInviteCode(scanResult: String): String? {
|
||||||
|
val trimmed = scanResult.trim()
|
||||||
|
if (trimmed.isEmpty()) return null
|
||||||
|
return try {
|
||||||
|
if (trimmed.startsWith("{")) {
|
||||||
|
JSONObject(trimmed).optString("code").takeIf { it.isNotEmpty() }
|
||||||
|
} else {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInviterInfo(inviteCode: String) {
|
||||||
|
val loadingDialog = LoadingDialog(requireActivity()).setMessage(this.getString(R.string.loading)).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.selectInviterInfo(SelectInviterInfoBean(code = inviteCode))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val inviter = response.data
|
||||||
|
val parentId = inviter.resolveParentId()
|
||||||
|
if (parentId.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
getString(R.string.network_error),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
val intent = Intent(requireContext(), JoinFamilyInviteActivity::class.java).apply {
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_INVITE_CODE, inviteCode)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_NICK_NAME, inviter.nickName)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_AVATAR, inviter.avatar)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_PARENT_ID, parentId)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_USER_ID, inviter.userId)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
||||||
override fun onUnreadCountChanged(count: Int) {
|
override fun onUnreadCountChanged(count: Int) {
|
||||||
updateUnreadCountUI(count)
|
updateUnreadCountUI(count)
|
||||||
@@ -197,12 +268,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
// 为 LinearLayout 设置渐变背景
|
binding.gradientLayout.setBackgroundColor(Color.TRANSPARENT)
|
||||||
setGradientBackground(
|
|
||||||
view = binding.gradientLayout,
|
|
||||||
startColor = Color.parseColor("#EBDCED"),
|
|
||||||
endColor = Color.parseColor("#CAF4FF")
|
|
||||||
)
|
|
||||||
binding.message.setOnClickListener {
|
binding.message.setOnClickListener {
|
||||||
val intent = Intent(requireContext(), MessageActivity::class.java)
|
val intent = Intent(requireContext(), MessageActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
@@ -236,9 +302,11 @@ class HomeMenuFragment : Fragment() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
binding.swipeRefreshLayout.setOnRefreshListener(object : PullRefreshLayout.OnRefreshListener {
|
||||||
|
override fun onRefresh() {
|
||||||
refreshDeviceList()
|
refreshDeviceList()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
binding.rvDeviceList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
binding.rvDeviceList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
@@ -246,9 +314,24 @@ class HomeMenuFragment : Fragment() {
|
|||||||
val layoutManager = recyclerView.layoutManager as GridLayoutManager
|
val layoutManager = recyclerView.layoutManager as GridLayoutManager
|
||||||
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
|
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
|
||||||
val totalItemCount = layoutManager.itemCount
|
val totalItemCount = layoutManager.itemCount
|
||||||
|
val firstVisibleItemPosition = layoutManager.findFirstVisibleItemPosition()
|
||||||
|
|
||||||
|
if (firstVisibleItemPosition == 0) {
|
||||||
|
val firstChild = layoutManager.findViewByPosition(0)
|
||||||
|
firstChild?.let { child ->
|
||||||
|
val top = child.top
|
||||||
|
if (top >= 0) {
|
||||||
|
val offset = (top.toFloat() / dpToPx(80f)).coerceIn(0f, 1f)
|
||||||
|
binding.gradientLayout.translationY = -offset * dpToPx(20f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!isLoading && hasMore && lastVisibleItemPosition >= totalItemCount - 1 && dy > 0) {
|
if (!isLoading && hasMore && lastVisibleItemPosition >= totalItemCount - 1 && dy > 0) {
|
||||||
loadMoreDevices()
|
loadMoreDevices()
|
||||||
|
} else if (!hasMore && !isLoading && lastVisibleItemPosition >= totalItemCount - 1
|
||||||
|
&& dy > 0 && totalItemCount > 0) {
|
||||||
|
showNoMoreToast()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -285,6 +368,10 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun refreshHomeData() {
|
||||||
|
fetchFamilyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun fetchFamilyList() {
|
private fun fetchFamilyList() {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -321,18 +408,22 @@ class HomeMenuFragment : Fragment() {
|
|||||||
Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
|
Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
|
||||||
if (canViewDevice) {
|
if (canViewDevice) {
|
||||||
binding.tvDeviceTitle.visibility = View.VISIBLE
|
binding.tvDeviceTitle.visibility = View.VISIBLE
|
||||||
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
binding.rvDeviceList.visibility = View.VISIBLE
|
binding.rvDeviceList.visibility = View.VISIBLE
|
||||||
binding.message.visibility = View.VISIBLE
|
binding.message.visibility = View.VISIBLE
|
||||||
binding.addFamily.visibility = View.VISIBLE
|
binding.addFamily.visibility = View.VISIBLE
|
||||||
binding.add.visibility = View.VISIBLE
|
binding.add.visibility = View.VISIBLE
|
||||||
binding.layoutNoPermission.visibility = View.GONE
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
binding.tvDeviceTitle.visibility = View.GONE
|
binding.tvDeviceTitle.visibility = View.GONE
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
binding.rvDeviceList.visibility = View.GONE
|
binding.rvDeviceList.visibility = View.GONE
|
||||||
binding.message.visibility = View.GONE
|
binding.message.visibility = View.GONE
|
||||||
binding.addFamily.visibility = View.GONE
|
binding.addFamily.visibility = View.GONE
|
||||||
binding.add.visibility = View.GONE
|
binding.add.visibility = View.GONE
|
||||||
binding.layoutNoPermission.visibility = View.VISIBLE
|
binding.layoutNoPermission.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +447,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
canViewDevice = userInfo?.role == "appadmin" && familyBean.role != "member"
|
canViewDevice = userInfo?.role == "appadmin" && familyBean.role != "member"
|
||||||
updateAdminUI()
|
updateAdminUI()
|
||||||
updateFamilyDisplayText(familyName)
|
updateFamilyDisplayText(familyName)
|
||||||
fetchDeviceList()
|
fetchDeviceList(showLoading = true)
|
||||||
FamilySwitchEvent.notifyFamilySwitched(familyName)
|
FamilySwitchEvent.notifyFamilySwitched(familyName)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
||||||
@@ -370,15 +461,20 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchDeviceList(page: Int = 1, isLoadMore: Boolean = false) {
|
private fun fetchDeviceList(page: Int = 1, isLoadMore: Boolean = false, showLoading: Boolean = false) {
|
||||||
if (!canViewDevice || isLoading) return
|
if (!canViewDevice || isLoading) return
|
||||||
|
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
|
||||||
|
loadingDialog = if (showLoading) LoadingDialog(requireActivity()).setMessage(getString(R.string.loading)).apply { show() } else null
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getDeviceList()
|
val response = RetrofitNetwork.getNetworkService().getDeviceList()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
if (!isAdded) return@withContext
|
||||||
|
loadingDialog?.dismiss()
|
||||||
|
loadingDialog = null
|
||||||
Log.d("DeviceList", "code = ${response.code}, data = ${response.data}")
|
Log.d("DeviceList", "code = ${response.code}, data = ${response.data}")
|
||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
val newDevices = response.data
|
val newDevices = response.data
|
||||||
@@ -390,32 +486,47 @@ class HomeMenuFragment : Fragment() {
|
|||||||
hasMore = newDevices.size >= pageSize
|
hasMore = newDevices.size >= pageSize
|
||||||
}
|
}
|
||||||
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
||||||
|
showDeviceContent()
|
||||||
updateDeviceList()
|
updateDeviceList()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
noNetwork()
|
||||||
|
val errorMsg = response.msg.ifBlank { getString(R.string.network_error) }
|
||||||
|
Toast.makeText(requireContext(), errorMsg, Toast.LENGTH_SHORT).show()
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
hasMore = false
|
hasMore = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
binding.swipeRefreshLayout.finishRefresh()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
if (!isAdded) return@withContext
|
||||||
|
loadingDialog?.dismiss()
|
||||||
|
loadingDialog = null
|
||||||
|
noNetwork()
|
||||||
Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
isLoading = false
|
isLoading = false
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
hasMore = false
|
hasMore = false
|
||||||
}
|
}
|
||||||
|
binding.swipeRefreshLayout.finishRefresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showNoMoreToast() {
|
||||||
|
val now = System.currentTimeMillis()
|
||||||
|
if (now - lastNoMoreToastTime < noMoreToastInterval) return
|
||||||
|
lastNoMoreToastTime = now
|
||||||
|
ToastUtils.showToast(requireContext(), getString(R.string.no_more_data))
|
||||||
|
}
|
||||||
|
|
||||||
private fun refreshDeviceList() {
|
private fun refreshDeviceList() {
|
||||||
currentPage = 1
|
currentPage = 1
|
||||||
hasMore = true
|
hasMore = true
|
||||||
fetchDeviceList(currentPage, false)
|
fetchDeviceList(currentPage, false)
|
||||||
binding.swipeRefreshLayout.isRefreshing = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun loadMoreDevices() {
|
private fun loadMoreDevices() {
|
||||||
@@ -445,26 +556,38 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDeviceList() {
|
private fun showDeviceContent() {
|
||||||
val deviceUiList = deviceBeanList.map {
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
DeviceUi(it.deviceName ?: "", it.status ?: "", it.id ?: "")
|
binding.rvDeviceList.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceUiList.isEmpty()) {
|
private fun noNetwork() {
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
|
binding.rvDeviceList.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDeviceList() {
|
||||||
|
if (deviceBeanList.isEmpty()) {
|
||||||
deviceAdapter.submitList(listOf(
|
deviceAdapter.submitList(listOf(
|
||||||
DeviceUi(getString(R.string.no_device), "0")
|
DeviceBean(deviceName = getString(R.string.no_device), status = "0")
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
deviceAdapter.submitList(deviceUiList)
|
deviceAdapter.submitList(deviceBeanList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onDeviceClicked(device: DeviceUi) {
|
private fun onDeviceClicked(device: DeviceBean) {
|
||||||
if (device.isOnline) {
|
if (device.isOnline) {
|
||||||
DeviceIdEvent.setDeviceId(device.deviceId)
|
DeviceIdEvent.setDeviceId(device.deviceId)
|
||||||
val intent = Intent(requireContext(), LiveVideoActivity::class.java)
|
val intent = Intent(requireContext(), LiveVideoActivity::class.java)
|
||||||
intent.putExtra("device_id", device.deviceId)
|
intent.putExtra("device_id", device.deviceId)
|
||||||
intent.putExtra("device_name", device.name)
|
intent.putExtra("device_name", device.name)
|
||||||
|
intent.putExtra("deviceNo", device.deviceNo)
|
||||||
|
intent.putExtra("light", device.light)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
showDefenseDialog(
|
showDefenseDialog(
|
||||||
@@ -481,6 +604,14 @@ class HomeMenuFragment : Fragment() {
|
|||||||
).toInt()
|
).toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun dpToPx(dp: Float): Float {
|
||||||
|
return TypedValue.applyDimension(
|
||||||
|
TypedValue.COMPLEX_UNIT_DIP,
|
||||||
|
dp,
|
||||||
|
resources.displayMetrics
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private class GridHorizontalSpaceItemDecoration(
|
private class GridHorizontalSpaceItemDecoration(
|
||||||
private val horizontalSpace: Int
|
private val horizontalSpace: Int
|
||||||
) : RecyclerView.ItemDecoration() {
|
) : RecyclerView.ItemDecoration() {
|
||||||
@@ -501,19 +632,10 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setGradientBackground(
|
|
||||||
view: View,
|
|
||||||
startColor: Int,
|
|
||||||
endColor: Int,
|
|
||||||
orientation: GradientDrawable.Orientation = GradientDrawable.Orientation.TL_BR
|
|
||||||
) {
|
|
||||||
val gradientDrawable = GradientDrawable(orientation, intArrayOf(startColor, endColor))
|
|
||||||
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
|
|
||||||
view.background = gradientDrawable
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroyView() {
|
override fun onDestroyView() {
|
||||||
super.onDestroyView()
|
super.onDestroyView()
|
||||||
|
loadingDialog?.dismiss()
|
||||||
|
loadingDialog = null
|
||||||
binding.rvFamilyList.adapter = null
|
binding.rvFamilyList.adapter = null
|
||||||
binding.rvDeviceList.adapter = null
|
binding.rvDeviceList.adapter = null
|
||||||
MessageStatusManager.removeListener(unreadCountChangeListener)
|
MessageStatusManager.removeListener(unreadCountChangeListener)
|
||||||
@@ -1,15 +1,18 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.adapter.MessageListAdapter
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.MessageListItem
|
import com.ckkj.defense_device.adapter.MessageListAdapter
|
||||||
import com.example.defenseapplication.databinding.MessageActivityBinding
|
import com.ckkj.defense_device.adapter.MessageListItem
|
||||||
import com.example.defenseapplication.utils.MessageStatusManager
|
import com.ckkj.defense_device.databinding.MessageActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.MessageStatusManager
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.ckkj.defense_device.view.PullRefreshLayout
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -19,13 +22,13 @@ import kotlinx.coroutines.withContext
|
|||||||
class MessageActivity : AppCompatActivity() {
|
class MessageActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: MessageActivityBinding
|
private lateinit var binding: MessageActivityBinding
|
||||||
private val messageAdapter by lazy { MessageListAdapter() }
|
private val messageAdapter by lazy { MessageListAdapter() }
|
||||||
|
private lateinit var loadingDialog: LoadingDialog
|
||||||
|
|
||||||
private var currentPage = 1
|
private var currentPage = 1
|
||||||
private val pageSize = 10
|
private val pageSize = 10
|
||||||
private var isLoading = false
|
private var isLoading = false
|
||||||
private var hasMoreData = true
|
private var hasMoreData = true
|
||||||
private val allMessages = mutableListOf<com.example.defenseapplication.bean.MessageBean>()
|
private val allMessages = mutableListOf<com.ckkj.defense_device.bean.MessageBean>()
|
||||||
private var lastLoadedCount = 0
|
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -41,10 +44,19 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initView() {
|
private fun initView() {
|
||||||
|
loadingDialog = LoadingDialog(this).setMessage(getString(R.string.loading))
|
||||||
binding.ivBack.setOnClickListener { finish() }
|
binding.ivBack.setOnClickListener { finish() }
|
||||||
binding.rvMessageList.layoutManager = LinearLayoutManager(this)
|
binding.rvMessageList.layoutManager = LinearLayoutManager(this)
|
||||||
binding.rvMessageList.adapter = messageAdapter
|
binding.rvMessageList.adapter = messageAdapter
|
||||||
|
|
||||||
|
binding.swipeRefreshLayout.setOnRefreshListener(object : PullRefreshLayout.OnRefreshListener {
|
||||||
|
override fun onRefresh() {
|
||||||
|
currentPage = 1
|
||||||
|
hasMoreData = true
|
||||||
|
loadMessageList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
binding.rvMessageList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
binding.rvMessageList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
super.onScrolled(recyclerView, dx, dy)
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
@@ -70,20 +82,21 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
if (isLoading) return
|
if (isLoading) return
|
||||||
|
|
||||||
isLoading = true
|
isLoading = true
|
||||||
|
|
||||||
|
if (currentPage == 1) {
|
||||||
|
showLoading()
|
||||||
|
}
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val messageResponse = RetrofitNetwork.getNetworkService().getMessage(
|
val messageResponse = RetrofitNetwork.getNetworkService().getMessage(
|
||||||
pageNum = currentPage,
|
pageNum = currentPage,
|
||||||
pageSize = pageSize
|
pageSize = pageSize
|
||||||
)
|
)
|
||||||
println("total: ${messageResponse.total}")
|
|
||||||
println("rows size: ${messageResponse.rows.size}")
|
|
||||||
println("当前页:$currentPage, 加载条数:${messageResponse.rows.size}")
|
|
||||||
|
|
||||||
val newMessages = messageResponse.rows
|
val newMessages = messageResponse.rows
|
||||||
val loadedCount = newMessages.size
|
|
||||||
|
|
||||||
if (loadedCount < pageSize) {
|
if (newMessages.size < pageSize) {
|
||||||
hasMoreData = false
|
hasMoreData = false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,11 +111,11 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
allMessages.clear()
|
allMessages.clear()
|
||||||
}
|
}
|
||||||
allMessages.addAll(newMessages)
|
allMessages.addAll(newMessages)
|
||||||
lastLoadedCount = loadedCount
|
|
||||||
|
|
||||||
val items = convertToMessageListItems(allMessages)
|
val items = convertToMessageListItems(allMessages)
|
||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
hideEmptyState()
|
hideEmptyState()
|
||||||
messageAdapter.submitList(items)
|
messageAdapter.submitList(items)
|
||||||
|
|
||||||
@@ -116,20 +129,24 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (allMessages.isEmpty()) {
|
if (allMessages.isEmpty()) {
|
||||||
println("items is empty, showing empty state")
|
|
||||||
showEmptyState()
|
showEmptyState()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
println("Exception: ${e.message}")
|
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (allMessages.isEmpty()) {
|
if (allMessages.isEmpty()) {
|
||||||
showEmptyState()
|
noNetwork()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
if (currentPage == 1) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
hideLoading()
|
||||||
|
binding.swipeRefreshLayout.finishRefresh()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -141,17 +158,35 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
loadMessageList()
|
loadMessageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun showLoading() {
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
|
binding.emptyLayout.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
|
loadingDialog.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun hideLoading() {
|
||||||
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
|
||||||
private fun showEmptyState() {
|
private fun showEmptyState() {
|
||||||
binding.rvMessageList.visibility = View.GONE
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
binding.emptyLayout.visibility = View.VISIBLE
|
binding.emptyLayout.visibility = View.VISIBLE
|
||||||
binding.tvNoMoreData.visibility = View.GONE
|
binding.tvNoMoreData.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun hideEmptyState() {
|
private fun hideEmptyState() {
|
||||||
binding.rvMessageList.visibility = View.VISIBLE
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
binding.emptyLayout.visibility = View.GONE
|
binding.emptyLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
binding.tvNoMoreData.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
private fun showNoMoreDataHint() {
|
private fun showNoMoreDataHint() {
|
||||||
binding.tvNoMoreData.visibility = View.VISIBLE
|
binding.tvNoMoreData.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
@@ -160,14 +195,11 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
binding.tvNoMoreData.visibility = View.GONE
|
binding.tvNoMoreData.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun convertToMessageListItems(messages: List<com.example.defenseapplication.bean.MessageBean>): List<MessageListItem> {
|
private fun convertToMessageListItems(messages: List<com.ckkj.defense_device.bean.MessageBean>): List<MessageListItem> {
|
||||||
val items = mutableListOf<MessageListItem>()
|
val items = mutableListOf<MessageListItem>()
|
||||||
val groupedMessages = messages.groupBy { extractDate(it.createTime ?: "") }
|
val groupedMessages = messages.groupBy { extractDate(it.createTime ?: "") }
|
||||||
groupedMessages.forEach { (date, messageList) ->
|
groupedMessages.forEach { (date, messageList) ->
|
||||||
val headerTitle = formatDate(date)
|
val headerTitle = formatDate(date)
|
||||||
messageList.forEachIndexed { index, message ->
|
|
||||||
println(" 消息${index + 1}: id=${message.id}, categoryName=${message.categoryName}, createTime=${message.createTime}")
|
|
||||||
}
|
|
||||||
items.add(MessageListItem.Header(headerTitle))
|
items.add(MessageListItem.Header(headerTitle))
|
||||||
messageList.forEach { message ->
|
messageList.forEach { message ->
|
||||||
items.add(
|
items.add(
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -9,21 +9,23 @@ import android.view.ViewGroup
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.UserInfoBean
|
import com.ckkj.defense_device.bean.UserInfoBean
|
||||||
import com.example.defenseapplication.databinding.PersonalFragmentBinding
|
import com.ckkj.defense_device.databinding.PersonalFragmentBinding
|
||||||
import com.example.defenseapplication.liveVideo.LinkedUserActivity
|
import com.ckkj.defense_device.liveVideo.LinkedUserActivity
|
||||||
import com.example.defenseapplication.personal.FaceManagementActivity
|
import com.ckkj.defense_device.personal.FaceManagementActivity
|
||||||
import com.example.defenseapplication.personal.PasswordManagementActivity
|
import com.ckkj.defense_device.personal.PasswordManagementActivity
|
||||||
import com.example.defenseapplication.personal.PersonalProfileActivity
|
import com.ckkj.defense_device.personal.PersonalProfileActivity
|
||||||
import com.example.defenseapplication.utils.AppLanguage
|
import com.ckkj.defense_device.personal.SettingsMenusActivity
|
||||||
import com.example.defenseapplication.utils.LanguageUtil
|
import com.ckkj.defense_device.utils.AppLanguage
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.LanguageUtil
|
||||||
import com.example.defenseapplication.utils.UserinfoUtil
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.utils.ActivityManager
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
import com.example.defenseapplication.view.FamilySwitchDialog
|
import com.ckkj.defense_device.utils.ActivityManager
|
||||||
import com.example.defenseapplication.view.LanguageDialog
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.example.defenseapplication.home.HomeActivity
|
import com.ckkj.defense_device.view.FamilySwitchDialog
|
||||||
|
import com.ckkj.defense_device.view.LanguageDialog
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -34,6 +36,7 @@ class PersonalFragment : Fragment() {
|
|||||||
// ViewBinding
|
// ViewBinding
|
||||||
private var _binding: PersonalFragmentBinding? = null
|
private var _binding: PersonalFragmentBinding? = null
|
||||||
private val binding get() = _binding!!
|
private val binding get() = _binding!!
|
||||||
|
private var loadingDialog: LoadingDialog? = null
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
fetchUserInfo()
|
fetchUserInfo()
|
||||||
@@ -49,10 +52,10 @@ class PersonalFragment : Fragment() {
|
|||||||
.titleBar(binding.headerLayout)
|
.titleBar(binding.headerLayout)
|
||||||
.init()
|
.init()
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(R.drawable.img)
|
.load("")
|
||||||
.circleCrop()
|
.circleCrop()
|
||||||
.into(binding.ivAvatar)
|
.into(binding.ivAvatar)
|
||||||
binding.headerLayout.setOnClickListener {
|
binding.ivAvatar.setOnClickListener {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
||||||
@@ -101,13 +104,20 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
// 退出登录点击事件
|
// 退出登录点击事件
|
||||||
binding.btnLogout.setOnClickListener {
|
binding.btnLogout.setOnClickListener {
|
||||||
|
val dialog = CustomDialogFragmentText()
|
||||||
|
.setTitle(getString(R.string.tip))
|
||||||
|
.setMessage(getString(R.string.logout_confirm))
|
||||||
|
.setShowInput(false)
|
||||||
|
.setNegativeText(getString(R.string.cancel))
|
||||||
|
.setPositiveText(getString(R.string.confirm))
|
||||||
|
.setOnConfirmListener {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().logout()
|
val response = RetrofitNetwork.getNetworkService().logout()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
UserinfoUtil.clearUserInfo()
|
UserinfoUtil.clearUserInfo()
|
||||||
val intent = Intent(requireContext(), com.example.defenseapplication.login.LoginActivity::class.java)
|
val intent = Intent(requireContext(), com.ckkj.defense_device.login.LoginActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
requireActivity().finish()
|
requireActivity().finish()
|
||||||
@@ -123,6 +133,12 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dialog.show(childFragmentManager, "logout_dialog")
|
||||||
|
}
|
||||||
|
binding.ivMenu.setOnClickListener {
|
||||||
|
val intent = Intent(requireContext(), SettingsMenusActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
fetchCurrentFamily()
|
fetchCurrentFamily()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
@@ -220,6 +236,7 @@ class PersonalFragment : Fragment() {
|
|||||||
|
|
||||||
|
|
||||||
private fun fetchUserInfo() {
|
private fun fetchUserInfo() {
|
||||||
|
loadingDialog = LoadingDialog(requireContext()).setMessage(getString(R.string.loading)).apply { show() }
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
||||||
@@ -230,6 +247,11 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
} finally {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog?.dismiss()
|
||||||
|
loadingDialog = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -243,8 +265,8 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
userInfo.avatar?.let {
|
userInfo.avatar?.let {
|
||||||
val requestOptions = RequestOptions()
|
val requestOptions = RequestOptions()
|
||||||
.placeholder(R.drawable.img) // 加载中显示
|
.placeholder(R.mipmap.img) // 加载中显示
|
||||||
.error(R.drawable.img) // 失败时显示
|
.error(R.mipmap.img) // 失败时显示
|
||||||
|
|
||||||
Glide.with(this)
|
Glide.with(this)
|
||||||
.load(it) // 如果 avatar 为 null,Glide 会直接回调 error
|
.load(it) // 如果 avatar 为 null,Glide 会直接回调 error
|
||||||
@@ -258,6 +280,7 @@ class PersonalFragment : Fragment() {
|
|||||||
} else {
|
} else {
|
||||||
getString(R.string.member)
|
getString(R.string.member)
|
||||||
}
|
}
|
||||||
|
binding.tvRoleTag.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,14 +1,13 @@
|
|||||||
package com.example.defenseapplication.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.bean.AddDeviceBean
|
import com.ckkj.defense_device.bean.AddDeviceBean
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.databinding.SetNameActivityBinding
|
||||||
import com.example.defenseapplication.databinding.SetNameActivityBinding
|
import com.ckkj.defense_device.liveVideo.LiveVideoActivity
|
||||||
import com.example.defenseapplication.liveVideo.LiveVideoActivity
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -61,7 +60,9 @@ class SetNameActivity : AppCompatActivity() {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (result.code == 200) {
|
if (result.code == 200) {
|
||||||
Toast.makeText(this@SetNameActivity, "设备添加成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@SetNameActivity, "设备添加成功", Toast.LENGTH_SHORT).show()
|
||||||
startActivity(Intent(this@SetNameActivity, LiveVideoActivity::class.java))
|
startActivity(Intent(this@SetNameActivity, HomeActivity::class.java).apply {
|
||||||
|
putExtra(HomeActivity.EXTRA_REFRESH, true)
|
||||||
|
})
|
||||||
finish()
|
finish()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this@SetNameActivity, result.msg ?: "添加失败", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@SetNameActivity, result.msg ?: "添加失败", Toast.LENGTH_SHORT).show()
|
||||||
@@ -0,0 +1,41 @@
|
|||||||
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.ckkj.defense_device.databinding.ActivityStartBinding
|
||||||
|
import com.ckkj.defense_device.login.LoginActivity
|
||||||
|
import com.ckkj.defense_device.utils.ApiConfig
|
||||||
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
|
||||||
|
class StartActivity : AppCompatActivity() {
|
||||||
|
private lateinit var binding: ActivityStartBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = ActivityStartBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(null)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
// 延迟2秒后再判断登录状态
|
||||||
|
Handler(Looper.getMainLooper()).postDelayed({
|
||||||
|
val userInfo = UserinfoUtil.getUserInfo()
|
||||||
|
if (userInfo != null) {
|
||||||
|
// 设置token
|
||||||
|
ApiConfig.authToken = userInfo.access_token
|
||||||
|
val intent = Intent(this, HomeActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
val intent = Intent(this, LoginActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
finish()
|
||||||
|
}, 2000) // 2秒延迟
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,21 +1,22 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.AddLinkedUserAdapter
|
import com.ckkj.defense_device.adapter.AddLinkedUserAdapter
|
||||||
import com.example.defenseapplication.adapter.UserItem
|
import com.ckkj.defense_device.adapter.UserItem
|
||||||
import com.example.defenseapplication.bean.AddDeviceUserRequest
|
import com.ckkj.defense_device.bean.AddDeviceUserRequest
|
||||||
import com.example.defenseapplication.bean.FamilyMembersBean
|
import com.ckkj.defense_device.bean.FamilyMembersBean
|
||||||
import com.example.defenseapplication.databinding.AddLinkedUserActivityBinding
|
import com.ckkj.defense_device.databinding.AddLinkedUserActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.DeviceUserUpdateEvent
|
import com.ckkj.defense_device.utils.DeviceUserUpdateEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -95,19 +96,33 @@ class AddLinkedUserActivity : AppCompatActivity() {
|
|||||||
Toast.makeText(this@AddLinkedUserActivity, "暂无家庭成员数据", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "暂无家庭成员数据", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
hide()
|
||||||
Toast.makeText(this@AddLinkedUserActivity, "请求失败: ${response.msg}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "请求失败: ${response.msg}", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
android.util.Log.e("AddLinkedUserActivity", "网络请求异常", e)
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
|
noNetwork()
|
||||||
Toast.makeText(this@AddLinkedUserActivity, "网络请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "网络请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hide() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvAddLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvAddLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateFamilyMemberList(familyMembersList: List<FamilyMembersBean>) {
|
private fun updateFamilyMemberList(familyMembersList: List<FamilyMembersBean>) {
|
||||||
fullUserItemList.clear()
|
fullUserItemList.clear()
|
||||||
familyMembersList.forEach { member ->
|
familyMembersList.forEach { member ->
|
||||||
@@ -0,0 +1,437 @@
|
|||||||
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.media.AudioManager
|
||||||
|
import android.media.MediaScannerConnection
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.Environment
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.adapter.AlarmLogAdapter
|
||||||
|
import com.ckkj.defense_device.bean.DeviceAlarmBean
|
||||||
|
import com.ckkj.defense_device.databinding.AlarmLogActivityBinding
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||||
|
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
||||||
|
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
||||||
|
import com.bigkoo.pickerview.builder.TimePickerBuilder
|
||||||
|
import com.bigkoo.pickerview.listener.OnTimeSelectListener
|
||||||
|
import com.ckkj.defense_device.view.CustomDialogFragment
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.ckkj.defense_device.view.MyGSYVideoPlayer
|
||||||
|
import com.ckkj.defense_device.view.showDefenseDialog
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import java.io.File
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
|
import android.net.Uri
|
||||||
|
import com.chiclaim.android.downloader.DownloadRequest
|
||||||
|
import com.chiclaim.android.downloader.DownloadListener
|
||||||
|
|
||||||
|
//告警记录
|
||||||
|
class AlarmLogActivity : AppCompatActivity() {
|
||||||
|
private lateinit var binding: AlarmLogActivityBinding
|
||||||
|
private lateinit var calendar: Calendar
|
||||||
|
private var adapter: AlarmLogAdapter? = null
|
||||||
|
private val alarmList = mutableListOf<DeviceAlarmBean>()
|
||||||
|
private val originalAlarmList = mutableListOf<DeviceAlarmBean>()
|
||||||
|
private var deviceId: String? = null
|
||||||
|
private var isLoading = false
|
||||||
|
private var videoUrl: String? = null
|
||||||
|
private var orientationUtils: OrientationUtils? = null
|
||||||
|
|
||||||
|
private var isMute = false
|
||||||
|
private lateinit var audioManager: AudioManager
|
||||||
|
private var currentAlarmItem: DeviceAlarmBean? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = AlarmLogActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(null)
|
||||||
|
.init()
|
||||||
|
audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
|
||||||
|
|
||||||
|
deviceId = intent.getStringExtra("device_id")
|
||||||
|
videoUrl = intent.getStringExtra("video_url")
|
||||||
|
calendar = Calendar.getInstance()
|
||||||
|
updateDateDisplay()
|
||||||
|
initVideoPlayer()
|
||||||
|
initRecyclerView()
|
||||||
|
fetchAlarmList()
|
||||||
|
initListener()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initVideoPlayer() {
|
||||||
|
val videoUrl = intent.getStringExtra("video_url") ?: "https://media.w3.org/2010/05/sintel/trailer.mp4"
|
||||||
|
val progressDrawable = ContextCompat.getDrawable(this, R.drawable.progress_video)
|
||||||
|
val thumbDrawable = ContextCompat.getDrawable(this, R.drawable.thumb_video)
|
||||||
|
|
||||||
|
orientationUtils = OrientationUtils(this, binding.exoPlayContextId)
|
||||||
|
orientationUtils?.isEnable = true
|
||||||
|
|
||||||
|
GSYVideoOptionBuilder()
|
||||||
|
.setUrl(videoUrl)
|
||||||
|
.setVideoTitle("")
|
||||||
|
.setNeedLockFull(true)
|
||||||
|
.setCacheWithPlay(false)
|
||||||
|
.setRotateViewAuto(true)
|
||||||
|
.setLockLand(false)
|
||||||
|
.setShowFullAnimation(true)
|
||||||
|
.setNeedShowWifiTip(false)
|
||||||
|
.setEnlargeImageRes(R.mipmap.full_size)
|
||||||
|
.setShrinkImageRes(R.mipmap.full_screen)
|
||||||
|
.setBottomShowProgressBarDrawable(progressDrawable, thumbDrawable)
|
||||||
|
.setVideoAllCallBack(object : GSYSampleCallBack() {
|
||||||
|
override fun onPrepared(url: String?, vararg objects: Any?) {
|
||||||
|
super.onPrepared(url, *objects)
|
||||||
|
orientationUtils?.isEnable = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
|
||||||
|
super.onQuitFullscreen(url, *objects)
|
||||||
|
orientationUtils?.backToProtVideo()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.build(binding.exoPlayContextId)
|
||||||
|
binding.exoPlayContextId.backButton.setOnClickListener {
|
||||||
|
|
||||||
|
if (orientationUtils?.isLand == 1) {
|
||||||
|
// 当前全屏,先退出全屏
|
||||||
|
binding.exoPlayContextId.fullscreenButton.performClick()
|
||||||
|
} else {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.exoPlayContextId.onControlVisibilityChanged = { show ->
|
||||||
|
Log.e("GSY_TEST", "Activity收到回调 show=$show")
|
||||||
|
val visible = if (show) View.VISIBLE else View.GONE
|
||||||
|
|
||||||
|
binding.ivDownload.visibility = visible
|
||||||
|
binding.ivDelete.visibility = visible
|
||||||
|
binding.ivMute.visibility = visible
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.exoPlayContextId.startPlayLogic()
|
||||||
|
binding.exoPlayContextId.fullscreenButton.setOnClickListener {
|
||||||
|
orientationUtils?.resolveByClick()
|
||||||
|
|
||||||
|
binding.exoPlayContextId.startWindowFullscreen(this, true, true)?.let { fullPlayer ->
|
||||||
|
|
||||||
|
if (fullPlayer is MyGSYVideoPlayer) {
|
||||||
|
fullPlayer.onControlVisibilityChanged = { show ->
|
||||||
|
val visible = if (show) View.VISIBLE else View.GONE
|
||||||
|
binding.ivDownload.visibility = visible
|
||||||
|
binding.ivDelete.visibility = visible
|
||||||
|
binding.ivMute.visibility = visible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
private fun initRecyclerView() {
|
||||||
|
adapter = AlarmLogAdapter(alarmList) { item ->
|
||||||
|
currentAlarmItem = item
|
||||||
|
if (!item.video.isNullOrEmpty()) {
|
||||||
|
binding.exoPlayContextId.setUp(item.video, true, item.categoryName)
|
||||||
|
binding.exoPlayContextId.startPlayLogic()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, "该告警记录没有视频", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.alarmListRecyclerView.layoutManager = LinearLayoutManager(this)
|
||||||
|
binding.alarmListRecyclerView.adapter = adapter
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchAlarmList() {
|
||||||
|
val currentDeviceId = deviceId ?: return
|
||||||
|
|
||||||
|
Log.d("AlarmLogActivity", "=== 开始请求设备告警日志 ===")
|
||||||
|
Log.d("AlarmLogActivity", "请求参数 - deviceId: $currentDeviceId")
|
||||||
|
|
||||||
|
isLoading = true
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
Log.d("AlarmLogActivity", "正在发送网络请求...")
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getDeviceAlarmList(
|
||||||
|
deviceId = currentDeviceId,
|
||||||
|
pageNum = "1",
|
||||||
|
pageSize = "10"
|
||||||
|
)
|
||||||
|
|
||||||
|
Log.d("AlarmLogActivity", "请求完成")
|
||||||
|
Log.d("AlarmLogActivity", "总条数: ${response.total}, 当前页数据条数: ${response.rows.size}")
|
||||||
|
|
||||||
|
val newData = response.rows
|
||||||
|
originalAlarmList.clear()
|
||||||
|
originalAlarmList.addAll(newData)
|
||||||
|
filterAlarmListByDate(calendar)
|
||||||
|
currentAlarmItem = alarmList.firstOrNull()
|
||||||
|
Log.d("AlarmLogActivity", "已获取 ${newData.size} 条数据")
|
||||||
|
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("AlarmLogActivity", "请求异常: ${e.message}", e)
|
||||||
|
showAlarmListNetworkError()
|
||||||
|
} finally {
|
||||||
|
isLoading = false
|
||||||
|
Log.d("AlarmLogActivity", "请求结束")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateAlarmListState() {
|
||||||
|
if (alarmList.isEmpty()) {
|
||||||
|
binding.alarmListRecyclerView.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.alarmListRecyclerView.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAlarmListNetworkError() {
|
||||||
|
binding.alarmListRecyclerView.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun filterAlarmListByDate(selectedDate: Calendar) {
|
||||||
|
val dateFormat = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
|
||||||
|
val selectedDateStr = dateFormat.format(selectedDate.time)
|
||||||
|
|
||||||
|
alarmList.clear()
|
||||||
|
originalAlarmList.forEach { item ->
|
||||||
|
val itemDateStr = item.createTime.substring(0, 10)
|
||||||
|
if (itemDateStr == selectedDateStr) {
|
||||||
|
alarmList.add(item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
Log.d("AlarmLogActivity", "日期筛选完成,筛选后条数: ${alarmList.size}")
|
||||||
|
|
||||||
|
if (alarmList.isEmpty()) {
|
||||||
|
currentAlarmItem = null
|
||||||
|
} else {
|
||||||
|
currentAlarmItem = alarmList.firstOrNull()
|
||||||
|
}
|
||||||
|
updateAlarmListState()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDateDisplay() {
|
||||||
|
val month = calendar.get(Calendar.MONTH) + 1
|
||||||
|
val day = calendar.get(Calendar.DAY_OF_MONTH)
|
||||||
|
binding.tvDate.text = "${month}月${day}日"
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initListener() {
|
||||||
|
|
||||||
|
binding.expandImg.setOnClickListener {
|
||||||
|
showDatePicker()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivDownload.setOnClickListener {
|
||||||
|
|
||||||
|
// val item = currentAlarmItem
|
||||||
|
//
|
||||||
|
// if (item?.video.isNullOrEmpty()) {
|
||||||
|
// Toast.makeText(
|
||||||
|
// this,
|
||||||
|
// "没有可下载的视频",
|
||||||
|
// Toast.LENGTH_SHORT
|
||||||
|
// ).show()
|
||||||
|
// return@setOnClickListener
|
||||||
|
// }
|
||||||
|
|
||||||
|
showConfirmDialog(
|
||||||
|
getString(R.string.tip),
|
||||||
|
getString(R.string.download_alarm_video_confirm)
|
||||||
|
) {
|
||||||
|
|
||||||
|
//downloadVideo(item!!.video)
|
||||||
|
downloadVideo(
|
||||||
|
"https://media.w3.org/2010/05/sintel/trailer.mp4"
|
||||||
|
)
|
||||||
|
|
||||||
|
Toast.makeText(
|
||||||
|
this,
|
||||||
|
getString(R.string.download_start),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.ivDelete.setOnClickListener {
|
||||||
|
val item = currentAlarmItem
|
||||||
|
if (item == null) {
|
||||||
|
Toast.makeText(this, "没有可删除的告警记录", Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
showConfirmDialog(getString(R.string.tip), getString(R.string.delete_alarm_video_confirm)) {
|
||||||
|
val loadingDialog = LoadingDialog(this).setMessage("删除中...").apply { show() }
|
||||||
|
deleteAlarmItem(item.id, loadingDialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.ivMute.setOnClickListener {
|
||||||
|
isMute = !isMute
|
||||||
|
if (isMute) {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0)
|
||||||
|
binding.ivMute.setImageResource(
|
||||||
|
R.mipmap.mute
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
audioManager.setStreamVolume(AudioManager.STREAM_MUSIC, audioManager.getStreamMaxVolume(AudioManager.STREAM_MUSIC) / 2, 0)
|
||||||
|
binding.ivMute.setImageResource(
|
||||||
|
R.mipmap.un_mute
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showDatePicker() {
|
||||||
|
val timePicker = TimePickerBuilder(this, OnTimeSelectListener { date, _ ->
|
||||||
|
calendar.time = date
|
||||||
|
updateDateDisplay()
|
||||||
|
filterAlarmListByDate(calendar)
|
||||||
|
})
|
||||||
|
.setType(booleanArrayOf(true, true, true, false, false, false)) // 年月日
|
||||||
|
.setTitleText(getString(R.string.select_date))
|
||||||
|
.setSubmitColor(Color.parseColor("#09C2BD"))//确定按钮文字颜色
|
||||||
|
.setCancelColor(Color.parseColor("#09C2BD"))//取消按钮文字颜色
|
||||||
|
.setSubCalSize(18)//确定和取消文字大小
|
||||||
|
.setTextColorCenter(Color.parseColor("#09C2BD"))//选中颜色
|
||||||
|
.setLineSpacingMultiplier(2.5f)//行间距倍数
|
||||||
|
.setItemVisibleCount(5)//可见项数量
|
||||||
|
.setDate(calendar) // 设置默认选中日期为tvDate显示的日期
|
||||||
|
.build()
|
||||||
|
timePicker.show()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
binding.exoPlayContextId.onVideoPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.exoPlayContextId.onVideoResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showConfirmDialog(title: String, message: String, onConfirm: () -> Unit) {
|
||||||
|
val config = CustomDialogFragment.Config(
|
||||||
|
title = title,
|
||||||
|
message = message,
|
||||||
|
positiveText = getString(R.string.confirm),
|
||||||
|
negativeText = getString(R.string.cancel)
|
||||||
|
)
|
||||||
|
showDefenseDialog(config, onPositiveClick = { onConfirm() })
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun downloadVideo(url: String) {
|
||||||
|
|
||||||
|
val dir = File(
|
||||||
|
Environment.getExternalStoragePublicDirectory(
|
||||||
|
Environment.DIRECTORY_MOVIES
|
||||||
|
),
|
||||||
|
"AlarmVideo"
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!dir.exists()) {
|
||||||
|
dir.mkdirs()
|
||||||
|
}
|
||||||
|
|
||||||
|
val targetFile = File(
|
||||||
|
dir,
|
||||||
|
"${System.currentTimeMillis()}.mp4"
|
||||||
|
)
|
||||||
|
|
||||||
|
val request = DownloadRequest(
|
||||||
|
this,
|
||||||
|
url
|
||||||
|
)
|
||||||
|
.setDestinationUri(Uri.fromFile(targetFile))
|
||||||
|
.setNotificationTitle("${"视频名称"}:视频下载")
|
||||||
|
.registerListener(object : DownloadListener {
|
||||||
|
|
||||||
|
override fun onDownloadStart() {
|
||||||
|
Log.d("DOWNLOAD", "开始下载")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onProgressUpdate(percent: Int) {
|
||||||
|
Log.d("DOWNLOAD", "进度:$percent%")
|
||||||
|
}
|
||||||
|
override fun onDownloadComplete(uri: Uri) {
|
||||||
|
MediaScannerConnection.scanFile(
|
||||||
|
this@AlarmLogActivity,
|
||||||
|
arrayOf(targetFile.absolutePath),
|
||||||
|
arrayOf("video/mp4"),
|
||||||
|
null
|
||||||
|
)
|
||||||
|
|
||||||
|
runOnUiThread {
|
||||||
|
ToastUtils.showSuccess(
|
||||||
|
this@AlarmLogActivity,
|
||||||
|
"下载成功"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDownloadFailed(e: Throwable) {
|
||||||
|
runOnUiThread {
|
||||||
|
ToastUtils.showError(
|
||||||
|
this@AlarmLogActivity,
|
||||||
|
"下载失败:${e.message}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
request.startDownload()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteAlarmItem(id: String, loadingDialog: LoadingDialog) {
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().deleteMessage(id)
|
||||||
|
if (response.code == 200) {
|
||||||
|
Toast.makeText(this@AlarmLogActivity, getString(R.string.delete_success), Toast.LENGTH_SHORT).show()
|
||||||
|
originalAlarmList.removeAll { it.id == id }
|
||||||
|
alarmList.removeAll { it.id == id }
|
||||||
|
adapter?.notifyDataSetChanged()
|
||||||
|
currentAlarmItem = alarmList.firstOrNull()
|
||||||
|
if (alarmList.isEmpty()) {
|
||||||
|
showAlarmListNetworkError()
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@AlarmLogActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Toast.makeText(this@AlarmLogActivity, "删除失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||||
|
} finally {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
|
||||||
|
orientationUtils?.releaseListener()
|
||||||
|
binding.exoPlayContextId.release()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@@ -8,12 +8,12 @@ import java.util.Calendar
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.AutoModeActivityBinding
|
import com.ckkj.defense_device.databinding.AutoModeActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.DeviceUpdateEvent
|
import com.ckkj.defense_device.utils.DeviceUpdateEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.AutoModeNoticeDialog
|
import com.ckkj.defense_device.view.AutoModeNoticeDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -31,6 +31,7 @@ class AutoModeActivity : AppCompatActivity() {
|
|||||||
private var selectedStartMinute = 0
|
private var selectedStartMinute = 0
|
||||||
private var selectedEndHour = 10
|
private var selectedEndHour = 10
|
||||||
private var selectedEndMinute = 0
|
private var selectedEndMinute = 0
|
||||||
|
private var optionPassword: String? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -42,6 +43,8 @@ class AutoModeActivity : AppCompatActivity() {
|
|||||||
.titleBar(binding.topBar)
|
.titleBar(binding.topBar)
|
||||||
.init()
|
.init()
|
||||||
|
|
||||||
|
optionPassword = intent.getStringExtra("optionPassword")
|
||||||
|
|
||||||
initListener()
|
initListener()
|
||||||
|
|
||||||
loadCurrentSettings()
|
loadCurrentSettings()
|
||||||
@@ -173,11 +176,12 @@ class AutoModeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deviceBean = com.example.defenseapplication.bean.DeviceBean(
|
val deviceBean = com.ckkj.defense_device.bean.DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
workMode = selectedMode,
|
workMode = selectedMode,
|
||||||
startTime = startTime,
|
startTime = startTime,
|
||||||
endTime = endTime
|
endTime = endTime,
|
||||||
|
optionPassword = optionPassword
|
||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@@ -1,12 +1,11 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.TextView
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.databinding.DeviceInfoActivityBinding
|
import com.ckkj.defense_device.databinding.DeviceInfoActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -55,9 +54,9 @@ class DeviceInfoActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDeviceInfo(device: com.example.defenseapplication.bean.DeviceBean) {
|
private fun updateDeviceInfo(device: com.ckkj.defense_device.bean.DeviceBean) {
|
||||||
binding.tvDeviceModelValue.text = device.deviceNo.toString()
|
binding.tvDeviceModelValue.text = device.deviceNo?.toString()?: ""
|
||||||
binding.tvDeviceNoValue.text = device.deviceSn.toString()
|
binding.tvDeviceNoValue.text = device.deviceSn?.toString() ?: ""
|
||||||
binding.tvFwVersionValue.text = device.fwVer.toString()
|
binding.tvFwVersionValue.text = device.fwVer?.toString()?: ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
@@ -11,22 +11,22 @@ import androidx.appcompat.app.AppCompatActivity
|
|||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.LinkedUser
|
import com.ckkj.defense_device.adapter.LinkedUser
|
||||||
import com.example.defenseapplication.adapter.LinkedUserAdapter
|
import com.ckkj.defense_device.adapter.LinkedUserAdapter
|
||||||
import com.example.defenseapplication.bean.DeleteDeviceUserRequest
|
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
||||||
import com.example.defenseapplication.bean.DeviceUserBean
|
import com.ckkj.defense_device.bean.DeviceUserBean
|
||||||
import com.example.defenseapplication.bean.FamilyMembersBean
|
import com.ckkj.defense_device.bean.FamilyMembersBean
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.databinding.LinkedUserActivityBinding
|
import com.ckkj.defense_device.databinding.LinkedUserActivityBinding
|
||||||
import com.example.defenseapplication.personal.PasswordInputDialog
|
import com.ckkj.defense_device.personal.PasswordInputDialog
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.DeviceUserUpdateEvent
|
import com.ckkj.defense_device.utils.DeviceUserUpdateEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
|
import com.ckkj.defense_device.view.PullRefreshLayout
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import com.yanzhenjie.recyclerview.SwipeMenuItem
|
import com.yanzhenjie.recyclerview.SwipeMenuItem
|
||||||
import com.yanzhenjie.recyclerview.SwipeRecyclerView
|
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -96,9 +96,11 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
(binding.rvLinkedUser as RecyclerView).layoutManager = LinearLayoutManager(this)
|
(binding.rvLinkedUser as RecyclerView).layoutManager = LinearLayoutManager(this)
|
||||||
|
|
||||||
binding.swipeRefresh.setOnRefreshListener {
|
binding.swipeRefresh.setOnRefreshListener(object : PullRefreshLayout.OnRefreshListener {
|
||||||
|
override fun onRefresh() {
|
||||||
fetchUserList()
|
fetchUserList()
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
binding.rvLinkedUser.setSwipeMenuCreator { leftMenu, rightMenu, position ->
|
binding.rvLinkedUser.setSwipeMenuCreator { leftMenu, rightMenu, position ->
|
||||||
if (mode == MODE_SETTINGS) {
|
if (mode == MODE_SETTINGS) {
|
||||||
@@ -230,7 +232,6 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchUserList() {
|
private fun fetchUserList() {
|
||||||
binding.swipeRefresh.isRefreshing = true
|
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
try {
|
try {
|
||||||
var deviceId: String? = null
|
var deviceId: String? = null
|
||||||
@@ -239,7 +240,7 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
if (deviceId.isNullOrEmpty()) {
|
if (deviceId.isNullOrEmpty()) {
|
||||||
Toast.makeText(this@LinkedUserActivity, "设备 ID 为空", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LinkedUserActivity, "设备 ID 为空", Toast.LENGTH_SHORT).show()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.finishRefresh()
|
||||||
}
|
}
|
||||||
return@launch
|
return@launch
|
||||||
}
|
}
|
||||||
@@ -250,7 +251,7 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
RetrofitNetwork.getNetworkService().getFamilyMembers()
|
RetrofitNetwork.getNetworkService().getFamilyMembers()
|
||||||
}
|
}
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.finishRefresh()
|
||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
if (mode == MODE_SETTINGS) {
|
if (mode == MODE_SETTINGS) {
|
||||||
updateDeviceUserList(response.data as List<DeviceUserBean>)
|
updateDeviceUserList(response.data as List<DeviceUserBean>)
|
||||||
@@ -258,18 +259,32 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
updateFamilyMembersList(response.data as List<FamilyMembersBean>)
|
updateFamilyMembersList(response.data as List<FamilyMembersBean>)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
hide()
|
||||||
Toast.makeText(this@LinkedUserActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LinkedUserActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.finishRefresh()
|
||||||
Toast.makeText(this@LinkedUserActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
|
noNetwork()
|
||||||
|
Toast.makeText(this@LinkedUserActivity, R.string.network_request_failed, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun hide() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateDeviceUserList(deviceUserList: List<DeviceUserBean>) {
|
private fun updateDeviceUserList(deviceUserList: List<DeviceUserBean>) {
|
||||||
fullUserList.clear()
|
fullUserList.clear()
|
||||||
@@ -339,7 +354,7 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
binding.fabAdd.setOnClickListener {
|
binding.fabAdd.setOnClickListener {
|
||||||
if (checkUserLimit()) {
|
if (checkUserLimit()) {
|
||||||
val intent = Intent(this, com.example.defenseapplication.personal.InvitationCodeActivity::class.java)
|
val intent = Intent(this, com.ckkj.defense_device.personal.InvitationCodeActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,484 @@
|
|||||||
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.content.res.Configuration
|
||||||
|
import android.graphics.Color
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.adapter.AlarmLogHorizontalAdapter
|
||||||
|
import com.ckkj.defense_device.base.BaseActivity
|
||||||
|
import com.ckkj.defense_device.bean.DeviceAlarmBean
|
||||||
|
import com.ckkj.defense_device.databinding.LiveVideoActivityBinding
|
||||||
|
import com.ckkj.defense_device.utils.ActivityManager
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||||
|
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
||||||
|
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
|
import com.ckkj.defense_device.bean.VideoStreamInfo
|
||||||
|
import com.ckkj.defense_device.bean.VideoStreamRequest
|
||||||
|
import com.ckkj.defense_device.view.MyGSYVideoPlayerLive
|
||||||
|
|
||||||
|
class LiveVideoActivity : BaseActivity() {
|
||||||
|
private lateinit var binding: LiveVideoActivityBinding
|
||||||
|
|
||||||
|
private var isVoiceEnabled = false
|
||||||
|
private var isLightOn = false
|
||||||
|
private var isConsoleVisible = false
|
||||||
|
private var deviceId: String? = null
|
||||||
|
private var deviceNo: String? = null
|
||||||
|
private var alarmList: MutableList<DeviceAlarmBean> = mutableListOf()
|
||||||
|
private var alarmAdapter: AlarmLogHorizontalAdapter? = null
|
||||||
|
private var currentPage = 1
|
||||||
|
private var totalPage = 1
|
||||||
|
private val pageSize = 10
|
||||||
|
private var hasMore = true
|
||||||
|
private var isLoading = false
|
||||||
|
|
||||||
|
private var orientationUtils: OrientationUtils? = null
|
||||||
|
private val ptzHandler = Handler(Looper.getMainLooper())
|
||||||
|
private var currentPtzDirection: String? = null
|
||||||
|
private var streamUrl: String? = null
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
Log.d("onEnterFullscreen", "onCreate")
|
||||||
|
|
||||||
|
binding = LiveVideoActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
deviceId = intent.getStringExtra("device_id")
|
||||||
|
val deviceName = intent.getStringExtra("device_name")
|
||||||
|
deviceNo = intent.getStringExtra("deviceNo")
|
||||||
|
val light = intent.getStringExtra("light")
|
||||||
|
if (!deviceName.isNullOrEmpty()) {
|
||||||
|
binding.tvTitle.text = deviceName
|
||||||
|
}
|
||||||
|
|
||||||
|
initVideoPlayer()
|
||||||
|
initAlarmRecyclerView()
|
||||||
|
initListener()
|
||||||
|
fetchAlarmList()
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 这段代码重写了onConfigurationChanged方法,用于监听屏幕方向变化:
|
||||||
|
当屏幕旋转为横屏时,隐藏顶部栏(topBar)
|
||||||
|
当屏幕为竖屏时,显示顶部栏
|
||||||
|
目的是在横屏观看视频时提供更沉浸的全屏体验。
|
||||||
|
* */
|
||||||
|
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||||
|
super.onConfigurationChanged(newConfig)
|
||||||
|
if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||||
|
binding.topBar.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.topBar.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initVideoPlayer() {
|
||||||
|
orientationUtils = OrientationUtils(this, binding.exoPlayContextId)
|
||||||
|
orientationUtils?.isEnable = true
|
||||||
|
|
||||||
|
hidePlayerControls()
|
||||||
|
fetchStreamUrl()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchStreamUrl() {
|
||||||
|
val no = deviceNo ?: return
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().videoStart(VideoStreamRequest(no))
|
||||||
|
Log.d("直播流开始", "code=${response.code}, msg=${response.msg}")
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
//flv(http) 支持(IjkPlayer最好)
|
||||||
|
//hls(.m3u8) 支持(ExoPlayer/Ijk都支持)
|
||||||
|
//rtmp IjkPlayer支持,Exo默认不支持
|
||||||
|
//rtsp IjkPlayer支持
|
||||||
|
//webrtcGSYVideoPlayer 不支持
|
||||||
|
streamUrl = response.data.playUrls.flv
|
||||||
|
Log.d("直播流开始", "获取地址:$streamUrl")
|
||||||
|
setupVideoPlayer(streamUrl!!)
|
||||||
|
} else {
|
||||||
|
Log.e("直播流开始", response.msg)
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("直播流开始", "异常", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupVideoPlayer(videoUrl: String) {
|
||||||
|
GSYVideoOptionBuilder()
|
||||||
|
.setUrl(videoUrl)
|
||||||
|
.setCacheWithPlay(false)
|
||||||
|
.setRotateViewAuto(true)
|
||||||
|
.setLockLand(false)
|
||||||
|
.setShowFullAnimation(true)
|
||||||
|
.setNeedShowWifiTip(false)
|
||||||
|
.setEnlargeImageRes(R.drawable.full_size)
|
||||||
|
.setShrinkImageRes(R.drawable.full_screen)
|
||||||
|
.setVideoAllCallBack(object : GSYSampleCallBack() {
|
||||||
|
override fun onPrepared(url: String?, vararg objects: Any?) {
|
||||||
|
super.onPrepared(url, *objects)
|
||||||
|
orientationUtils?.isEnable = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
|
||||||
|
super.onQuitFullscreen(url, *objects)
|
||||||
|
orientationUtils?.backToProtVideo()
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
.build(binding.exoPlayContextId)
|
||||||
|
binding.exoPlayContextId.startPlayLogic()
|
||||||
|
binding.exoPlayContextId.fullscreenButton.setOnClickListener {
|
||||||
|
binding.exoPlayContextId.onPtzControlListener =
|
||||||
|
object : MyGSYVideoPlayerLive.OnPtzControlListener {
|
||||||
|
override fun onStartPtz(direction: String) {
|
||||||
|
val no = deviceNo ?: return
|
||||||
|
startPtz(deviceNo = no, direction = direction)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onStopPtz() {
|
||||||
|
stopCurrentPtz()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onShoot() {
|
||||||
|
deviceNo?.let { shoot(it) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
orientationUtils?.resolveByClick()
|
||||||
|
binding.exoPlayContextId.startWindowFullscreen(this, true, true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private fun hidePlayerControls() {
|
||||||
|
binding.exoPlayContextId.backButton.visibility = View.GONE
|
||||||
|
binding.exoPlayContextId.titleTextView.visibility = View.GONE
|
||||||
|
binding.exoPlayContextId.startButton.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.exoPlayContextId.findViewById<View>(
|
||||||
|
com.shuyu.gsyvideoplayer.R.id.current
|
||||||
|
)?.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.exoPlayContextId.findViewById<View>(
|
||||||
|
com.shuyu.gsyvideoplayer.R.id.total
|
||||||
|
)?.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.exoPlayContextId.findViewById<View>(
|
||||||
|
com.shuyu.gsyvideoplayer.R.id.progress
|
||||||
|
)?.visibility = View.INVISIBLE
|
||||||
|
|
||||||
|
binding.exoPlayContextId.findViewById<View>(
|
||||||
|
com.shuyu.gsyvideoplayer.R.id.start
|
||||||
|
)?.visibility = View.GONE
|
||||||
|
|
||||||
|
binding.exoPlayContextId.findViewById<View>(
|
||||||
|
com.shuyu.gsyvideoplayer.R.id.layout_bottom
|
||||||
|
)?.setBackgroundColor(Color.TRANSPARENT)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initAlarmRecyclerView() {
|
||||||
|
val layoutManager = LinearLayoutManager(this, LinearLayoutManager.HORIZONTAL, false)
|
||||||
|
binding.alarmLogRecyclerView.layoutManager = layoutManager
|
||||||
|
alarmAdapter = AlarmLogHorizontalAdapter(alarmList) { messageBean ->
|
||||||
|
val intent = Intent(this, AlarmLogActivity::class.java)
|
||||||
|
intent.putExtra("device_id", deviceId)
|
||||||
|
intent.putExtra("selected_id", messageBean.id)
|
||||||
|
intent.putExtra("video_url", messageBean.video)
|
||||||
|
intent.putExtra("create_time", messageBean.createTime)
|
||||||
|
intent.putExtra("from_live_video", true)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
binding.alarmLogRecyclerView.adapter = alarmAdapter
|
||||||
|
|
||||||
|
binding.alarmLogRecyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||||
|
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||||
|
super.onScrolled(recyclerView, dx, dy)
|
||||||
|
if (dx > 0 && !isLoading && hasMore) {
|
||||||
|
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
|
||||||
|
if (lastVisibleItemPosition == alarmList.size - 1) {
|
||||||
|
loadMoreAlarms()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun loadMoreAlarms() {
|
||||||
|
if (!hasMore || isLoading) return
|
||||||
|
currentPage++
|
||||||
|
if (currentPage > totalPage) {
|
||||||
|
hasMore = false
|
||||||
|
return
|
||||||
|
}
|
||||||
|
fetchAlarmList(currentPage)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initListener() {
|
||||||
|
binding.btnBack.setOnClickListener {
|
||||||
|
ActivityManager.finishExceptHome()
|
||||||
|
val intent = Intent(this, com.ckkj.defense_device.home.HomeActivity::class.java)
|
||||||
|
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||||
|
startActivity(intent)
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivMenu.setOnClickListener {
|
||||||
|
val intent = Intent(this, SettingsActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
binding.llLight.setOnClickListener {
|
||||||
|
isLightOn = !isLightOn
|
||||||
|
|
||||||
|
if (isLightOn) {
|
||||||
|
binding.ivLight.setImageResource(com.ckkj.defense_device.R.mipmap.light_on_open)
|
||||||
|
} else {
|
||||||
|
binding.ivLight.setImageResource(com.ckkj.defense_device.R.mipmap.light_on)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.xq.setOnClickListener {
|
||||||
|
val intent = Intent(this, AlarmLogActivity::class.java)
|
||||||
|
intent.putExtra("device_id", deviceId)
|
||||||
|
intent.putExtra("from_live_video", true)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.llRecord.setOnClickListener {
|
||||||
|
isConsoleVisible = !isConsoleVisible
|
||||||
|
if (isConsoleVisible) {
|
||||||
|
binding.llAlarmLog.visibility = View.GONE
|
||||||
|
binding.consoleBar.visibility = View.VISIBLE
|
||||||
|
binding.ivRecord.setImageResource(R.mipmap.copy_open)
|
||||||
|
} else {
|
||||||
|
binding.llAlarmLog.visibility = View.VISIBLE
|
||||||
|
binding.consoleBar.visibility = View.GONE
|
||||||
|
binding.ivRecord.setImageResource(R.mipmap.copy)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.llVoice.setOnClickListener {
|
||||||
|
isVoiceEnabled = !isVoiceEnabled
|
||||||
|
if (isVoiceEnabled) {
|
||||||
|
Glide.with(this)
|
||||||
|
.asGif()
|
||||||
|
.load(R.mipmap.voice_open)
|
||||||
|
.into(binding.ivVoice)
|
||||||
|
} else {
|
||||||
|
binding.ivVoice.setImageResource(R.mipmap.voice)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivUp.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(
|
||||||
|
view = v,
|
||||||
|
event = event,
|
||||||
|
direction = "up",
|
||||||
|
action = { deviceNo }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivDown.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(
|
||||||
|
view = v,
|
||||||
|
event = event,
|
||||||
|
direction = "down",
|
||||||
|
action = { deviceNo }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivLeft.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(
|
||||||
|
view = v,
|
||||||
|
event = event,
|
||||||
|
direction = "left",
|
||||||
|
action = { deviceNo }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.ivRight.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(
|
||||||
|
view = v,
|
||||||
|
event = event,
|
||||||
|
direction = "right",
|
||||||
|
action = { deviceNo }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePtzTouch(
|
||||||
|
view: View,
|
||||||
|
event: MotionEvent,
|
||||||
|
direction: String,
|
||||||
|
action: () -> String?
|
||||||
|
): Boolean {
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
view.isPressed = true
|
||||||
|
val deviceNo = action()
|
||||||
|
if (!deviceNo.isNullOrEmpty()) {
|
||||||
|
startPtz(deviceNo = deviceNo, direction = direction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
|
view.isPressed = false
|
||||||
|
stopCurrentPtz()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startPtz(deviceNo: String, direction: String) {
|
||||||
|
stopCurrentPtz()
|
||||||
|
|
||||||
|
currentPtzDirection = direction
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = when (direction) {
|
||||||
|
"up" -> RetrofitNetwork.getNetworkService().ptzUp(deviceNo)
|
||||||
|
"down" -> RetrofitNetwork.getNetworkService().ptzDown(deviceNo)
|
||||||
|
"left" -> RetrofitNetwork.getNetworkService().ptzLeft(deviceNo)
|
||||||
|
"right" -> RetrofitNetwork.getNetworkService().ptzRight(deviceNo)
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
Log.d("LV", "PTZ $direction start response: ${response?.code}")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("LV", "PTZ $direction start failed", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shoot(deviceNo: String) {
|
||||||
|
Log.d("LV", "btnCapture click, deviceNo=$deviceNo, duration=0")
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().ptzShoot(
|
||||||
|
deviceNo = deviceNo,
|
||||||
|
duration = "0"
|
||||||
|
)
|
||||||
|
Log.d("LV", "PTZ shoot response: code=${response.code}, msg=${response.msg}")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("LV", "PTZ shoot failed", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopCurrentPtz() {
|
||||||
|
val direction = currentPtzDirection ?: return
|
||||||
|
currentPtzDirection = null
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().ptzStop(deviceNo ?: return@launch)
|
||||||
|
Log.d("LV", "PTZ $direction stop response: ${response.code}")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("LV", "PTZ $direction stop failed", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchAlarmList(page: Int = 1) {
|
||||||
|
val currentDeviceId = deviceId ?: return
|
||||||
|
isLoading = true
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getDeviceAlarmList(
|
||||||
|
deviceId = currentDeviceId,
|
||||||
|
pageNum = page.toString(),
|
||||||
|
pageSize = pageSize.toString()
|
||||||
|
)
|
||||||
|
Log.d("LiveVideoActivity", "总条数: ${response.total}, 当前页数据条数: ${response.rows.size}")
|
||||||
|
val newData = response.rows
|
||||||
|
|
||||||
|
totalPage = if (response.total % pageSize == 0) {
|
||||||
|
response.total / pageSize
|
||||||
|
} else {
|
||||||
|
response.total / pageSize + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if (page == 1) {
|
||||||
|
alarmList.clear()
|
||||||
|
hasMore = totalPage > 1
|
||||||
|
}
|
||||||
|
alarmList.addAll(newData)
|
||||||
|
alarmAdapter?.notifyDataSetChanged()
|
||||||
|
updateAlarmListState()
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("LiveVideoActivity", "请求告警列表失败", e)
|
||||||
|
hasMore = false
|
||||||
|
showAlarmListNetworkError()
|
||||||
|
} finally {
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateAlarmListState() {
|
||||||
|
if (alarmList.isEmpty()) {
|
||||||
|
binding.alarmLogRecyclerView.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
|
} else {
|
||||||
|
binding.alarmLogRecyclerView.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun showAlarmListNetworkError() {
|
||||||
|
binding.alarmLogRecyclerView.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onResume() {
|
||||||
|
super.onResume()
|
||||||
|
binding.exoPlayContextId.onVideoResume()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onPause() {
|
||||||
|
super.onPause()
|
||||||
|
binding.exoPlayContextId.onVideoPause()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
ptzHandler.removeCallbacksAndMessages(null)
|
||||||
|
orientationUtils?.releaseListener()
|
||||||
|
binding.exoPlayContextId.release()
|
||||||
|
stopStream()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopStream() {
|
||||||
|
val no = deviceNo ?: return
|
||||||
|
GlobalScope.launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().videoStop(no)
|
||||||
|
Log.d("直播流停止", "videoStop response: code=${response.code}, msg=${response.msg}")
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("直播流停止", "停止推流异常", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,19 +1,19 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.base.BaseActivity
|
import com.ckkj.defense_device.base.BaseActivity
|
||||||
import com.example.defenseapplication.databinding.SettingsActivityBinding
|
import com.ckkj.defense_device.databinding.SettingsActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.example.defenseapplication.view.RecognitionModeDialog
|
import com.ckkj.defense_device.view.RecognitionModeDialog
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.personal.PasswordInputDialog
|
import com.ckkj.defense_device.personal.PasswordInputDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -27,6 +27,7 @@ class SettingsActivity : BaseActivity() {
|
|||||||
private var alertAudio: String? = null
|
private var alertAudio: String? = null
|
||||||
private var audioContent: String? = null
|
private var audioContent: String? = null
|
||||||
private var isPasswordVerified = false
|
private var isPasswordVerified = false
|
||||||
|
private var verifiedPassword: String? = null
|
||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
@@ -55,15 +56,15 @@ class SettingsActivity : BaseActivity() {
|
|||||||
if (isPasswordVerified) {
|
if (isPasswordVerified) {
|
||||||
val dialog = RecognitionModeDialog(this)
|
val dialog = RecognitionModeDialog(this)
|
||||||
dialog.setOnConfirmListener { mode ->
|
dialog.setOnConfirmListener { mode ->
|
||||||
updateRecognitionMode(mode)
|
updateRecognitionMode(mode, verifiedPassword)
|
||||||
}
|
}
|
||||||
dialog.show()
|
dialog.show()
|
||||||
} else {
|
} else {
|
||||||
showPasswordDialog {
|
showPasswordDialog { inputPassword ->
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
val dialog = RecognitionModeDialog(this)
|
val dialog = RecognitionModeDialog(this)
|
||||||
dialog.setOnConfirmListener { mode ->
|
dialog.setOnConfirmListener { mode ->
|
||||||
updateRecognitionMode(mode)
|
updateRecognitionMode(mode, inputPassword)
|
||||||
}
|
}
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
@@ -94,22 +95,24 @@ class SettingsActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
binding.itemWaterGunSetting.setOnClickListener {
|
binding.itemWaterGunSetting.setOnClickListener {
|
||||||
if (isPasswordVerified) {
|
if (isPasswordVerified) {
|
||||||
navigateToWaterGunSettings()
|
navigateToWaterGunSettings(verifiedPassword)
|
||||||
} else {
|
} else {
|
||||||
showPasswordDialog {
|
showPasswordDialog { inputPassword ->
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
navigateToWaterGunSettings()
|
navigateToWaterGunSettings(inputPassword)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binding.itemAutoMode.setOnClickListener {
|
binding.itemAutoMode.setOnClickListener {
|
||||||
if (isPasswordVerified) {
|
if (isPasswordVerified) {
|
||||||
val intent = Intent(this, AutoModeActivity::class.java)
|
val intent = Intent(this, AutoModeActivity::class.java)
|
||||||
|
intent.putExtra("optionPassword", verifiedPassword)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
} else {
|
} else {
|
||||||
showPasswordDialog {
|
showPasswordDialog { inputPassword ->
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
val intent = Intent(this, AutoModeActivity::class.java)
|
val intent = Intent(this, AutoModeActivity::class.java)
|
||||||
|
intent.putExtra("optionPassword", inputPassword)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -183,7 +186,7 @@ class SettingsActivity : BaseActivity() {
|
|||||||
binding.tvRelatedUsers.text = "$count 人"
|
binding.tvRelatedUsers.text = "$count 人"
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDeviceInfo(device: com.example.defenseapplication.bean.DeviceBean) {
|
private fun updateDeviceInfo(device: com.ckkj.defense_device.bean.DeviceBean) {
|
||||||
binding.tvDeviceName.text = device.deviceName ?: "未设置"
|
binding.tvDeviceName.text = device.deviceName ?: "未设置"
|
||||||
binding.tvWifiName.text = device.wifiName ?: "未设置"
|
binding.tvWifiName.text = device.wifiName ?: "未设置"
|
||||||
|
|
||||||
@@ -236,7 +239,7 @@ class SettingsActivity : BaseActivity() {
|
|||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deviceBean = com.example.defenseapplication.bean.DeviceBean(
|
val deviceBean = com.ckkj.defense_device.bean.DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
deviceName = name,
|
deviceName = name,
|
||||||
)
|
)
|
||||||
@@ -258,7 +261,7 @@ class SettingsActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateRecognitionMode(mode: String) {
|
private fun updateRecognitionMode(mode: String, optionPassword: String?) {
|
||||||
val deviceId = DeviceIdEvent.getDeviceId()
|
val deviceId = DeviceIdEvent.getDeviceId()
|
||||||
if (deviceId.isNullOrEmpty()) {
|
if (deviceId.isNullOrEmpty()) {
|
||||||
Toast.makeText(this, "设备ID为空", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, "设备ID为空", Toast.LENGTH_SHORT).show()
|
||||||
@@ -273,9 +276,10 @@ class SettingsActivity : BaseActivity() {
|
|||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deviceBean = com.example.defenseapplication.bean.DeviceBean(
|
val deviceBean = com.ckkj.defense_device.bean.DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
patternPerception = patternPerception,
|
patternPerception = patternPerception,
|
||||||
|
optionPassword = optionPassword
|
||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@@ -305,13 +309,13 @@ class SettingsActivity : BaseActivity() {
|
|||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deleteBean = com.example.defenseapplication.bean.DeleteBean()
|
val deleteBean = com.ckkj.defense_device.bean.DeleteBean()
|
||||||
deleteBean.deviceId = deviceId
|
deleteBean.deviceId = deviceId
|
||||||
val response = RetrofitNetwork.getNetworkService().deleteDevice(deleteBean)
|
val response = RetrofitNetwork.getNetworkService().deleteDevice(deleteBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@SettingsActivity, "解绑成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@SettingsActivity, "解绑成功", Toast.LENGTH_SHORT).show()
|
||||||
val intent = Intent(this@SettingsActivity, com.example.defenseapplication.home.HomeActivity::class.java)
|
val intent = Intent(this@SettingsActivity, com.ckkj.defense_device.home.HomeActivity::class.java)
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_NEW_TASK
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
@@ -328,7 +332,7 @@ class SettingsActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPasswordDialog(onVerified: () -> Unit) {
|
private fun showPasswordDialog(onVerified: (String) -> Unit) {
|
||||||
passwordDialog = PasswordInputDialog(this).apply {
|
passwordDialog = PasswordInputDialog(this).apply {
|
||||||
setOnConfirmListener { inputPassword ->
|
setOnConfirmListener { inputPassword ->
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
@@ -338,7 +342,8 @@ class SettingsActivity : BaseActivity() {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
dismiss()
|
dismiss()
|
||||||
onVerified()
|
verifiedPassword = inputPassword
|
||||||
|
onVerified(inputPassword)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
this@SettingsActivity,
|
this@SettingsActivity,
|
||||||
@@ -365,8 +370,9 @@ class SettingsActivity : BaseActivity() {
|
|||||||
passwordDialog.show()
|
passwordDialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun navigateToWaterGunSettings() {
|
private fun navigateToWaterGunSettings(optionPassword: String? = null) {
|
||||||
val intent = Intent(this, WaterGunSettingsActivity::class.java)
|
val intent = Intent(this, WaterGunSettingsActivity::class.java)
|
||||||
|
intent.putExtra("optionPassword", optionPassword)
|
||||||
val deviceId = DeviceIdEvent.getDeviceId()
|
val deviceId = DeviceIdEvent.getDeviceId()
|
||||||
if (!deviceId.isNullOrEmpty()) {
|
if (!deviceId.isNullOrEmpty()) {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
@@ -1,17 +1,17 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.animation.ObjectAnimator
|
import android.animation.ObjectAnimator
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.ImageView
|
import android.widget.ImageView
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.databinding.StrikePositionActivityBinding
|
import com.ckkj.defense_device.databinding.StrikePositionActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.CustomDialogFragment
|
import com.ckkj.defense_device.view.CustomDialogFragment
|
||||||
import com.example.defenseapplication.view.showDefenseDialog
|
import com.ckkj.defense_device.view.showDefenseDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -45,7 +45,7 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private var selectedZone: Zone = Zone.CHEST
|
private var selectedZone: Zone = Zone.CHEST
|
||||||
|
|
||||||
// Touch tracking for ImageView (captured in onTouch, used in ACTION_UP for click detection)
|
// ImageView 的触控追踪(在 onTouch 中捕获,ACTION_UP 用于点击检测)
|
||||||
private var lastTouchX = 0f
|
private var lastTouchX = 0f
|
||||||
private var lastTouchY = 0f
|
private var lastTouchY = 0f
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
binding.ivBack.setOnClickListener { finish() }
|
binding.ivBack.setOnClickListener { finish() }
|
||||||
binding.btnSubmit.setOnClickListener { showConfirmDialog() }
|
binding.btnSubmit.setOnClickListener { showConfirmDialog() }
|
||||||
|
|
||||||
// Use OnTouchListener to track touch coordinates
|
// 使用 OnTouchListen 来跟踪触摸坐标
|
||||||
binding.ivHumanBody.setOnTouchListener { _, event ->
|
binding.ivHumanBody.setOnTouchListener { _, event ->
|
||||||
lastTouchX = event.x
|
lastTouchX = event.x
|
||||||
lastTouchY = event.y
|
lastTouchY = event.y
|
||||||
@@ -77,7 +77,7 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
// OnClick fires on ACTION_UP; coordinates captured from lastTouchX/Y
|
// OnClick 对ACTION_UP开火;坐标来自lastTouchXY
|
||||||
binding.ivHumanBody.setOnClickListener {
|
binding.ivHumanBody.setOnClickListener {
|
||||||
val imageView = it as ImageView
|
val imageView = it as ImageView
|
||||||
val (nx, ny) = resolveTapLocation(lastTouchX, lastTouchY, imageView)
|
val (nx, ny) = resolveTapLocation(lastTouchX, lastTouchY, imageView)
|
||||||
@@ -100,10 +100,12 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Converts a screen coordinate (from onTouch) into a normalised [0..1] offset
|
* 这段代码将触摸坐标转换为图片内部的归一化位置:
|
||||||
* inside the drawable, accounting for:
|
*
|
||||||
* - ImageView scaling (scaleType="fitCenter" adds letterboxing)
|
* 1. 计算图片等比缩放后的实际尺寸
|
||||||
* - Letterbox / pillarbox margins when image aspect ≠ view aspect
|
* 2. 计算letterbox/pillarbox的偏移量
|
||||||
|
* 3. 将触摸点限制在图片有效区域内
|
||||||
|
* 4. 返回相对于图片的归一化坐标(0-1范围)
|
||||||
*/
|
*/
|
||||||
private fun resolveTapLocation(rawX: Float, rawY: Float, imageView: ImageView): Pair<Float, Float> {
|
private fun resolveTapLocation(rawX: Float, rawY: Float, imageView: ImageView): Pair<Float, Float> {
|
||||||
val drawable = imageView.drawable ?: return Pair(0f, 0f)
|
val drawable = imageView.drawable ?: return Pair(0f, 0f)
|
||||||
@@ -114,22 +116,22 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
val intrinsicWidth = drawable.intrinsicWidth.toFloat()
|
val intrinsicWidth = drawable.intrinsicWidth.toFloat()
|
||||||
val intrinsicHeight = drawable.intrinsicHeight.toFloat()
|
val intrinsicHeight = drawable.intrinsicHeight.toFloat()
|
||||||
|
|
||||||
// scale: the uniform factor the image is scaled by to fit the view
|
// 比例:图像被缩放以适应视图的均匀因子
|
||||||
val scale = min(ivWidth / intrinsicWidth, ivHeight / intrinsicHeight)
|
val scale = min(ivWidth / intrinsicWidth, ivHeight / intrinsicHeight)
|
||||||
|
|
||||||
// Physical pixel size of the drawable after scaling
|
// 缩放后绘制的物理像素大小
|
||||||
val drawnW = intrinsicWidth * scale
|
val drawnW = intrinsicWidth * scale
|
||||||
val drawnH = intrinsicHeight * scale
|
val drawnH = intrinsicHeight * scale
|
||||||
|
|
||||||
// Letterbox offsets (top / left) when aspect ratios differ
|
// 当宽高比不同时,信箱偏移(左上角)
|
||||||
val drawableLeft = (ivWidth - drawnW) / 2f
|
val drawableLeft = (ivWidth - drawnW) / 2f
|
||||||
val drawableTop = (ivHeight - drawnH) / 2f
|
val drawableTop = (ivHeight - drawnH) / 2f
|
||||||
|
|
||||||
// Clamp touch to the actual drawable area
|
// 夹紧触地接触实际可绘制区域
|
||||||
val clampedX = max(drawableLeft, min(rawX, drawableLeft + drawnW))
|
val clampedX = max(drawableLeft, min(rawX, drawableLeft + drawnW))
|
||||||
val clampedY = max(drawableTop, min(rawY, drawableTop + drawnH))
|
val clampedY = max(drawableTop, min(rawY, drawableTop + drawnH))
|
||||||
|
|
||||||
// Normalised offset [0..1] within the drawable
|
// 可绘制物内的归一化偏移 [0..1]
|
||||||
val normalizedX = (clampedX - drawableLeft) / drawnW
|
val normalizedX = (clampedX - drawableLeft) / drawnW
|
||||||
val normalizedY = (clampedY - drawableTop) / drawnH
|
val normalizedY = (clampedY - drawableTop) / drawnH
|
||||||
|
|
||||||
@@ -137,14 +139,11 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Zones are divided by:
|
* 这段代码根据归一化坐标确定触摸区域:
|
||||||
* - Horizontal boundary at ny = 0.5 → top = HEAD, bottom = shoulders
|
|
||||||
* - Vertical boundary 1 at nx = 1/3 → left = LEFT_SHOULDER
|
|
||||||
* - Vertical boundary 2 at nx = 2/3 → right = RIGHT_SHOULDER, middle = CHEST
|
|
||||||
*
|
*
|
||||||
* If the touch falls within ±tolerance of any boundary line, the nearest
|
* 1. 将图片分为头部、左肩、胸部、右肩四个区域
|
||||||
* zone centre (Euclidean distance in normalised space) is used to avoid
|
* 2. 边界附近±0.04范围内,使用最近区域中心避免误判
|
||||||
* arbitrary assignments at boundary pixels.
|
* 3. 上半部分为头部,下半部分按1/3和2/3垂直线划分
|
||||||
*/
|
*/
|
||||||
private fun zoneForLocation(nx: Float, ny: Float): Zone {
|
private fun zoneForLocation(nx: Float, ny: Float): Zone {
|
||||||
val hBoundary = 0.5f
|
val hBoundary = 0.5f
|
||||||
@@ -168,7 +167,14 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the Zone whose normalised centre is closest (Euclidean) to (nx, ny). */
|
/**
|
||||||
|
* 这段代码找到距离触摸点最近的区域:
|
||||||
|
*
|
||||||
|
* 1. 遍历所有Zone,计算与触摸点的欧氏距离平方
|
||||||
|
* 2. 返回距离最小的Zone作为结果
|
||||||
|
* 3. 若无匹配则默认返回CHEST
|
||||||
|
* */
|
||||||
|
|
||||||
private fun nearestZone(nx: Float, ny: Float): Zone {
|
private fun nearestZone(nx: Float, ny: Float): Zone {
|
||||||
return Zone.values().minByOrNull { zone ->
|
return Zone.values().minByOrNull { zone ->
|
||||||
val dx = nx - zone.normalizedX
|
val dx = nx - zone.normalizedX
|
||||||
@@ -178,12 +184,12 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Positions the marker (ivStrikeMarker) at the zone's centre, clamped so the
|
这段代码更新标记位置到区域中心:
|
||||||
* marker never goes out of the ivHumanBody bounds.
|
|
||||||
*
|
1. 根据Zone的归一化坐标计算目标位置
|
||||||
* Because the marker is a child of ivHumanBody and starts at its center
|
2. 限制标记不超出图片边界(Y仅限制上限)
|
||||||
* (layout_gravity="center"), we compute the offset from that center point
|
3. 相对于ImageView中心计算偏移量并应用
|
||||||
* and apply it via translationX/Y so the marker's layout bounds stay intact.
|
4. 支持动画或即时移动两种方式
|
||||||
*/
|
*/
|
||||||
private fun updateMarkerPosition(zone: Zone, animated: Boolean) {
|
private fun updateMarkerPosition(zone: Zone, animated: Boolean) {
|
||||||
if (humanBodyWidth <= 0 || humanBodyHeight <= 0) return
|
if (humanBodyWidth <= 0 || humanBodyHeight <= 0) return
|
||||||
@@ -198,9 +204,7 @@ class StrikePositionActivity : AppCompatActivity() {
|
|||||||
val rawX = humanBodyWidth * zone.normalizedX
|
val rawX = humanBodyWidth * zone.normalizedX
|
||||||
val rawY = humanBodyHeight * zone.normalizedY
|
val rawY = humanBodyHeight * zone.normalizedY
|
||||||
|
|
||||||
// Clamp X so the marker never extends beyond the drawable edges.
|
//用X夹住,使标记永远不会超出可绘制的边缘。Y钳只有一个上界——在归一化Y=0处的HEAD可以一直达到顶端(平移Y可以为负)。
|
||||||
// Y clamp only has an upper bound — HEAD at normalizedY=0 is allowed to go
|
|
||||||
// all the way to the top (translationY can be negative).
|
|
||||||
val clampedX = min(max(rawX, halfMarkerW), humanBodyWidth - halfMarkerW)
|
val clampedX = min(max(rawX, halfMarkerW), humanBodyWidth - halfMarkerW)
|
||||||
val clampedY = min(rawY, humanBodyHeight - halfMarkerH)
|
val clampedY = min(rawY, humanBodyHeight - halfMarkerH)
|
||||||
|
|
||||||
@@ -1,20 +1,20 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.DeleteDeviceUserRequest
|
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
||||||
import com.example.defenseapplication.bean.ObtainInviterInformationRequest
|
import com.ckkj.defense_device.bean.ObtainInviterInformationRequest
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.UpdateFamilyUserRequest
|
||||||
import com.example.defenseapplication.personal.PasswordInputDialog
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.personal.PasswordInputDialog
|
||||||
import com.example.defenseapplication.utils.DeviceUserUpdateEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.databinding.UserDetailsActivityBinding
|
import com.ckkj.defense_device.utils.DeviceUserUpdateEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.databinding.UserDetailsActivityBinding
|
||||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
@@ -27,6 +27,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
private var userId: String = ""
|
private var userId: String = ""
|
||||||
private var isPasswordVerified: Boolean = false
|
private var isPasswordVerified: Boolean = false
|
||||||
private lateinit var passwordDialog: PasswordInputDialog
|
private lateinit var passwordDialog: PasswordInputDialog
|
||||||
|
private var optionPassword: String = ""
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -73,8 +74,8 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateUI(data: com.example.defenseapplication.bean.ObtainInviterInformationBean) {
|
private fun updateUI(data: com.ckkj.defense_device.bean.ObtainInviterInformationBean) {
|
||||||
binding.tvContactName.text = data.nickName ?: "未知用户"
|
binding.tvContactName.text = data.nickName ?: ""
|
||||||
binding.tvPhone.text = data.phonenumber ?: ""
|
binding.tvPhone.text = data.phonenumber ?: ""
|
||||||
binding.tvIdCard.text = data.idCard ?: ""
|
binding.tvIdCard.text = data.idCard ?: ""
|
||||||
binding.tvMacAddress.text = data.mac ?: ""
|
binding.tvMacAddress.text = data.mac ?: ""
|
||||||
@@ -88,10 +89,12 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
binding.swUserStatus.setOnCheckedChangeListener { _, isChecked ->
|
binding.swUserStatus.setOnCheckedChangeListener { _, isChecked ->
|
||||||
if (!isPasswordVerified) {
|
if (!isPasswordVerified) {
|
||||||
binding.swUserStatus.isChecked = !isChecked
|
binding.swUserStatus.isChecked = !isChecked
|
||||||
showPasswordDialog {
|
showPasswordDialog(isChecked) {
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
binding.swUserStatus.isChecked = isChecked
|
binding.swUserStatus.isChecked = isChecked
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
updateFamilyUserStatus(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -100,7 +103,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPasswordDialog(onVerified: () -> Unit) {
|
private fun showPasswordDialog(status: Boolean, onVerified: () -> Unit) {
|
||||||
passwordDialog = PasswordInputDialog(this).apply {
|
passwordDialog = PasswordInputDialog(this).apply {
|
||||||
setOnConfirmListener { inputPassword ->
|
setOnConfirmListener { inputPassword ->
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
@@ -110,6 +113,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
dismiss()
|
dismiss()
|
||||||
|
updateFamilyUserStatus(status, inputPassword)
|
||||||
onVerified()
|
onVerified()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@@ -136,6 +140,48 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun updateFamilyUserStatus(status: Boolean) {
|
||||||
|
updateFamilyUserStatus(status, optionPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateFamilyUserStatus(status: Boolean, password: String) {
|
||||||
|
if (userId.isEmpty()) {
|
||||||
|
Toast.makeText(this, "用户ID为空", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.isNotEmpty()) {
|
||||||
|
optionPassword = password
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val request = UpdateFamilyUserRequest(
|
||||||
|
id = userId,
|
||||||
|
optionPassword = optionPassword,
|
||||||
|
optionStatus = "status",
|
||||||
|
status = if (status) "1" else "0"
|
||||||
|
)
|
||||||
|
val response = RetrofitNetwork.getNetworkService().updateFamilyUser(request)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, "状态修改成功", Toast.LENGTH_SHORT).show()
|
||||||
|
DeviceUserUpdateEvent.notifyUpdate()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, response.msg ?: "状态修改失败", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.swUserStatus.isChecked = !status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.swUserStatus.isChecked = !status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showDeleteDialog() {
|
private fun showDeleteDialog() {
|
||||||
val dialog = CustomDialogFragmentText()
|
val dialog = CustomDialogFragmentText()
|
||||||
dialog.setTitle(getString(R.string.tip))
|
dialog.setTitle(getString(R.string.tip))
|
||||||
@@ -147,7 +193,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
if (isPasswordVerified) {
|
if (isPasswordVerified) {
|
||||||
deleteDeviceUser()
|
deleteDeviceUser()
|
||||||
} else {
|
} else {
|
||||||
showPasswordDialog {
|
showPasswordDialog(false) {
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
deleteDeviceUser()
|
deleteDeviceUser()
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,15 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.databinding.VoiceSettingsActivityBinding
|
import com.ckkj.defense_device.databinding.VoiceSettingsActivityBinding
|
||||||
import com.example.defenseapplication.utils.ApiService
|
import com.ckkj.defense_device.utils.ApiService
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -79,8 +79,7 @@ class VoiceSettingsActivity : AppCompatActivity() {
|
|||||||
private fun updateDeviceAlertAudio() {
|
private fun updateDeviceAlertAudio() {
|
||||||
deviceId?.let { id ->
|
deviceId?.let { id ->
|
||||||
val newAlertAudio = if (binding.swWarningVoice.isChecked) "1" else "0"
|
val newAlertAudio = if (binding.swWarningVoice.isChecked) "1" else "0"
|
||||||
// 只有状态发生变化时才请求
|
// 点击返回时总是触发网络请求
|
||||||
if (newAlertAudio != originalAlertAudio) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deviceBean = DeviceBean(id = id, alertAudio = newAlertAudio)
|
val deviceBean = DeviceBean(id = id, alertAudio = newAlertAudio)
|
||||||
@@ -89,20 +88,23 @@ class VoiceSettingsActivity : AppCompatActivity() {
|
|||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, "修改成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, "修改成功", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
|
// 仅在状态实际发生变化时才显示错误提示
|
||||||
|
if (newAlertAudio != originalAlertAudio) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
// 仅在状态实际发生变化时才显示失败提示
|
||||||
|
if (newAlertAudio != originalAlertAudio) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, "修改失败", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, "修改失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@@ -6,10 +6,10 @@ import android.os.Bundle
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.widget.doAfterTextChanged
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.databinding.WarningVoiceContentActivityBinding
|
import com.ckkj.defense_device.databinding.WarningVoiceContentActivityBinding
|
||||||
import com.example.defenseapplication.utils.ApiService
|
import com.ckkj.defense_device.utils.ApiService
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,16 +1,15 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.base.BaseActivity
|
||||||
import com.example.defenseapplication.base.BaseActivity
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.databinding.WaterGunSettingsActivityBinding
|
||||||
import com.example.defenseapplication.databinding.WaterGunSettingsActivityBinding
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.view.ContainerSelectDialog
|
||||||
import com.example.defenseapplication.view.ContainerSelectDialog
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -25,6 +24,7 @@ class WaterGunSettingsActivity : BaseActivity() {
|
|||||||
private var currentStrikeRange: String = "7"
|
private var currentStrikeRange: String = "7"
|
||||||
private var currentStrikeInterval: String = "3"
|
private var currentStrikeInterval: String = "3"
|
||||||
private var currentContainer: String = "容器4"
|
private var currentContainer: String = "容器4"
|
||||||
|
private var optionPassword: String? = null
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -42,6 +42,7 @@ class WaterGunSettingsActivity : BaseActivity() {
|
|||||||
currentStrikeRange = intent.getStringExtra("strikeRange") ?: "7"
|
currentStrikeRange = intent.getStringExtra("strikeRange") ?: "7"
|
||||||
currentStrikeInterval = intent.getStringExtra("strikeInterval") ?: "3"
|
currentStrikeInterval = intent.getStringExtra("strikeInterval") ?: "3"
|
||||||
currentContainer = intent.getStringExtra("container") ?: "容器4"
|
currentContainer = intent.getStringExtra("container") ?: "容器4"
|
||||||
|
optionPassword = intent.getStringExtra("optionPassword")
|
||||||
|
|
||||||
// 显示初始值
|
// 显示初始值
|
||||||
binding.tvDistance.text = "${currentStrikeRange}m"
|
binding.tvDistance.text = "${currentStrikeRange}m"
|
||||||
@@ -101,7 +102,8 @@ class WaterGunSettingsActivity : BaseActivity() {
|
|||||||
try {
|
try {
|
||||||
val deviceBean = DeviceBean(
|
val deviceBean = DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
strikeRange = distance
|
strikeRange = distance,
|
||||||
|
optionPassword = optionPassword
|
||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@@ -132,7 +134,8 @@ class WaterGunSettingsActivity : BaseActivity() {
|
|||||||
try {
|
try {
|
||||||
val deviceBean = DeviceBean(
|
val deviceBean = DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
strikeInterval = interval
|
strikeInterval = interval,
|
||||||
|
optionPassword = optionPassword
|
||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@@ -163,7 +166,8 @@ class WaterGunSettingsActivity : BaseActivity() {
|
|||||||
try {
|
try {
|
||||||
val deviceBean = DeviceBean(
|
val deviceBean = DeviceBean(
|
||||||
id = deviceId,
|
id = deviceId,
|
||||||
container = container
|
container = container,
|
||||||
|
optionPassword = optionPassword
|
||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.liveVideo
|
package com.ckkj.defense_device.liveVideo
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.BroadcastReceiver
|
import android.content.BroadcastReceiver
|
||||||
@@ -18,13 +18,13 @@ import android.widget.PopupWindow
|
|||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.adapter.WifiListAdapter
|
import com.ckkj.defense_device.adapter.WifiListAdapter
|
||||||
import com.example.defenseapplication.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.example.defenseapplication.databinding.DialogWifiListBinding
|
import com.ckkj.defense_device.databinding.DialogWifiListBinding
|
||||||
import com.example.defenseapplication.databinding.WifiManagementActivityBinding
|
import com.ckkj.defense_device.databinding.WifiManagementActivityBinding
|
||||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import com.ckkj.defense_device.databinding.FaceLoginActivityBinding
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.databinding.FaceLoginActivityBinding
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
//人脸识别
|
//人脸识别
|
||||||
class FaceLoginActivity : AppCompatActivity() {
|
class FaceLoginActivity : AppCompatActivity() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
@@ -13,8 +13,8 @@ import androidx.camera.core.Preview
|
|||||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||||
import androidx.core.app.ActivityCompat
|
import androidx.core.app.ActivityCompat
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.example.defenseapplication.databinding.FaceVerificationActivityBinding
|
import com.ckkj.defense_device.databinding.FaceVerificationActivityBinding
|
||||||
import com.example.defenseapplication.view.FaceAnalyzer
|
import com.ckkj.defense_device.view.FaceAnalyzer
|
||||||
import com.google.mlkit.vision.face.FaceDetection
|
import com.google.mlkit.vision.face.FaceDetection
|
||||||
import com.google.mlkit.vision.face.FaceDetectorOptions
|
import com.google.mlkit.vision.face.FaceDetectorOptions
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
@@ -7,9 +7,10 @@ import android.os.CountDownTimer
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import bean.ForgotRequest
|
import bean.ForgotRequest
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.ForgetPasswordActivityBinding
|
import com.ckkj.defense_device.databinding.ForgetPasswordActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.google.firebase.crashlytics.buildtools.reloc.org.apache.http.util.TextUtils
|
import com.google.firebase.crashlytics.buildtools.reloc.org.apache.http.util.TextUtils
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -20,6 +21,7 @@ import java.util.regex.Pattern
|
|||||||
|
|
||||||
class ForgetPasswordActivity : AppCompatActivity() {
|
class ForgetPasswordActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: ForgetPasswordActivityBinding
|
private lateinit var binding: ForgetPasswordActivityBinding
|
||||||
|
private var isLoading = false
|
||||||
private var countDownTimer: CountDownTimer? = null
|
private var countDownTimer: CountDownTimer? = null
|
||||||
private var isSendingCode = false
|
private var isSendingCode = false
|
||||||
|
|
||||||
@@ -55,17 +57,19 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
if (isPhoneNumberValid(phoneNumber)) {
|
if (isPhoneNumberValid(phoneNumber)) {
|
||||||
sendVerificationCode(phoneNumber)
|
sendVerificationCode(phoneNumber)
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, "请输入有效的11位手机号", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.phone_tip), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this, "请稍后再试", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.please_try_later), Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.btnNext.setOnClickListener {
|
binding.btnNext.setOnClickListener {
|
||||||
|
if (!isLoading) {
|
||||||
performResetPassword()
|
performResetPassword()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isPhoneNumberValid(phone: String): Boolean {
|
private fun isPhoneNumberValid(phone: String): Boolean {
|
||||||
if (TextUtils.isEmpty(phone)) return false
|
if (TextUtils.isEmpty(phone)) return false
|
||||||
@@ -82,7 +86,7 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
val response = RetrofitNetwork.getNetworkService().getCode(phoneNumber)
|
val response = RetrofitNetwork.getNetworkService().getCode(phoneNumber)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@ForgetPasswordActivity, "验证码已发送", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, getString(R.string.code_sent_to), Toast.LENGTH_SHORT).show()
|
||||||
startCountDown()
|
startCountDown()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this@ForgetPasswordActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
@@ -104,11 +108,10 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
* 开始验证码按钮倒计时
|
* 开始验证码按钮倒计时
|
||||||
*/
|
*/
|
||||||
private fun startCountDown() {
|
private fun startCountDown() {
|
||||||
|
binding.sendCodeBtn.isEnabled = false
|
||||||
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
|
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
val secondsRemaining = (millisUntilFinished / 1000).toInt()
|
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
||||||
binding.sendCodeBtn.text = "${secondsRemaining}秒后重试"
|
|
||||||
binding.sendCodeBtn.isEnabled = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
@@ -123,7 +126,7 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
private fun resetSendButton() {
|
private fun resetSendButton() {
|
||||||
countDownTimer?.cancel()
|
countDownTimer?.cancel()
|
||||||
countDownTimer = null
|
countDownTimer = null
|
||||||
binding.sendCodeBtn.text = "发送验证码"
|
binding.sendCodeBtn.text = getString(R.string.resend_code)
|
||||||
binding.sendCodeBtn.isEnabled = true
|
binding.sendCodeBtn.isEnabled = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,34 +140,38 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
val confirmPassword = binding.etInviteCode.text.toString().trim()
|
val confirmPassword = binding.etInviteCode.text.toString().trim()
|
||||||
|
|
||||||
if (!isPhoneNumberValid(phoneNumber)) {
|
if (!isPhoneNumberValid(phoneNumber)) {
|
||||||
Toast.makeText(this, "手机号格式不正确", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.invalid_phone), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(smsCode)) {
|
if (TextUtils.isEmpty(smsCode)) {
|
||||||
Toast.makeText(this, "请输入验证码", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.hint_code_zh), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (TextUtils.isEmpty(newPassword) || TextUtils.isEmpty(confirmPassword)) {
|
if (TextUtils.isEmpty(newPassword) || TextUtils.isEmpty(confirmPassword)) {
|
||||||
Toast.makeText(this, "密码不能为空", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.password_cannot_empty), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (newPassword.length < MIN_PASSWORD_LENGTH || newPassword.length > MAX_PASSWORD_LENGTH) {
|
if (newPassword.length < MIN_PASSWORD_LENGTH || newPassword.length > MAX_PASSWORD_LENGTH) {
|
||||||
Toast.makeText(this, "密码长度需为${MIN_PASSWORD_LENGTH}-${MAX_PASSWORD_LENGTH}位", Toast.LENGTH_SHORT).show()
|
val tip = getString(R.string.pwd_length_tip, MIN_PASSWORD_LENGTH, MAX_PASSWORD_LENGTH)
|
||||||
|
Toast.makeText(this, tip, Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (!newPassword.matches(Regex(".*[A-Za-z].*")) || !newPassword.matches(Regex(".*[0-9].*"))) {
|
if (!newPassword.matches(Regex(".*[A-Za-z].*")) || !newPassword.matches(Regex(".*[0-9].*"))) {
|
||||||
Toast.makeText(this, "密码需同时包含字母和数字", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.password_letter_digit), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if (newPassword != confirmPassword) {
|
if (newPassword != confirmPassword) {
|
||||||
Toast.makeText(this, "两次输入的密码不一致", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, getString(R.string.password_mismatch), Toast.LENGTH_SHORT).show()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLoading = true
|
||||||
binding.btnNext.isEnabled = false
|
binding.btnNext.isEnabled = false
|
||||||
binding.btnNext.text = "重置中..."
|
val loadingDialog = LoadingDialog(this)
|
||||||
|
.setMessage(getString(R.string.resetting))
|
||||||
|
.apply { show() }
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -175,8 +182,9 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().forgotPassword(forgotRequest)
|
val response = RetrofitNetwork.getNetworkService().forgotPassword(forgotRequest)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = "确定"
|
|
||||||
|
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@ForgetPasswordActivity, R.string.reset_success, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, R.string.reset_success, Toast.LENGTH_SHORT).show()
|
||||||
@@ -187,8 +195,9 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = "确定"
|
|
||||||
Toast.makeText(this@ForgetPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,21 +1,23 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout
|
import androidx.constraintlayout.widget.ConstraintLayout
|
||||||
import androidx.constraintlayout.widget.ConstraintSet
|
import androidx.constraintlayout.widget.ConstraintSet
|
||||||
import bean.LoginRequest
|
import bean.LoginRequest
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.ActivityLoginBinding
|
import com.ckkj.defense_device.databinding.ActivityLoginBinding
|
||||||
import com.example.defenseapplication.home.HomeActivity
|
import com.ckkj.defense_device.home.HomeActivity
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.ApiConfig
|
||||||
import com.example.defenseapplication.utils.UserinfoUtil
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -26,19 +28,13 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
private lateinit var binding: ActivityLoginBinding
|
private lateinit var binding: ActivityLoginBinding
|
||||||
private var currentLoginMode = LoginMode.SMS
|
private var currentLoginMode = LoginMode.SMS
|
||||||
|
private var countDownTimer: CountDownTimer? = null
|
||||||
|
|
||||||
enum class LoginMode { SMS, PASSWORD }
|
enum class LoginMode { SMS, PASSWORD }
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
|
ApiConfig.resetAuthRedirectFlag()
|
||||||
if (UserinfoUtil.getUserInfo() != null) {
|
|
||||||
val intent = Intent(this, HomeActivity::class.java)
|
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
|
||||||
startActivity(intent)
|
|
||||||
finish()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
binding = ActivityLoginBinding.inflate(layoutInflater)
|
binding = ActivityLoginBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
@@ -81,7 +77,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
binding.registerText.visibility = View.VISIBLE
|
binding.registerText.visibility = View.VISIBLE
|
||||||
binding.forgetText.visibility = View.GONE
|
binding.forgetText.visibility = View.GONE
|
||||||
updateRegisterTextConstraints(center = false)
|
updateRegisterTextConstraints(center = true)
|
||||||
|
|
||||||
//需要正确的方法名和参数
|
//需要正确的方法名和参数
|
||||||
updateLoginButtonTopConstraint(R.id.smsRowLayout)
|
updateLoginButtonTopConstraint(R.id.smsRowLayout)
|
||||||
@@ -106,7 +102,6 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
private fun updateLoginButtonTopConstraint(topTargetId: Int) {
|
private fun updateLoginButtonTopConstraint(topTargetId: Int) {
|
||||||
val params = binding.loginBtn.layoutParams as ConstraintLayout.LayoutParams
|
val params = binding.loginBtn.layoutParams as ConstraintLayout.LayoutParams
|
||||||
params.topToBottom = topTargetId
|
params.topToBottom = topTargetId
|
||||||
params.topMargin = 32
|
|
||||||
binding.loginBtn.layoutParams = params
|
binding.loginBtn.layoutParams = params
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,7 +118,6 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
params.endToEnd = ConstraintSet.UNSET
|
params.endToEnd = ConstraintSet.UNSET
|
||||||
}
|
}
|
||||||
params.topToBottom = binding.loginBtn.id
|
params.topToBottom = binding.loginBtn.id
|
||||||
params.topMargin = 20
|
|
||||||
binding.registerText.layoutParams = params
|
binding.registerText.layoutParams = params
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,25 +168,24 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
binding.registerText.setOnClickListener {
|
binding.registerText.setOnClickListener {
|
||||||
val intent= Intent(this, RegisterActivity::class.java)
|
val intent= Intent(this, RegisterActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
Toast.makeText(this, R.string.redirect_register_page, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
binding.forgetText.setOnClickListener {
|
binding.forgetText.setOnClickListener {
|
||||||
val intent= Intent(this, ForgetPasswordActivity::class.java)
|
val intent= Intent(this, ForgetPasswordActivity::class.java)
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
Toast.makeText(this, R.string.forgot_password_page, Toast.LENGTH_SHORT).show()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startCountDown() {
|
private fun startCountDown() {
|
||||||
binding.sendCodeBtn.isEnabled = false
|
binding.sendCodeBtn.isEnabled = false
|
||||||
object : CountDownTimer(60000, 1000) {
|
countDownTimer = object : CountDownTimer(60000, 1000) {
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
||||||
}
|
}
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
binding.sendCodeBtn.text = getString(R.string.send_code)
|
binding.sendCodeBtn.text = getString(R.string.resend_code)
|
||||||
binding.sendCodeBtn.isEnabled = true
|
binding.sendCodeBtn.isEnabled = true
|
||||||
|
countDownTimer = null
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
@@ -202,6 +195,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getCode(phone)
|
val response = RetrofitNetwork.getNetworkService().getCode(phone)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d("VerificationCode", "code = ${response.code}, msg = ${response.msg}")
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@LoginActivity, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LoginActivity, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
||||||
startCountDown()
|
startCountDown()
|
||||||
@@ -267,6 +261,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
UserinfoUtil.saveUserInfo(response.data)
|
UserinfoUtil.saveUserInfo(response.data)
|
||||||
Toast.makeText(this@LoginActivity, R.string.password_login_success_title, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LoginActivity, R.string.password_login_success_title, Toast.LENGTH_SHORT).show()
|
||||||
val intent = Intent(this@LoginActivity, HomeActivity::class.java)
|
val intent = Intent(this@LoginActivity, HomeActivity::class.java)
|
||||||
|
//清除任务栈
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
@@ -293,4 +288,10 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
|
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
|
||||||
view.background = gradientDrawable
|
view.background = gradientDrawable
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
countDownTimer?.cancel()
|
||||||
|
countDownTimer = null
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
@@ -8,9 +8,10 @@ import android.os.CountDownTimer
|
|||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import bean.RegisterRequest
|
import bean.RegisterRequest
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.RegisterActivityBinding
|
import com.ckkj.defense_device.databinding.RegisterActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -99,11 +100,10 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun startCountDown() {
|
private fun startCountDown() {
|
||||||
|
binding.sendCodeBtn.isEnabled = false
|
||||||
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
|
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
|
||||||
override fun onTick(millisUntilFinished: Long) {
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
val secondsRemaining = (millisUntilFinished / 1000).toInt()
|
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
||||||
binding.sendCodeBtn.text = "${secondsRemaining}秒后重试"
|
|
||||||
binding.sendCodeBtn.isEnabled = false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
@@ -115,7 +115,7 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
private fun resetSendButton() {
|
private fun resetSendButton() {
|
||||||
countDownTimer?.cancel()
|
countDownTimer?.cancel()
|
||||||
countDownTimer = null
|
countDownTimer = null
|
||||||
binding.sendCodeBtn.text = getString(R.string.send_code)
|
binding.sendCodeBtn.text = getString(R.string.resend_code)
|
||||||
binding.sendCodeBtn.isEnabled = true
|
binding.sendCodeBtn.isEnabled = true
|
||||||
isSendingCode = false
|
isSendingCode = false
|
||||||
}
|
}
|
||||||
@@ -158,7 +158,9 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
isLoading = true
|
isLoading = true
|
||||||
binding.btnNext.isEnabled = false
|
binding.btnNext.isEnabled = false
|
||||||
binding.btnNext.text = getString(R.string.registering)
|
val loadingDialog = LoadingDialog(this)
|
||||||
|
.setMessage(getString(R.string.registering))
|
||||||
|
.apply { show() }
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -174,12 +176,13 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
val response = RetrofitNetwork.getNetworkService().register(registerRequest)
|
val response = RetrofitNetwork.getNetworkService().register(registerRequest)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = getString(R.string.next_step)
|
|
||||||
|
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@RegisterActivity, R.string.register_success, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@RegisterActivity, R.string.register_success, Toast.LENGTH_SHORT).show()
|
||||||
val intent = Intent(this@RegisterActivity, LoginActivity::class.java)
|
val intent = Intent(this@RegisterActivity, RegisterSuccessActivity::class.java)
|
||||||
|
//清除任务栈
|
||||||
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
startActivity(intent)
|
startActivity(intent)
|
||||||
finish()
|
finish()
|
||||||
@@ -190,8 +193,8 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = getString(R.string.next_step)
|
|
||||||
Toast.makeText(this@RegisterActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@RegisterActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,15 +1,11 @@
|
|||||||
package com.example.defenseapplication.login
|
package com.ckkj.defense_device.login
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import com.ckkj.defense_device.databinding.RegisterSuccessActivityBinding
|
||||||
import androidx.core.view.WindowInsetsCompat
|
import com.ckkj.defense_device.home.HomeActivity
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.databinding.RegisterSuccessActivityBinding
|
|
||||||
import com.example.defenseapplication.home.HomeActivity
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
//注册成功界面
|
//注册成功界面
|
||||||
class RegisterSuccessActivity : AppCompatActivity() {
|
class RegisterSuccessActivity : AppCompatActivity() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.model
|
package com.ckkj.defense_device.model
|
||||||
|
|
||||||
data class FamilyItem(
|
data class FamilyItem(
|
||||||
val id: String,
|
val id: String,
|
||||||
@@ -0,0 +1,144 @@
|
|||||||
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.os.CountDownTimer
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.databinding.CancelAccountActivityBinding
|
||||||
|
import com.ckkj.defense_device.login.LoginActivity
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
|
import com.ckkj.defense_device.view.CustomDialogFragment
|
||||||
|
import com.ckkj.defense_device.view.DefenseDialogs
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
class CancelAccountActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: CancelAccountActivityBinding
|
||||||
|
private var countDownTimer: CountDownTimer? = null
|
||||||
|
private var phoneNumber: String = ""
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = CancelAccountActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
getUserInfo()
|
||||||
|
initListener()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getUserInfo() {
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getUserInfo()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
phoneNumber = response.data?.phonenumber ?: ""
|
||||||
|
binding.tvPhoneNumber.text = maskPhoneNumber(phoneNumber)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(this@CancelAccountActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun maskPhoneNumber(phone: String): String {
|
||||||
|
if (phone.length != 11) {
|
||||||
|
return phone
|
||||||
|
}
|
||||||
|
return phone.substring(0, 3) + "****" + phone.substring(7)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun initListener() {
|
||||||
|
binding.ivBack.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.btnSendCode.setOnClickListener {
|
||||||
|
if (phoneNumber.isEmpty()) {
|
||||||
|
Toast.makeText(this, R.string.get_user_info_fail, Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
if (phoneNumber.length != 11) {
|
||||||
|
Toast.makeText(this, R.string.phone_format_invalid, Toast.LENGTH_SHORT).show()
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
|
||||||
|
sendVerificationCode(phoneNumber)
|
||||||
|
}
|
||||||
|
|
||||||
|
binding.btnCancelAccount.setOnClickListener {
|
||||||
|
DefenseDialogs.showDialog(
|
||||||
|
this,
|
||||||
|
config = CustomDialogFragment.Config(
|
||||||
|
title = getString(R.string.tip),
|
||||||
|
message = getString(R.string.confirm_cancel_account_user_account),
|
||||||
|
positiveText = getString(R.string.confirm),
|
||||||
|
negativeText = getString(R.string.cancel)
|
||||||
|
),
|
||||||
|
onPositiveClick = {
|
||||||
|
Toast.makeText(this@CancelAccountActivity, getString(R.string.cancel_account), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun sendVerificationCode(phone: String) {
|
||||||
|
binding.btnSendCode.isEnabled = false
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService().getCode(phone)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
Toast.makeText(this@CancelAccountActivity, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
||||||
|
startCountdown()
|
||||||
|
} else {
|
||||||
|
binding.btnSendCode.isEnabled = true
|
||||||
|
Toast.makeText(this@CancelAccountActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
binding.btnSendCode.isEnabled = true
|
||||||
|
Toast.makeText(this@CancelAccountActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startCountdown() {
|
||||||
|
countDownTimer = object : CountDownTimer(60000, 1000) {
|
||||||
|
override fun onTick(millisUntilFinished: Long) {
|
||||||
|
binding.btnSendCode.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFinish() {
|
||||||
|
binding.btnSendCode.text = getString(R.string.resend_code)
|
||||||
|
binding.btnSendCode.isEnabled = true
|
||||||
|
countDownTimer = null
|
||||||
|
}
|
||||||
|
}.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun onDestroy() {
|
||||||
|
super.onDestroy()
|
||||||
|
countDownTimer?.cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,12 +1,12 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.UpdatePassword
|
import com.ckkj.defense_device.bean.UpdatePassword
|
||||||
import com.example.defenseapplication.databinding.ChangePasswordActivityBinding
|
import com.ckkj.defense_device.databinding.ChangePasswordActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.databinding.FaceManagementActivityBinding
|
import com.ckkj.defense_device.databinding.FaceManagementActivityBinding
|
||||||
import com.example.defenseapplication.login.FaceLoginActivity
|
import com.ckkj.defense_device.login.FaceLoginActivity
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
|
||||||
//人脸管理页面
|
//人脸管理页面
|
||||||
@@ -1,32 +1,45 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.RecommendationCodeBean
|
||||||
import com.example.defenseapplication.databinding.DialogExpireTimeBinding
|
import com.ckkj.defense_device.bean.SelectInviterInfoBean
|
||||||
import com.example.defenseapplication.databinding.InvitationCodeActivityBinding
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.databinding.DialogExpireTimeBinding
|
||||||
|
import com.ckkj.defense_device.databinding.InvitationCodeActivityBinding
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.google.zxing.BarcodeFormat
|
import com.google.zxing.BarcodeFormat
|
||||||
import com.google.zxing.EncodeHintType
|
import com.google.zxing.EncodeHintType
|
||||||
import com.google.zxing.qrcode.QRCodeWriter
|
import com.google.zxing.qrcode.QRCodeWriter
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import com.maning.mlkitscanner.scan.MNScanManager
|
||||||
|
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.json.JSONObject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.util.Hashtable
|
import java.util.Hashtable
|
||||||
@@ -44,7 +57,24 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
private var isLoading = false // 是否正在加载
|
private var isLoading = false // 是否正在加载
|
||||||
private var hasGeneratedQrCode = false // 是否已经生成过二维码
|
private var hasGeneratedQrCode = false // 是否已经生成过二维码
|
||||||
|
|
||||||
|
private val requestPermissionsLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestMultiplePermissions()
|
||||||
|
) { permissions ->
|
||||||
|
val cameraGranted = permissions[Manifest.permission.CAMERA] ?: false
|
||||||
|
val storageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
permissions[Manifest.permission.READ_MEDIA_IMAGES] ?: false
|
||||||
|
} else {
|
||||||
|
permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: false
|
||||||
|
}
|
||||||
|
if (cameraGranted && storageGranted) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TAG = "InvitationCodeActivity"
|
||||||
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
||||||
const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L
|
const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L
|
||||||
}
|
}
|
||||||
@@ -90,15 +120,136 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// 撤销邀请按钮
|
// 撤销邀请按钮
|
||||||
binding.btnCancelInvite.setOnClickListener {
|
binding.btnCancelInvite.setOnClickListener {
|
||||||
showPasswordDialog {
|
if (generatedInviteCode.isEmpty()) {
|
||||||
cancelInvitation()
|
ToastUtils.showError(this, getString(R.string.qr_code_expired))
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
showPasswordDialog { password, dialog ->
|
||||||
|
cancelInvitation(password, dialog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成/重新生成按钮
|
// 生成/重新生成按钮
|
||||||
binding.btnRegenerate.setOnClickListener {
|
binding.btnRegenerate.setOnClickListener {
|
||||||
showPasswordDialog {
|
showPasswordDialog { password, dialog ->
|
||||||
generateOrRegenerateInvitation()
|
generateOrRegenerateInvitation(password, dialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.sys.setOnClickListener {
|
||||||
|
checkPermissionsAndScan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPermissionsAndScan() {
|
||||||
|
val cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
|
||||||
|
val storagePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES)
|
||||||
|
} else {
|
||||||
|
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
if (cameraPermission == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
storagePermission == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
val permissionsToRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
requestPermissionsLauncher.launch(permissionsToRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startScan() {
|
||||||
|
MNScanManager.startScan(this, object : MNScanCallback {
|
||||||
|
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||||
|
when (resultCode) {
|
||||||
|
MNScanManager.RESULT_SUCCESS -> {
|
||||||
|
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
||||||
|
if (!result.isNullOrEmpty()) {
|
||||||
|
val inviteCode = parseInviteCode(result[0])
|
||||||
|
if (inviteCode.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "无效的邀请码", Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
fetchInviterInfo(inviteCode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码结果为空", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_FAIL -> {
|
||||||
|
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码失败: $error", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_CANCLE -> {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码取消", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseInviteCode(scanResult: String): String? {
|
||||||
|
val trimmed = scanResult.trim()
|
||||||
|
if (trimmed.isEmpty()) return null
|
||||||
|
return try {
|
||||||
|
if (trimmed.startsWith("{")) {
|
||||||
|
JSONObject(trimmed).optString("code").takeIf { it.isNotEmpty() }
|
||||||
|
} else {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInviterInfo(inviteCode: String) {
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.selectInviterInfo(SelectInviterInfoBean(code = inviteCode))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val inviter = response.data
|
||||||
|
val parentId = inviter.resolveParentId()
|
||||||
|
if (parentId.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@InvitationCodeActivity,
|
||||||
|
getString(R.string.network_error),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
val intent = Intent(this@InvitationCodeActivity, JoinFamilyInviteActivity::class.java).apply {
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_INVITE_CODE, inviteCode)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_NICK_NAME, inviter.nickName)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_AVATAR, inviter.avatar)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_PARENT_ID, parentId)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_USER_ID, inviter.userId)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
this@InvitationCodeActivity,
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,14 +257,56 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
/**
|
/**
|
||||||
* 生成或重新生成邀请码
|
* 生成或重新生成邀请码
|
||||||
*/
|
*/
|
||||||
private fun generateOrRegenerateInvitation() {
|
private fun generateOrRegenerateInvitation(password: String, passwordDialog: PasswordInputDialog) {
|
||||||
// 根据当前选择的时效生成邀请码
|
if (isLoading) return
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.generateRecommendationCode(VerifyOptionPasswordRequest(password))
|
||||||
|
Log.d(TAG, "生成推荐码响应: code=${response.code}, msg=${response.msg}, data=${response.data}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
val parsed = parseRecommendationCode(response.data)
|
||||||
|
if (parsed != null) {
|
||||||
|
passwordDialog.dismiss()
|
||||||
|
generatedInviteCode = parsed.first
|
||||||
|
expireTimestamp = parsed.second
|
||||||
|
qrCodeContent =
|
||||||
|
"{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
||||||
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"推荐码生成成功: Code=$generatedInviteCode, expireTimestamp=$expireTimestamp, qrContent=$qrCodeContent"
|
||||||
|
)
|
||||||
generateQRCode()
|
generateQRCode()
|
||||||
showQrCode()
|
showQrCode()
|
||||||
// 更新按钮文字为"重新生成"
|
|
||||||
binding.btnRegenerate.text = getString(R.string.regenerate)
|
binding.btnRegenerate.text = getString(R.string.regenerate)
|
||||||
hasGeneratedQrCode = true
|
hasGeneratedQrCode = true
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
ToastUtils.showSuccess(this@InvitationCodeActivity, getString(R.string.operation_success))
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "推荐码解析失败, raw data=${response.data}")
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "生成推荐码失败: code=${response.code}, msg=${response.msg}")
|
||||||
|
passwordDialog.showError(
|
||||||
|
response.msg.ifEmpty { getString(R.string.password_error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "生成推荐码异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showExpireTimeDialog() {
|
private fun showExpireTimeDialog() {
|
||||||
@@ -151,9 +344,6 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 显示二维码并生成
|
|
||||||
showQrCode()
|
|
||||||
generateQRCode()
|
|
||||||
expireTimeDialog?.dismiss()
|
expireTimeDialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,22 +363,28 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateQRCode() {
|
private fun generateQRCode() {
|
||||||
// 检查二维码是否过期,如果过期则生成新的邀请码
|
if (qrCodeContent.isEmpty()) return
|
||||||
val isExpired = expireTimestamp > 0 && System.currentTimeMillis() > expireTimestamp
|
val qrBitmap = createQRCodeWithLogo(qrCodeContent, 400, 400)
|
||||||
val content = if (qrCodeContent.isNotEmpty() && !isExpired) qrCodeContent else generateInviteCode()
|
|
||||||
val qrBitmap = createQRCodeWithLogo(content, 400, 400)
|
|
||||||
binding.ivQrCode.setImageBitmap(qrBitmap)
|
binding.ivQrCode.setImageBitmap(qrBitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInviteCode(): String {
|
private fun parseRecommendationCode(data: Any?): Pair<String, Long>? {
|
||||||
val timestamp = System.currentTimeMillis()
|
if (data == null) return null
|
||||||
expireTimestamp = timestamp + expireTimeInMillis
|
return when (data) {
|
||||||
generatedInviteCode = "INV${timestamp}"
|
is String -> {
|
||||||
qrCodeContent = "{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
if (data.isEmpty()) null
|
||||||
// 输出日志,方便调试验证
|
else Pair(data, System.currentTimeMillis() + expireTimeInMillis)
|
||||||
android.util.Log.d("InvitationCode", "生成的二维码内容: $qrCodeContent")
|
}
|
||||||
android.util.Log.d("InvitationCode", "推荐码: $generatedInviteCode, 过期时间戳: $expireTimestamp")
|
else -> {
|
||||||
return qrCodeContent
|
val bean = Gson().fromJson(Gson().toJson(data), RecommendationCodeBean::class.java)
|
||||||
|
val code = bean.inviteCode?.takeIf { it.isNotEmpty() }
|
||||||
|
?: bean.code?.takeIf { it.isNotEmpty() }
|
||||||
|
?: return null
|
||||||
|
val expire = bean.expireTime ?: bean.expire
|
||||||
|
?: (System.currentTimeMillis() + expireTimeInMillis)
|
||||||
|
Pair(code, expire)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* 这段代码生成带Logo的二维码:
|
* 这段代码生成带Logo的二维码:
|
||||||
@@ -232,7 +428,7 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val logoDrawable = ContextCompat.getDrawable(this, R.mipmap.loge)
|
val logoDrawable = ContextCompat.getDrawable(this, R.mipmap.logo)
|
||||||
if (logoDrawable != null) {
|
if (logoDrawable != null) {
|
||||||
val logoSize = width / 5
|
val logoSize = width / 5
|
||||||
val logoX = (width - logoSize) / 2
|
val logoX = (width - logoSize) / 2
|
||||||
@@ -415,55 +611,61 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
/**
|
/**
|
||||||
* 撤销邀请
|
* 撤销邀请
|
||||||
*/
|
*/
|
||||||
private fun cancelInvitation() {
|
private fun cancelInvitation(password: String, passwordDialog: PasswordInputDialog) {
|
||||||
// 撤销邀请逻辑
|
if (isLoading) return
|
||||||
|
if (generatedInviteCode.isEmpty()) {
|
||||||
|
passwordDialog.showError(getString(R.string.qr_code_expired))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.revokeInvitation(VerifyOptionPasswordRequest(password))
|
||||||
|
Log.d(TAG, "撤销邀请响应: code=${response.code}, msg=${response.msg}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
passwordDialog.dismiss()
|
||||||
hideQrCode()
|
hideQrCode()
|
||||||
generatedInviteCode = ""
|
generatedInviteCode = ""
|
||||||
qrCodeContent = ""
|
qrCodeContent = ""
|
||||||
expireTimestamp = 0
|
expireTimestamp = 0
|
||||||
hasGeneratedQrCode = false
|
hasGeneratedQrCode = false
|
||||||
// 恢复按钮文字为"生成邀请码"
|
|
||||||
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
||||||
// 显示提示
|
ToastUtils.showSuccess(this@InvitationCodeActivity, getString(R.string.operation_success))
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
} else {
|
||||||
|
passwordDialog.showError(
|
||||||
|
response.msg.ifEmpty { getString(R.string.password_error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "撤销邀请异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示密码输入对话框
|
* 显示密码输入对话框
|
||||||
* @param onSuccess 验证成功后的回调
|
|
||||||
*/
|
*/
|
||||||
private fun showPasswordDialog(onSuccess: () -> Unit) {
|
private fun showPasswordDialog(onConfirm: (String, PasswordInputDialog) -> Unit) {
|
||||||
val dialog = PasswordInputDialog(this)
|
val dialog = PasswordInputDialog(this)
|
||||||
dialog.setTitle(getString(R.string.input_op_pwd))
|
dialog.setTitle(getString(R.string.input_op_pwd))
|
||||||
dialog.setOnConfirmListener { password ->
|
dialog.setOnConfirmListener { password ->
|
||||||
verifyPassword(password, dialog, onSuccess)
|
onConfirm(password, dialog)
|
||||||
}
|
}
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证操作密码
|
|
||||||
*/
|
|
||||||
private fun verifyPassword(password: String, dialog: PasswordInputDialog, onSuccess: () -> Unit) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
val response = RetrofitNetwork.getNetworkService()
|
|
||||||
.verifyOptionPassword(VerifyOptionPasswordRequest(password))
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (response.code == 200) {
|
|
||||||
dialog.dismiss()
|
|
||||||
onSuccess.invoke()
|
|
||||||
} else {
|
|
||||||
dialog.showError(getString(R.string.password_error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
dialog.showError(getString(R.string.network_error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.bean.JoinTheFamilyBean
|
||||||
|
import com.ckkj.defense_device.databinding.JoinFamilyInviteActivityBinding
|
||||||
|
import com.ckkj.defense_device.home.HomeActivity
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
// 邀请加入家庭
|
||||||
|
class JoinFamilyInviteActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: JoinFamilyInviteActivityBinding
|
||||||
|
private var isLoading = false
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = JoinFamilyInviteActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
binding.ivBack.setOnClickListener { finish() }
|
||||||
|
binding.btnJoinNow.setOnClickListener { joinFamily() }
|
||||||
|
displayInviterInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun joinFamily() {
|
||||||
|
if (isLoading) return
|
||||||
|
|
||||||
|
val parentId = intent.getStringExtra(EXTRA_USER_ID).orEmpty()
|
||||||
|
val inviteCode = intent.getStringExtra(EXTRA_INVITE_CODE).orEmpty()
|
||||||
|
if (parentId.isEmpty() || inviteCode.isEmpty()) {
|
||||||
|
Log.e(TAG, "加入家庭参数无效: parentId=$parentId, inviteCode=$inviteCode")
|
||||||
|
Toast.makeText(this, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.e(TAG, "加入家庭请求: parentId=$parentId, inviteCode=$inviteCode")
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.joinTheFamily(JoinTheFamilyBean(parentId = parentId, inviteCode = inviteCode))
|
||||||
|
Log.e(TAG, "加入家庭响应: code=${response.code}, msg=${response.msg}, data=${response.data}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
Log.e(TAG, "加入家庭成功,返回首页刷新")
|
||||||
|
ToastUtils.showSuccess(this@JoinFamilyInviteActivity, getString(R.string.operation_success))
|
||||||
|
val homeIntent = Intent(this@JoinFamilyInviteActivity, HomeActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||||
|
putExtra(HomeActivity.EXTRA_REFRESH, true)
|
||||||
|
}
|
||||||
|
startActivity(homeIntent)
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "加入家庭失败: code=${response.code}, msg=${response.msg}")
|
||||||
|
Toast.makeText(
|
||||||
|
this@JoinFamilyInviteActivity,
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "加入家庭请求异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(this@JoinFamilyInviteActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun displayInviterInfo() {
|
||||||
|
val nickName = intent.getStringExtra(EXTRA_NICK_NAME).orEmpty()
|
||||||
|
val avatar = intent.getStringExtra(EXTRA_AVATAR)
|
||||||
|
|
||||||
|
binding.tvNickname.text = nickName.ifEmpty { getString(R.string.nickname_placeholder) }
|
||||||
|
binding.tvInviteMessage.text = getString(
|
||||||
|
R.string.invite_join_family_message,
|
||||||
|
nickName.ifEmpty { getString(R.string.nickname_placeholder) }
|
||||||
|
)
|
||||||
|
|
||||||
|
val requestOptions = RequestOptions()
|
||||||
|
.placeholder(R.mipmap.img)
|
||||||
|
.error(R.mipmap.img)
|
||||||
|
|
||||||
|
Glide.with(this)
|
||||||
|
.load(avatar)
|
||||||
|
.apply(requestOptions)
|
||||||
|
.circleCrop()
|
||||||
|
.into(binding.ivAvatar)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "JoinFamilyInviteActivity"
|
||||||
|
const val EXTRA_INVITE_CODE = "invite_code"
|
||||||
|
const val EXTRA_NICK_NAME = "nick_name"
|
||||||
|
const val EXTRA_AVATAR = "avatar"
|
||||||
|
const val EXTRA_PARENT_ID = "parent_id"
|
||||||
|
const val EXTRA_USER_ID = "user_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,14 +1,9 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import com.ckkj.defense_device.databinding.LoginPasswordActivityBinding
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import com.example.defenseapplication.R
|
|
||||||
import com.example.defenseapplication.databinding.LoginPasswordActivityBinding
|
|
||||||
import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
|
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
|
||||||
//登录密码
|
//登录密码
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.UpdateUserInfo
|
import com.ckkj.defense_device.bean.UpdateUserInfo
|
||||||
import com.example.defenseapplication.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.example.defenseapplication.databinding.OperationPasswordActivityBinding
|
import com.ckkj.defense_device.databinding.OperationPasswordActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.CustomDialogFragment
|
import com.ckkj.defense_device.view.CustomDialogFragment
|
||||||
import com.example.defenseapplication.view.LoadingDialog
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.example.defenseapplication.view.showDefenseDialog
|
import com.ckkj.defense_device.view.showDefenseDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.example.defenseapplication.databinding.PasswordManagementActivityBinding
|
import com.ckkj.defense_device.databinding.PasswordManagementActivityBinding
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
//密码管理
|
//密码管理
|
||||||
class PasswordManagementActivity : AppCompatActivity() {
|
class PasswordManagementActivity : AppCompatActivity() {
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.ContentResolver
|
import android.content.ContentResolver
|
||||||
@@ -11,24 +11,21 @@ import android.os.Environment
|
|||||||
import android.provider.MediaStore
|
import android.provider.MediaStore
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.enableEdgeToEdge
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import androidx.core.content.FileProvider
|
import androidx.core.content.FileProvider
|
||||||
import androidx.core.view.ViewCompat
|
|
||||||
import androidx.core.view.WindowInsetsCompat
|
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
import com.bumptech.glide.request.RequestOptions
|
import com.bumptech.glide.request.RequestOptions
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.bean.UpdateUserInfo
|
import com.ckkj.defense_device.bean.UpdateUserInfo
|
||||||
import com.example.defenseapplication.bean.UserInfoBean
|
import com.ckkj.defense_device.bean.UserInfoBean
|
||||||
import com.example.defenseapplication.databinding.PersonalProfileActivityBinding
|
import com.ckkj.defense_device.databinding.PersonalProfileActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.example.defenseapplication.view.AvatarSelectDialog
|
import com.ckkj.defense_device.view.AvatarSelectDialog
|
||||||
import com.example.defenseapplication.view.CustomDialogFragmentText
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.example.defenseapplication.view.LoadingDialog
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.example.defenseapplication.view.PhoneModifyDialogFragment
|
import com.ckkj.defense_device.view.PhoneModifyDialogFragment
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -1,13 +1,13 @@
|
|||||||
package com.example.defenseapplication.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import bean.ForgotRequest
|
import bean.ForgotRequest
|
||||||
import com.example.defenseapplication.R
|
import com.ckkj.defense_device.R
|
||||||
import com.example.defenseapplication.databinding.RetrievePasswordActivityBinding
|
import com.ckkj.defense_device.databinding.RetrievePasswordActivityBinding
|
||||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -163,7 +163,7 @@ class RetrievePasswordActivity : AppCompatActivity() {
|
|||||||
override fun onFinish() {
|
override fun onFinish() {
|
||||||
isCountingDown = false
|
isCountingDown = false
|
||||||
binding.btnGetCode.isEnabled = true
|
binding.btnGetCode.isEnabled = true
|
||||||
binding.btnGetCode.text = getString(R.string.get_verification_code)
|
binding.btnGetCode.text = getString(R.string.resend_code)
|
||||||
}
|
}
|
||||||
}.start()
|
}.start()
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.enableEdgeToEdge
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.ckkj.defense_device.databinding.SettingsMenusActivityBinding
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
class SettingsMenusActivity : AppCompatActivity() {
|
||||||
|
private lateinit var binding: SettingsMenusActivityBinding
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
enableEdgeToEdge()
|
||||||
|
binding = SettingsMenusActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
|
||||||
|
val versionName = packageManager.getPackageInfo(packageName, 0).versionName
|
||||||
|
binding.tvVersion.text = versionName
|
||||||
|
// 显示缓存大小
|
||||||
|
displayCacheSize()
|
||||||
|
|
||||||
|
setupClickListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupClickListeners() {
|
||||||
|
// 返回按钮
|
||||||
|
binding.ivBack.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查更新
|
||||||
|
binding.itemCheckUpdate.setOnClickListener {
|
||||||
|
Toast.makeText(this, "正在检查更新...", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除缓存
|
||||||
|
binding.itemClearCache.setOnClickListener {
|
||||||
|
clearCache()
|
||||||
|
displayCacheSize() // 更新缓存大小显示
|
||||||
|
Toast.makeText(this, "缓存已清除", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户协议
|
||||||
|
binding.itemUserAgreement.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐私政策
|
||||||
|
binding.itemPrivacyPolicy.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注销账号
|
||||||
|
binding.itemLogout.setOnClickListener {
|
||||||
|
val intent = Intent(this, CancelAccountActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//缓存方法
|
||||||
|
private fun displayCacheSize() {
|
||||||
|
val cacheSize = getCacheSize()
|
||||||
|
val sizeString = when {
|
||||||
|
cacheSize >= 1024 * 1024 -> String.format("%.2f MB", cacheSize / (1024.0 * 1024.0))
|
||||||
|
else -> String.format("%d KB", cacheSize / 1024)
|
||||||
|
}
|
||||||
|
binding.tvCacheSize.text = sizeString
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getCacheSize(): Long {
|
||||||
|
val cacheDir = cacheDir
|
||||||
|
return getFolderSize(cacheDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getFolderSize(dir: File?): Long {
|
||||||
|
var size = 0L
|
||||||
|
if (dir != null && dir.isDirectory) {
|
||||||
|
dir.listFiles()?.forEach { file ->
|
||||||
|
size += if (file.isFile) {
|
||||||
|
file.length()
|
||||||
|
} else {
|
||||||
|
getFolderSize(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun clearCache() {
|
||||||
|
val cacheDir = cacheDir
|
||||||
|
deleteDir(cacheDir)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteDir(dir: File?): Boolean {
|
||||||
|
if (dir != null && dir.isDirectory) {
|
||||||
|
dir.listFiles()?.forEach { file ->
|
||||||
|
deleteDir(file)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return dir?.delete() ?: false
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.example.defenseapplication.utils
|
package com.ckkj.defense_device.utils
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
@@ -1,8 +1,14 @@
|
|||||||
package com.example.defenseapplication.utils
|
package com.ckkj.defense_device.utils
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import com.example.defenseapplication.bean.BaseInfo
|
import android.widget.Toast
|
||||||
|
import com.blankj.utilcode.util.Utils
|
||||||
|
import com.ckkj.defense_device.bean.BaseInfo
|
||||||
|
import com.ckkj.defense_device.login.LoginActivity
|
||||||
import com.google.gson.Gson
|
import com.google.gson.Gson
|
||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import okhttp3.Interceptor
|
import okhttp3.Interceptor
|
||||||
@@ -24,10 +30,17 @@ object ApiConfig {
|
|||||||
@Volatile
|
@Volatile
|
||||||
public var authToken: String = ""
|
public var authToken: String = ""
|
||||||
|
|
||||||
|
@Volatile
|
||||||
|
private var isRedirectingToLogin = false
|
||||||
|
|
||||||
fun updateAuthToken(token: String) {
|
fun updateAuthToken(token: String) {
|
||||||
authToken = token
|
authToken = token
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun resetAuthRedirectFlag() {
|
||||||
|
isRedirectingToLogin = false
|
||||||
|
}
|
||||||
|
|
||||||
fun hasAuthToken(): Boolean {
|
fun hasAuthToken(): Boolean {
|
||||||
return authToken.isNotBlank()
|
return authToken.isNotBlank()
|
||||||
}
|
}
|
||||||
@@ -116,8 +129,8 @@ object ApiConfig {
|
|||||||
val businessCode = if (jsonObject.has("code")) jsonObject.get("code").asInt else 0
|
val businessCode = if (jsonObject.has("code")) jsonObject.get("code").asInt else 0
|
||||||
|
|
||||||
if (httpCode == 401 || httpCode == 424 || businessCode == 401) {
|
if (httpCode == 401 || httpCode == 424 || businessCode == 401) {
|
||||||
clearUserLoginInfo()
|
|
||||||
val msg = if (jsonObject.has("msg")) jsonObject.get("msg").asString else "登录已过期,请重新登录"
|
val msg = if (jsonObject.has("msg")) jsonObject.get("msg").asString else "登录已过期,请重新登录"
|
||||||
|
redirectToLogin(msg)
|
||||||
return@Interceptor buildFakeErrorResponse(request, msg, code = if (businessCode != 0) businessCode else httpCode)
|
return@Interceptor buildFakeErrorResponse(request, msg, code = if (businessCode != 0) businessCode else httpCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +151,7 @@ object ApiConfig {
|
|||||||
*/
|
*/
|
||||||
private fun buildFakeErrorResponse(request: Request, msg: String, code: Int = 1): Response {
|
private fun buildFakeErrorResponse(request: Request, msg: String, code: Int = 1): Response {
|
||||||
val baseInfo = BaseInfo(
|
val baseInfo = BaseInfo(
|
||||||
message = msg,
|
msg = msg,
|
||||||
code = code,
|
code = code,
|
||||||
data = null,
|
data = null,
|
||||||
)
|
)
|
||||||
@@ -179,12 +192,36 @@ object ApiConfig {
|
|||||||
private fun buildAuthorizationValue(token: String): String {
|
private fun buildAuthorizationValue(token: String): String {
|
||||||
return if (token.startsWith("Bearer ")) token else "Bearer $token"
|
return if (token.startsWith("Bearer ")) token else "Bearer $token"
|
||||||
}
|
}
|
||||||
|
//401跳转登录界面
|
||||||
|
private fun redirectToLogin(msg: String) {
|
||||||
|
Handler(Looper.getMainLooper()).post {
|
||||||
|
if (isRedirectingToLogin) return@post
|
||||||
|
val current = ActivityManager.getCurrentActivity()
|
||||||
|
if (current is LoginActivity) return@post
|
||||||
|
|
||||||
|
isRedirectingToLogin = true
|
||||||
|
clearUserLoginInfo()
|
||||||
|
|
||||||
|
val context = current ?: Utils.getApp()
|
||||||
|
ActivityManager.finishAllActivities()
|
||||||
|
|
||||||
|
val intent = Intent(context, LoginActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||||
|
}
|
||||||
|
context.startActivity(intent)
|
||||||
|
|
||||||
|
if (msg.isNotBlank()) {
|
||||||
|
Toast.makeText(Utils.getApp(), msg, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun clearUserLoginInfo() {
|
private fun clearUserLoginInfo() {
|
||||||
try {
|
try {
|
||||||
authToken = ""
|
UserinfoUtil.clearUserInfo()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
authToken = ""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user