Compare commits
10 Commits
02fc928f20
...
ab0dd2fbf6
| Author | SHA1 | Date | |
|---|---|---|---|
| ab0dd2fbf6 | |||
| a9a69ca31b | |||
| 1d54d6aa2a | |||
| 200086301a | |||
| 0d0838d0e1 | |||
| a132cdfd27 | |||
| 96c8cca033 | |||
| 07f634ae05 | |||
| 4819dbce86 | |||
| 6942abca3b |
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)
|
||||||
|
|
||||||
|
|
||||||
@@ -28,6 +28,12 @@
|
|||||||
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
|
<activity
|
||||||
android:name=".home.StartActivity"
|
android:name=".home.StartActivity"
|
||||||
android:exported="true">
|
android:exported="true">
|
||||||
@@ -122,8 +128,7 @@
|
|||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".home.HomeActivity"
|
android:name=".home.HomeActivity"
|
||||||
android:exported="false">
|
android:exported="false" />
|
||||||
</activity>
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".login.RegisterSuccessActivity"
|
android:name=".login.RegisterSuccessActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@@ -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
|
||||||
|
)
|
||||||
@@ -39,6 +39,7 @@ import com.ckkj.defense_device.utils.RetrofitNetwork
|
|||||||
import com.ckkj.defense_device.utils.UserinfoUtil
|
import com.ckkj.defense_device.utils.UserinfoUtil
|
||||||
import com.ckkj.defense_device.view.DefenseDialogs
|
import com.ckkj.defense_device.view.DefenseDialogs
|
||||||
import com.ckkj.defense_device.view.LoadingDialog
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.ckkj.defense_device.view.PullRefreshLayout
|
||||||
import com.ckkj.defense_device.view.showDefenseDialog
|
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
|
||||||
@@ -62,6 +63,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()
|
||||||
@@ -162,7 +166,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun fetchInviterInfo(inviteCode: String) {
|
private fun fetchInviterInfo(inviteCode: String) {
|
||||||
val loadingDialog = LoadingDialog(requireActivity()).apply { show() }
|
val loadingDialog = LoadingDialog(requireActivity()).setMessage(this.getString(R.string.loading)).apply { show() }
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService()
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
@@ -297,9 +301,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) {
|
||||||
@@ -307,9 +313,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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -425,7 +446,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()
|
||||||
@@ -439,15 +460,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("加载中...").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
|
||||||
@@ -470,25 +496,36 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
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()
|
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() {
|
||||||
@@ -548,6 +585,8 @@ class HomeMenuFragment : Fragment() {
|
|||||||
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(
|
||||||
@@ -564,6 +603,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() {
|
||||||
@@ -586,6 +633,8 @@ class HomeMenuFragment : Fragment() {
|
|||||||
|
|
||||||
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)
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import com.ckkj.defense_device.liveVideo.LinkedUserActivity
|
|||||||
import com.ckkj.defense_device.personal.FaceManagementActivity
|
import com.ckkj.defense_device.personal.FaceManagementActivity
|
||||||
import com.ckkj.defense_device.personal.PasswordManagementActivity
|
import com.ckkj.defense_device.personal.PasswordManagementActivity
|
||||||
import com.ckkj.defense_device.personal.PersonalProfileActivity
|
import com.ckkj.defense_device.personal.PersonalProfileActivity
|
||||||
|
import com.ckkj.defense_device.personal.SettingsMenusActivity
|
||||||
import com.ckkj.defense_device.utils.AppLanguage
|
import com.ckkj.defense_device.utils.AppLanguage
|
||||||
import com.ckkj.defense_device.utils.LanguageUtil
|
import com.ckkj.defense_device.utils.LanguageUtil
|
||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
@@ -52,7 +53,7 @@ class PersonalFragment : Fragment() {
|
|||||||
.load("")
|
.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()
|
||||||
@@ -132,6 +133,10 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
dialog.show(childFragmentManager, "logout_dialog")
|
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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -184,6 +184,7 @@ class AlarmLogActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Log.e("AlarmLogActivity", "请求异常: ${e.message}", e)
|
Log.e("AlarmLogActivity", "请求异常: ${e.message}", e)
|
||||||
|
showAlarmListNetworkError()
|
||||||
} finally {
|
} finally {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
Log.d("AlarmLogActivity", "请求结束")
|
Log.d("AlarmLogActivity", "请求结束")
|
||||||
@@ -191,14 +192,22 @@ class AlarmLogActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showEmptyView() {
|
private fun updateAlarmListState() {
|
||||||
|
if (alarmList.isEmpty()) {
|
||||||
binding.alarmListRecyclerView.visibility = View.GONE
|
binding.alarmListRecyclerView.visibility = View.GONE
|
||||||
binding.emptyLayout.visibility = View.VISIBLE
|
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 hideEmptyView() {
|
private fun showAlarmListNetworkError() {
|
||||||
binding.alarmListRecyclerView.visibility = View.VISIBLE
|
binding.alarmListRecyclerView.visibility = View.GONE
|
||||||
binding.emptyLayout.visibility = View.GONE
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun filterAlarmListByDate(selectedDate: Calendar) {
|
private fun filterAlarmListByDate(selectedDate: Calendar) {
|
||||||
@@ -216,12 +225,11 @@ class AlarmLogActivity : AppCompatActivity() {
|
|||||||
Log.d("AlarmLogActivity", "日期筛选完成,筛选后条数: ${alarmList.size}")
|
Log.d("AlarmLogActivity", "日期筛选完成,筛选后条数: ${alarmList.size}")
|
||||||
|
|
||||||
if (alarmList.isEmpty()) {
|
if (alarmList.isEmpty()) {
|
||||||
showEmptyView()
|
|
||||||
currentAlarmItem = null
|
currentAlarmItem = null
|
||||||
} else {
|
} else {
|
||||||
hideEmptyView()
|
|
||||||
currentAlarmItem = alarmList.firstOrNull()
|
currentAlarmItem = alarmList.firstOrNull()
|
||||||
}
|
}
|
||||||
|
updateAlarmListState()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDateDisplay() {
|
private fun updateDateDisplay() {
|
||||||
@@ -407,7 +415,7 @@ class AlarmLogActivity : AppCompatActivity() {
|
|||||||
adapter?.notifyDataSetChanged()
|
adapter?.notifyDataSetChanged()
|
||||||
currentAlarmItem = alarmList.firstOrNull()
|
currentAlarmItem = alarmList.firstOrNull()
|
||||||
if (alarmList.isEmpty()) {
|
if (alarmList.isEmpty()) {
|
||||||
showEmptyView()
|
showAlarmListNetworkError()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(this@AlarmLogActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AlarmLogActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.content.res.Configuration
|
|||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
@@ -20,8 +21,14 @@ import com.gyf.immersionbar.ImmersionBar
|
|||||||
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
|
||||||
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
import com.shuyu.gsyvideoplayer.listener.GSYSampleCallBack
|
||||||
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
import com.shuyu.gsyvideoplayer.utils.OrientationUtils
|
||||||
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import androidx.lifecycle.lifecycleScope
|
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() {
|
class LiveVideoActivity : BaseActivity() {
|
||||||
private lateinit var binding: LiveVideoActivityBinding
|
private lateinit var binding: LiveVideoActivityBinding
|
||||||
@@ -30,6 +37,7 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
private var isLightOn = false
|
private var isLightOn = false
|
||||||
private var isConsoleVisible = false
|
private var isConsoleVisible = false
|
||||||
private var deviceId: String? = null
|
private var deviceId: String? = null
|
||||||
|
private var deviceNo: String? = null
|
||||||
private var alarmList: MutableList<DeviceAlarmBean> = mutableListOf()
|
private var alarmList: MutableList<DeviceAlarmBean> = mutableListOf()
|
||||||
private var alarmAdapter: AlarmLogHorizontalAdapter? = null
|
private var alarmAdapter: AlarmLogHorizontalAdapter? = null
|
||||||
private var currentPage = 1
|
private var currentPage = 1
|
||||||
@@ -39,6 +47,9 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
private var isLoading = false
|
private var isLoading = false
|
||||||
|
|
||||||
private var orientationUtils: OrientationUtils? = null
|
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?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -54,6 +65,8 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
|
|
||||||
deviceId = intent.getStringExtra("device_id")
|
deviceId = intent.getStringExtra("device_id")
|
||||||
val deviceName = intent.getStringExtra("device_name")
|
val deviceName = intent.getStringExtra("device_name")
|
||||||
|
deviceNo = intent.getStringExtra("deviceNo")
|
||||||
|
val light = intent.getStringExtra("light")
|
||||||
if (!deviceName.isNullOrEmpty()) {
|
if (!deviceName.isNullOrEmpty()) {
|
||||||
binding.tvTitle.text = deviceName
|
binding.tvTitle.text = deviceName
|
||||||
}
|
}
|
||||||
@@ -80,15 +93,41 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initVideoPlayer() {
|
private fun initVideoPlayer() {
|
||||||
val videoUrl ="http://220.203.23.195:9090/live/test001.live.flv"
|
|
||||||
|
|
||||||
orientationUtils = OrientationUtils(this, binding.exoPlayContextId)
|
orientationUtils = OrientationUtils(this, binding.exoPlayContextId)
|
||||||
orientationUtils?.isEnable = true
|
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()
|
GSYVideoOptionBuilder()
|
||||||
.setUrl(videoUrl)
|
.setUrl(videoUrl)
|
||||||
.setCacheWithPlay(false)
|
.setCacheWithPlay(false)
|
||||||
.setCacheWithPlay(false)
|
|
||||||
.setRotateViewAuto(true)
|
.setRotateViewAuto(true)
|
||||||
.setLockLand(false)
|
.setLockLand(false)
|
||||||
.setShowFullAnimation(true)
|
.setShowFullAnimation(true)
|
||||||
@@ -103,19 +142,31 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
|
override fun onQuitFullscreen(url: String?, vararg objects: Any?) {
|
||||||
super.onQuitFullscreen(url, *objects)
|
super.onQuitFullscreen(url, *objects)
|
||||||
|
|
||||||
orientationUtils?.backToProtVideo()
|
orientationUtils?.backToProtVideo()
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
.build(binding.exoPlayContextId)
|
.build(binding.exoPlayContextId)
|
||||||
hidePlayerControls()
|
|
||||||
binding.exoPlayContextId.startPlayLogic()
|
binding.exoPlayContextId.startPlayLogic()
|
||||||
binding.exoPlayContextId.fullscreenButton.setOnClickListener {
|
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()
|
orientationUtils?.resolveByClick()
|
||||||
binding.exoPlayContextId.startWindowFullscreen(this, true, true)
|
binding.exoPlayContextId.startWindowFullscreen(this, true, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
private fun hidePlayerControls() {
|
private fun hidePlayerControls() {
|
||||||
binding.exoPlayContextId.backButton.visibility = View.GONE
|
binding.exoPlayContextId.backButton.visibility = View.GONE
|
||||||
@@ -237,6 +288,114 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
binding.ivVoice.setImageResource(R.mipmap.voice)
|
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) {
|
private fun fetchAlarmList(page: Int = 1) {
|
||||||
@@ -264,14 +423,35 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
alarmList.addAll(newData)
|
alarmList.addAll(newData)
|
||||||
alarmAdapter?.notifyDataSetChanged()
|
alarmAdapter?.notifyDataSetChanged()
|
||||||
|
updateAlarmListState()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Log.e("LiveVideoActivity", "请求告警列表失败", e)
|
||||||
hasMore = false
|
hasMore = false
|
||||||
|
showAlarmListNetworkError()
|
||||||
} finally {
|
} finally {
|
||||||
isLoading = false
|
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() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
binding.exoPlayContextId.onVideoResume()
|
binding.exoPlayContextId.onVideoResume()
|
||||||
@@ -284,7 +464,21 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
ptzHandler.removeCallbacksAndMessages(null)
|
||||||
orientationUtils?.releaseListener()
|
orientationUtils?.releaseListener()
|
||||||
binding.exoPlayContextId.release()
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
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
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
setupClickListeners()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupClickListeners() {
|
||||||
|
// 返回按钮
|
||||||
|
binding.ivBack.setOnClickListener {
|
||||||
|
finish()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查更新
|
||||||
|
binding.itemCheckUpdate.setOnClickListener {
|
||||||
|
Toast.makeText(this, "正在检查更新...", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清除缓存
|
||||||
|
binding.itemClearCache.setOnClickListener {
|
||||||
|
Toast.makeText(this, "缓存已清除", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.tvCacheSize.text = "0 KB"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 用户协议
|
||||||
|
binding.itemUserAgreement.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 隐私政策
|
||||||
|
binding.itemPrivacyPolicy.setOnClickListener {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 注销账号
|
||||||
|
binding.itemLogout.setOnClickListener {
|
||||||
|
val intent = Intent(this, CancelAccountActivity::class.java)
|
||||||
|
startActivity(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -28,6 +28,8 @@ import com.ckkj.defense_device.bean.UpdateUserInfo
|
|||||||
import com.ckkj.defense_device.bean.UploadResponse
|
import com.ckkj.defense_device.bean.UploadResponse
|
||||||
import com.ckkj.defense_device.bean.UserInfoBean
|
import com.ckkj.defense_device.bean.UserInfoBean
|
||||||
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
|
import com.ckkj.defense_device.bean.VideoStreamInfo
|
||||||
|
import com.ckkj.defense_device.bean.VideoStreamRequest
|
||||||
import okhttp3.MultipartBody
|
import okhttp3.MultipartBody
|
||||||
import retrofit2.http.Body
|
import retrofit2.http.Body
|
||||||
import retrofit2.http.DELETE
|
import retrofit2.http.DELETE
|
||||||
@@ -271,5 +273,79 @@ interface ApiService {
|
|||||||
@POST("/app/joinTheFamily")
|
@POST("/app/joinTheFamily")
|
||||||
suspend fun joinTheFamily(@Body request: JoinTheFamilyBean): GetCodeBean<Any>
|
suspend fun joinTheFamily(@Body request: JoinTheFamilyBean): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ向上控制
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/up")
|
||||||
|
suspend fun ptzUp(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
@Query("speed") speed: String = "5",
|
||||||
|
@Query("duration") duration: String = "0"
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ向下控制
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/down")
|
||||||
|
suspend fun ptzDown(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
@Query("speed") speed: String = "5",
|
||||||
|
@Query("duration") duration: String = "0"
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ向左控制
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/left")
|
||||||
|
suspend fun ptzLeft(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
@Query("speed") speed: String = "5",
|
||||||
|
@Query("duration") duration: String = "0"
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ向右控制
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/right")
|
||||||
|
suspend fun ptzRight(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
@Query("speed") speed: String = "5",
|
||||||
|
@Query("duration") duration: String = "0"
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ停止控制
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/stop")
|
||||||
|
suspend fun ptzStop(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* PTZ控制水枪喷水
|
||||||
|
*/
|
||||||
|
@POST("/app/ptz/{deviceNo}/shoot")
|
||||||
|
suspend fun ptzShoot(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String,
|
||||||
|
@Query("duration") duration: String,
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 开始推流
|
||||||
|
*/
|
||||||
|
@POST("/app/stream/start")
|
||||||
|
suspend fun videoStart(
|
||||||
|
@Body request: VideoStreamRequest
|
||||||
|
): GetCodeBean<VideoStreamInfo>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 停止推流
|
||||||
|
*/
|
||||||
|
@POST("/app/stream/stop/{deviceNo}")
|
||||||
|
suspend fun videoStop(
|
||||||
|
@retrofit2.http.Path("deviceNo") deviceNo: String
|
||||||
|
): GetCodeBean<Any>
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import java.util.concurrent.TimeUnit
|
|||||||
object RetrofitNetwork {
|
object RetrofitNetwork {
|
||||||
|
|
||||||
private const val DEFAULT_TIMEOUT = 30L
|
private const val DEFAULT_TIMEOUT = 30L
|
||||||
const val BASE_URL = "https://stem-boozy-margarine.ngrok-free.dev"
|
//const val BASE_URL = "https://stem-boozy-margarine.ngrok-free.dev"
|
||||||
//const val BASE_URL = "http://service.reinkun.com:8001"
|
const val BASE_URL = "http://service.reinkun.com:8001"
|
||||||
|
|
||||||
private var retrofit: Retrofit? = null
|
private var retrofit: Retrofit? = null
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import android.app.Dialog
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.drawable.ColorDrawable
|
import android.graphics.drawable.ColorDrawable
|
||||||
|
import android.os.Handler
|
||||||
|
import android.os.Looper
|
||||||
import android.view.Gravity
|
import android.view.Gravity
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.WindowManager
|
import android.view.WindowManager
|
||||||
@@ -13,6 +15,13 @@ class LoadingDialog(context: Context) {
|
|||||||
|
|
||||||
private val dialog: Dialog = Dialog(context)
|
private val dialog: Dialog = Dialog(context)
|
||||||
private val binding: DialogLoadingBinding
|
private val binding: DialogLoadingBinding
|
||||||
|
private val handler = Handler(Looper.getMainLooper())
|
||||||
|
private var showTime: Long = 0
|
||||||
|
private val dismissRunnable = Runnable {
|
||||||
|
if (dialog.isShowing) {
|
||||||
|
dialog.dismiss()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
|
binding = DialogLoadingBinding.inflate(LayoutInflater.from(context))
|
||||||
@@ -35,15 +44,24 @@ class LoadingDialog(context: Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun show() {
|
fun show() {
|
||||||
|
handler.removeCallbacks(dismissRunnable)
|
||||||
|
showTime = System.currentTimeMillis()
|
||||||
if (!dialog.isShowing) {
|
if (!dialog.isShowing) {
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun dismiss() {
|
fun dismiss() {
|
||||||
|
handler.removeCallbacks(dismissRunnable)
|
||||||
|
val elapsed = System.currentTimeMillis() - showTime
|
||||||
|
val MIN_SHOW_TIME = 1000L
|
||||||
|
if (elapsed >= MIN_SHOW_TIME) {
|
||||||
if (dialog.isShowing) {
|
if (dialog.isShowing) {
|
||||||
dialog.dismiss()
|
dialog.dismiss()
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
handler.postDelayed(dismissRunnable, MIN_SHOW_TIME - elapsed)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun isShowing(): Boolean {
|
fun isShowing(): Boolean {
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
package com.ckkj.defense_device.view
|
package com.ckkj.defense_device.view
|
||||||
|
|
||||||
|
import android.util.Log
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
|
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
|
||||||
@@ -12,6 +14,18 @@ class MyGSYVideoPlayerLive @JvmOverloads constructor(
|
|||||||
context: Context, attrs: AttributeSet? = null
|
context: Context, attrs: AttributeSet? = null
|
||||||
) : StandardGSYVideoPlayer(context, attrs) {
|
) : StandardGSYVideoPlayer(context, attrs) {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "MyGSYVideoPlayerLive"
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnPtzControlListener {
|
||||||
|
fun onStartPtz(direction: String)
|
||||||
|
fun onStopPtz()
|
||||||
|
fun onShoot()
|
||||||
|
}
|
||||||
|
|
||||||
|
var onPtzControlListener: OnPtzControlListener? = null
|
||||||
|
|
||||||
override fun init(context: Context) {
|
override fun init(context: Context) {
|
||||||
super.init(context)
|
super.init(context)
|
||||||
startButton.visibility = View.GONE
|
startButton.visibility = View.GONE
|
||||||
@@ -76,10 +90,54 @@ class MyGSYVideoPlayerLive @JvmOverloads constructor(
|
|||||||
|
|
||||||
overlay.findViewById<View>(R.id.btnCapture)
|
overlay.findViewById<View>(R.id.btnCapture)
|
||||||
?.setOnClickListener {
|
?.setOnClickListener {
|
||||||
|
Log.d("LV", "btnCapture clicked, onShoot invoked")
|
||||||
|
onPtzControlListener?.onShoot()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
player.initPtzControls(overlay)
|
||||||
|
|
||||||
return player
|
return player
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun initPtzControls(overlay: View) {
|
||||||
|
val ptzListener = onPtzControlListener
|
||||||
|
|
||||||
|
overlay.findViewById<View>(R.id.ivUp)?.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(v, event, "up", ptzListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay.findViewById<View>(R.id.ivDown)?.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(v, event, "down", ptzListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay.findViewById<View>(R.id.ivLeft)?.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(v, event, "left", ptzListener)
|
||||||
|
}
|
||||||
|
|
||||||
|
overlay.findViewById<View>(R.id.ivRight)?.setOnTouchListener { v, event ->
|
||||||
|
handlePtzTouch(v, event, "right", ptzListener)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handlePtzTouch(
|
||||||
|
view: View,
|
||||||
|
event: MotionEvent,
|
||||||
|
direction: String,
|
||||||
|
listener: OnPtzControlListener?
|
||||||
|
): Boolean {
|
||||||
|
when (event.action) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
Log.d(TAG, "全屏PTZ长按开始 direction=$direction")
|
||||||
|
view.isPressed = true
|
||||||
|
listener?.onStartPtz(direction)
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
|
Log.d(TAG, "全屏PTZ长按结束 direction=$direction")
|
||||||
|
view.isPressed = false
|
||||||
|
listener?.onStopPtz()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,288 @@
|
|||||||
|
package com.ckkj.defense_device.view
|
||||||
|
|
||||||
|
import android.animation.ValueAnimator
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import android.view.LayoutInflater
|
||||||
|
import android.view.MotionEvent
|
||||||
|
import android.view.View
|
||||||
|
import android.view.ViewConfiguration
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import android.view.animation.LinearInterpolator
|
||||||
|
import android.widget.ImageView
|
||||||
|
import android.widget.TextView
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 自定义下拉刷新控件
|
||||||
|
*下拉时列表跟随向下移动,顶部出现 Logo + 文字下拉头。
|
||||||
|
*
|
||||||
|
* 使用方式:直接包裹 RecyclerView 等可滚动子 View,调用 [setOnRefreshListener] 监听刷新。
|
||||||
|
*/
|
||||||
|
class PullRefreshLayout @JvmOverloads constructor(
|
||||||
|
context: Context,
|
||||||
|
attrs: AttributeSet? = null,
|
||||||
|
defStyleAttr: Int = 0
|
||||||
|
) : ViewGroup(context, attrs, defStyleAttr) {
|
||||||
|
|
||||||
|
private val touchSlop = ViewConfiguration.get(context).scaledTouchSlop
|
||||||
|
|
||||||
|
/** 触发刷新的下拉阈值(Header 的高度) */
|
||||||
|
private val headerHeight: Int = dp(120)
|
||||||
|
|
||||||
|
/** 触发刷新的最大下拉距离(Header 高度的 1.5 倍) */
|
||||||
|
private val maxPullDistance: Int = (headerHeight * 1.5f).toInt()
|
||||||
|
|
||||||
|
private var headerView: View
|
||||||
|
private val ivRefreshIcon: ImageView
|
||||||
|
private val tvHint: TextView
|
||||||
|
|
||||||
|
/** 子内容 View(通常是 RecyclerView) */
|
||||||
|
private var contentView: View? = null
|
||||||
|
|
||||||
|
private var downY = 0f
|
||||||
|
private var isDragging = false
|
||||||
|
|
||||||
|
/** 当前下拉偏移量(>= 0) */
|
||||||
|
private var currentOffset = 0f
|
||||||
|
|
||||||
|
/** 是否处于刷新状态 */
|
||||||
|
private var isRefreshing = false
|
||||||
|
set(value) {
|
||||||
|
if (field == value) return
|
||||||
|
field = value
|
||||||
|
if (value) {
|
||||||
|
startLoadingAnimation()
|
||||||
|
} else {
|
||||||
|
stopLoadingAnimation()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private var refreshListener: OnRefreshListener? = null
|
||||||
|
private var resetAnimator: ValueAnimator? = null
|
||||||
|
|
||||||
|
init {
|
||||||
|
clipToPadding = false
|
||||||
|
// 添加 Header 视图
|
||||||
|
headerView = LayoutInflater.from(context).inflate(R.layout.layout_refresh_header, this, false)
|
||||||
|
addView(headerView)
|
||||||
|
ivRefreshIcon = headerView.findViewById(R.id.ivRefreshIcon)
|
||||||
|
tvHint = headerView.findViewById(R.id.tvRefreshHint)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
val width = MeasureSpec.getSize(widthMeasureSpec)
|
||||||
|
val height = MeasureSpec.getSize(heightMeasureSpec)
|
||||||
|
|
||||||
|
// 测量 Header
|
||||||
|
val headerHeightSpec = MeasureSpec.makeMeasureSpec(headerHeight, MeasureSpec.EXACTLY)
|
||||||
|
headerView.measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
||||||
|
headerHeightSpec
|
||||||
|
)
|
||||||
|
|
||||||
|
// 测量内容 View(仅第一个非 Header 子 View)
|
||||||
|
for (i in 0 until childCount) {
|
||||||
|
val child = getChildAt(i)
|
||||||
|
if (child === headerView) continue
|
||||||
|
child.measure(
|
||||||
|
MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY),
|
||||||
|
MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY)
|
||||||
|
)
|
||||||
|
contentView = child
|
||||||
|
}
|
||||||
|
setMeasuredDimension(width, height)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onLayout(changed: Boolean, l: Int, t: Int, r: Int, b: Int) {
|
||||||
|
// Header 布局在容器顶部之上(初始隐藏,下拉时滑入)
|
||||||
|
headerView.layout(
|
||||||
|
0,
|
||||||
|
-headerHeight + currentOffset.toInt(),
|
||||||
|
width,
|
||||||
|
currentOffset.toInt()
|
||||||
|
)
|
||||||
|
|
||||||
|
// 内容 View 跟随偏移
|
||||||
|
contentView?.layout(
|
||||||
|
0,
|
||||||
|
currentOffset.toInt(),
|
||||||
|
width,
|
||||||
|
height + currentOffset.toInt()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onInterceptTouchEvent(ev: MotionEvent): Boolean {
|
||||||
|
if (isRefreshing) return false
|
||||||
|
|
||||||
|
when (ev.actionMasked) {
|
||||||
|
MotionEvent.ACTION_DOWN -> {
|
||||||
|
downY = ev.y
|
||||||
|
isDragging = false
|
||||||
|
cancelResetAnimator()
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val dy = ev.y - downY
|
||||||
|
if (dy > touchSlop && canPullDown()) {
|
||||||
|
isDragging = true
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
|
isDragging = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTouchEvent(ev: MotionEvent): Boolean {
|
||||||
|
if (isRefreshing) return false
|
||||||
|
|
||||||
|
when (ev.actionMasked) {
|
||||||
|
MotionEvent.ACTION_MOVE -> {
|
||||||
|
val dy = ev.y - downY
|
||||||
|
if (dy > 0) {
|
||||||
|
if (!isDragging) {
|
||||||
|
if (dy > touchSlop) {
|
||||||
|
isDragging = true
|
||||||
|
} else {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 添加阻尼效果:越往下拉越吃力
|
||||||
|
val damped = computePullOffset(dy)
|
||||||
|
currentOffset = damped.coerceAtMost(maxPullDistance.toFloat())
|
||||||
|
updateHeaderState()
|
||||||
|
requestLayout()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MotionEvent.ACTION_UP, MotionEvent.ACTION_CANCEL -> {
|
||||||
|
if (currentOffset >= headerHeight * 0.9f) {
|
||||||
|
// 触发刷新
|
||||||
|
triggerRefresh()
|
||||||
|
} else {
|
||||||
|
// 回弹
|
||||||
|
resetToIdle()
|
||||||
|
}
|
||||||
|
isDragging = false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return isDragging
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加阻尼效果,让下拉越深越慢,模拟弹性手感
|
||||||
|
*/
|
||||||
|
private fun computePullOffset(rawDy: Float): Float {
|
||||||
|
// 原始距离的 0.5 倍为基本偏移,超过阈值后逐渐衰减
|
||||||
|
val resistance = 1.8f
|
||||||
|
return (rawDy / resistance).coerceAtMost(maxPullDistance.toFloat())
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 判断是否可以从当前位置下拉(列表已经滚动到顶部)
|
||||||
|
*/
|
||||||
|
private fun canPullDown(): Boolean {
|
||||||
|
val content = contentView ?: return false
|
||||||
|
return !content.canScrollVertically(-1)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据下拉距离更新 Header 的视觉状态(旋转角度、提示文字)
|
||||||
|
*/
|
||||||
|
private fun updateHeaderState() {
|
||||||
|
val ratio = (currentOffset / headerHeight).coerceIn(0f, 1f)
|
||||||
|
|
||||||
|
// 刷新图标根据下拉比例旋转 0~360 度
|
||||||
|
ivRefreshIcon.rotation = ratio * 360f
|
||||||
|
|
||||||
|
// 文字提示
|
||||||
|
tvHint.text = when {
|
||||||
|
currentOffset >= headerHeight * 0.9f -> context.getString(R.string.refresh_hint_release)
|
||||||
|
else -> context.getString(R.string.refresh_hint_pull)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun triggerRefresh() {
|
||||||
|
// 平滑动画到 header 高度
|
||||||
|
val animator = ValueAnimator.ofFloat(currentOffset, headerHeight.toFloat())
|
||||||
|
animator.duration = 200L
|
||||||
|
animator.interpolator = LinearInterpolator()
|
||||||
|
animator.addUpdateListener {
|
||||||
|
currentOffset = it.animatedValue as Float
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
animator.start()
|
||||||
|
resetAnimator = animator
|
||||||
|
|
||||||
|
isRefreshing = true
|
||||||
|
tvHint.text = context.getString(R.string.refresh_hint_refreshing)
|
||||||
|
refreshListener?.onRefresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 结束刷新并回弹
|
||||||
|
*/
|
||||||
|
fun finishRefresh() {
|
||||||
|
if (!isRefreshing) return
|
||||||
|
isRefreshing = false
|
||||||
|
resetToIdle()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun resetToIdle() {
|
||||||
|
cancelResetAnimator()
|
||||||
|
val animator = ValueAnimator.ofFloat(currentOffset, 0f)
|
||||||
|
animator.duration = 300L
|
||||||
|
animator.interpolator = LinearInterpolator()
|
||||||
|
animator.addUpdateListener {
|
||||||
|
currentOffset = it.animatedValue as Float
|
||||||
|
if (!isRefreshing) {
|
||||||
|
// 刷新结束后,重置图标旋转角度
|
||||||
|
ivRefreshIcon.rotation = 0f
|
||||||
|
tvHint.text = context.getString(R.string.refresh_hint_pull)
|
||||||
|
}
|
||||||
|
requestLayout()
|
||||||
|
}
|
||||||
|
animator.start()
|
||||||
|
resetAnimator = animator
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun cancelResetAnimator() {
|
||||||
|
resetAnimator?.cancel()
|
||||||
|
resetAnimator = null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startLoadingAnimation() {
|
||||||
|
// 持续旋转动画
|
||||||
|
ivRefreshIcon.animate()
|
||||||
|
.rotation(ivRefreshIcon.rotation + 360f)
|
||||||
|
.setDuration(800L)
|
||||||
|
.setInterpolator(LinearInterpolator())
|
||||||
|
.withEndAction {
|
||||||
|
if (isRefreshing) startLoadingAnimation()
|
||||||
|
}
|
||||||
|
.start()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun stopLoadingAnimation() {
|
||||||
|
ivRefreshIcon.animate().cancel()
|
||||||
|
ivRefreshIcon.rotation = 0f
|
||||||
|
tvHint.text = context.getString(R.string.refresh_hint_pull)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setOnRefreshListener(listener: OnRefreshListener) {
|
||||||
|
this.refreshListener = listener
|
||||||
|
}
|
||||||
|
|
||||||
|
interface OnRefreshListener {
|
||||||
|
fun onRefresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dp(value: Int): Int {
|
||||||
|
val density = resources.displayMetrics.density
|
||||||
|
return (value * density).toInt()
|
||||||
|
}
|
||||||
|
}
|
||||||
15
app/src/main/res/drawable/btn_selector_red.xml
Normal file
15
app/src/main/res/drawable/btn_selector_red.xml
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<item android:state_pressed="true">
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#CC3D49" />
|
||||||
|
<corners android:radius="25dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<shape>
|
||||||
|
<solid android:color="#E34D59" />
|
||||||
|
<corners android:radius="25dp" />
|
||||||
|
</shape>
|
||||||
|
</item>
|
||||||
|
</selector>
|
||||||
10
app/src/main/res/drawable/ic_warning.xml
Normal file
10
app/src/main/res/drawable/ic_warning.xml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="24dp"
|
||||||
|
android:height="24dp"
|
||||||
|
android:viewportWidth="24"
|
||||||
|
android:viewportHeight="24">
|
||||||
|
<path
|
||||||
|
android:fillColor="#E34D59"
|
||||||
|
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-2h2v2zM13,13h-2L11,7h2v6z"/>
|
||||||
|
</vector>
|
||||||
@@ -42,8 +42,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/white"
|
android:background="@color/white"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingVertical="12dp"
|
android:paddingVertical="12dp">
|
||||||
android:layout_marginTop="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -102,7 +102,7 @@
|
|||||||
android:background="#FFFFFF" />
|
android:background="#FFFFFF" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/emptyLayout"
|
android:id="@+id/layoutNoPermission"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"
|
android:layout_weight="1"
|
||||||
@@ -116,6 +116,22 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:src="@drawable/no_message" />
|
android:src="@drawable/no_message" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="#FFFFFF"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@mipmap/no_network_img_name" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -36,10 +36,6 @@
|
|||||||
android:layout_height="24dp" />
|
android:layout_height="24dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
android:background="@color/face" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
|
|||||||
153
app/src/main/res/layout/cancel_account_activity.xml
Normal file
153
app/src/main/res/layout/cancel_account_activity.xml
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:orientation="vertical"
|
||||||
|
tools:context=".personal.CancelAccountActivity">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivBack"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@mipmap/back"
|
||||||
|
android:contentDescription="@string/back" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/cancel_account"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16dp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ScrollView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:padding="16dp">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/cancel_account_warning_text"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="14sp"
|
||||||
|
android:lineSpacingMultiplier="1.5" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/gray_divider"
|
||||||
|
android:layout_marginVertical="16dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/current_account"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvPhoneNumber"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:textSize="20sp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:layout_marginTop="8dp" />
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1px"
|
||||||
|
android:background="@color/gray_divider"
|
||||||
|
android:layout_marginVertical="16dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/verification_code"
|
||||||
|
android:textColor="@color/text_secondary"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
|
||||||
|
<RelativeLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:background="@drawable/textinput_white_bg">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/etVerificationCode"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_toLeftOf="@+id/btnSendCode"
|
||||||
|
android:hint="@string/enter_verification_code"
|
||||||
|
android:inputType="number"
|
||||||
|
android:paddingHorizontal="16dp"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:background="@null"
|
||||||
|
android:textColorHint="@color/gray"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
|
||||||
|
<android.widget.Button
|
||||||
|
android:id="@+id/btnSendCode"
|
||||||
|
android:layout_width="110dp"
|
||||||
|
android:layout_height="36dp"
|
||||||
|
android:minWidth="0dp"
|
||||||
|
android:minHeight="0dp"
|
||||||
|
android:layout_alignParentRight="true"
|
||||||
|
android:layout_centerVertical="true"
|
||||||
|
android:layout_marginRight="8dp"
|
||||||
|
android:background="@drawable/send_code_btn_selector"
|
||||||
|
android:text="@string/send_sms_code"
|
||||||
|
android:textColor="@color/send_code_text_color"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
android:gravity="center"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</RelativeLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
</ScrollView>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:padding="16dp"
|
||||||
|
android:background="@color/white">
|
||||||
|
|
||||||
|
<android.widget.Button
|
||||||
|
android:id="@+id/btnCancelAccount"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:background="@drawable/btn_selector_red"
|
||||||
|
android:text="@string/cancel_account_btn"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
android:textSize="16sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="16dp"
|
android:layout_marginTop="16dp"
|
||||||
android:text="@string/uploading"
|
android:text="@string/uploading"
|
||||||
android:textColor="@color/black"
|
android:textColor="@color/green"
|
||||||
android:textSize="16sp"/>
|
android:textSize="16sp"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -134,7 +134,7 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<com.ckkj.defense_device.view.PullRefreshLayout
|
||||||
android:id="@+id/swipeRefreshLayout"
|
android:id="@+id/swipeRefreshLayout"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_marginLeft="12dp"
|
android:layout_marginLeft="12dp"
|
||||||
@@ -152,11 +152,11 @@
|
|||||||
android:layout_marginTop="8dp"
|
android:layout_marginTop="8dp"
|
||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:clipToPadding="false"
|
android:clipToPadding="false"
|
||||||
android:nestedScrollingEnabled="false"
|
android:overScrollMode="never"
|
||||||
android:paddingBottom="16dp"
|
android:paddingBottom="16dp"
|
||||||
android:background="@android:color/transparent"
|
android:background="@android:color/transparent"
|
||||||
tools:listitem="@layout/item_device" />
|
tools:listitem="@layout/item_device" />
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</com.ckkj.defense_device.view.PullRefreshLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/layoutNoPermission"
|
android:id="@+id/layoutNoPermission"
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
android:id="@+id/llExpireTime"
|
android:id="@+id/llExpireTime"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="56dp"
|
android:layout_height="56dp"
|
||||||
android:layout_marginTop="8dp"
|
|
||||||
android:background="@color/white"
|
android:background="@color/white"
|
||||||
android:gravity="center_vertical"
|
android:gravity="center_vertical"
|
||||||
android:paddingHorizontal="16dp">
|
android:paddingHorizontal="16dp">
|
||||||
|
|||||||
24
app/src/main/res/layout/layout_refresh_header.xml
Normal file
24
app/src/main/res/layout/layout_refresh_header.xml
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingTop="24dp"
|
||||||
|
android:paddingBottom="20dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivRefreshIcon"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@mipmap/setting" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvRefreshHint"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="10dp"
|
||||||
|
android:text="@string/refresh_hint_pull"
|
||||||
|
android:textColor="@color/green"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
</LinearLayout>
|
||||||
@@ -48,8 +48,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:background="@color/white"
|
android:background="@color/white"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingVertical="12dp"
|
android:paddingVertical="12dp">
|
||||||
android:layout_marginTop="8dp">
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
@@ -252,6 +252,39 @@
|
|||||||
android:background="#FFFFFF"
|
android:background="#FFFFFF"
|
||||||
android:paddingTop="8dp" />
|
android:paddingTop="8dp" />
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoPermission"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="244dp"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
android:src="@mipmap/no_message" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="200dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
android:background="@color/white"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="244dp"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
android:src="@mipmap/no_network_img_name" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -70,6 +70,15 @@
|
|||||||
android:textColor="#666666"
|
android:textColor="#666666"
|
||||||
android:textSize="16dp" />
|
android:textSize="16dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_marginLeft="5dp"
|
||||||
|
android:id="@+id/ivMenu"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_gravity="center_vertical|top"
|
||||||
|
android:src="@mipmap/settings"/>
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
@@ -35,18 +35,16 @@
|
|||||||
android:layout_height="24dp" />
|
android:layout_height="24dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
android:background="@color/face" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingVertical="12dp"
|
|
||||||
android:text="@string/function_settings"
|
android:text="@string/function_settings"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/black"
|
||||||
|
android:background="@color/message_bg"
|
||||||
|
android:gravity="bottom"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingBottom="7dp"
|
||||||
android:textSize="14dp" />
|
android:textSize="14dp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
@@ -191,18 +189,16 @@
|
|||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
.
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
android:background="@color/face" />
|
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="50dp"
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingVertical="12dp"
|
|
||||||
android:text="@string/basic_settings"
|
android:text="@string/basic_settings"
|
||||||
android:textColor="@color/gray"
|
android:textColor="@color/black"
|
||||||
|
android:background="@color/message_bg"
|
||||||
|
android:gravity="bottom"
|
||||||
|
android:paddingStart="20dp"
|
||||||
|
android:paddingBottom="7dp"
|
||||||
android:textSize="14dp" />
|
android:textSize="14dp" />
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
|||||||
227
app/src/main/res/layout/settings_menus_activity.xml
Normal file
227
app/src/main/res/layout/settings_menus_activity.xml
Normal file
@@ -0,0 +1,227 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@color/white"
|
||||||
|
tools:context=".personal.SettingsMenusActivity">
|
||||||
|
|
||||||
|
<!-- Top Toolbar -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivBack"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:src="@mipmap/back"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/settings_title"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="16dp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Menu List Container -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:background="@android:color/white">
|
||||||
|
|
||||||
|
<!-- 检查更新 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_check_update"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/check_update"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_version"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text=""
|
||||||
|
android:textColor="#999999"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:src="@mipmap/right_back"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="#F0F0F0" />
|
||||||
|
|
||||||
|
<!-- 清除缓存 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_clear_cache"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/clear_cache"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tv_cache_size"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="11Kb"
|
||||||
|
android:textColor="#999999"
|
||||||
|
android:textSize="13sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:src="@mipmap/right_back"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="#F0F0F0" />
|
||||||
|
|
||||||
|
<!-- 用户协议 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_user_agreement"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/user_agreement"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@mipmap/right_back"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="#F0F0F0" />
|
||||||
|
|
||||||
|
<!-- 隐私政策 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_privacy_policy"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/privacy_policy"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@mipmap/right_back" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<View
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="1dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:background="#F0F0F0" />
|
||||||
|
|
||||||
|
<!-- 注销账号 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/item_logout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:paddingHorizontal="16dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:text="@string/cancel_account"
|
||||||
|
android:textSize="15sp" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="20dp"
|
||||||
|
android:layout_height="20dp"
|
||||||
|
android:src="@mipmap/right_back"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<!-- Bottom Contact Text -->
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="24dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="horizontal">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/tip_contact_us"
|
||||||
|
android:textColor="#999999"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="19927623@qq.com"
|
||||||
|
android:textColor="#4A90D9"
|
||||||
|
android:textSize="12sp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
@@ -35,11 +35,6 @@
|
|||||||
android:layout_height="24dp" />
|
android:layout_height="24dp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<View
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="10dp"
|
|
||||||
android:background="@color/face" />
|
|
||||||
|
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/itemDistance"
|
android:id="@+id/itemDistance"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
BIN
app/src/main/res/mipmap-xxxhdpi/setting.png
Normal file
BIN
app/src/main/res/mipmap-xxxhdpi/setting.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 8.6 KiB |
@@ -501,4 +501,22 @@
|
|||||||
<string name="password_update_success">密码修改成功</string>
|
<string name="password_update_success">密码修改成功</string>
|
||||||
<string name="password_update_failed">密码修改失败</string>
|
<string name="password_update_failed">密码修改失败</string>
|
||||||
<string name="update_failed">更新失败</string>
|
<string name="update_failed">更新失败</string>
|
||||||
|
|
||||||
|
<string name="check_update">检查更新</string>
|
||||||
|
<string name="clear_cache">清除缓存</string>
|
||||||
|
<string name="cancel_account">注销账号</string>
|
||||||
|
<string name="tip_contact_us">如有问题,请联系我们:</string>
|
||||||
|
|
||||||
|
<string name="cancel_account_warning_text">注销后无法恢复,请谨慎操作</string>
|
||||||
|
<string name="current_account">当前账号</string>
|
||||||
|
<string name="cancel_account_btn">注销</string>
|
||||||
|
<string name="confirm_cancel_account_user_account">确定注销该用户吗?</string>
|
||||||
|
|
||||||
|
<!-- HomeMenuFragment 列表刷新 -->
|
||||||
|
<string name="no_more_data">没有更多了</string>
|
||||||
|
<string name="refreshing">正在刷新…</string>
|
||||||
|
<string name="refresh_hint_pull">下拉刷新</string>
|
||||||
|
<string name="refresh_hint_release">松开刷新</string>
|
||||||
|
<string name="refresh_hint_refreshing">正在刷新…</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
@@ -23,4 +23,12 @@
|
|||||||
<color name="gradientLayout1">#EBDCED</color>
|
<color name="gradientLayout1">#EBDCED</color>
|
||||||
<color name="gradientLayout2">#CAF4FF</color>
|
<color name="gradientLayout2">#CAF4FF</color>
|
||||||
|
|
||||||
|
<!-- Common Colors -->
|
||||||
|
<color name="primary">#09C2BD</color>
|
||||||
|
<color name="text_primary">#333333</color>
|
||||||
|
<color name="text_secondary">#666666</color>
|
||||||
|
<color name="card_background">#F8F8F8</color>
|
||||||
|
<color name="button_disabled">#CCCCCC</color>
|
||||||
|
<color name="warning_red">#E34D59</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -31,9 +31,7 @@
|
|||||||
<string name="confirm_password">Confirm Password</string>
|
<string name="confirm_password">Confirm Password</string>
|
||||||
<string name="password_requirement">Password must be 6–20 characters</string>
|
<string name="password_requirement">Password must be 6–20 characters</string>
|
||||||
<string name="agreement_prefix">I have read and agree to the</string>
|
<string name="agreement_prefix">I have read and agree to the</string>
|
||||||
<string name="user_agreement">User Agreement</string>
|
|
||||||
<string name="and">and</string>
|
<string name="and">and</string>
|
||||||
<string name="privacy_policy">Privacy Policy</string>
|
|
||||||
<string name="register_success">Registration Successful</string>
|
<string name="register_success">Registration Successful</string>
|
||||||
<string name="registering">Registering...</string>
|
<string name="registering">Registering...</string>
|
||||||
<string name="register_success_message">Your account has been created successfully</string>
|
<string name="register_success_message">Your account has been created successfully</string>
|
||||||
@@ -507,4 +505,25 @@
|
|||||||
<string name="password_update_success">Password updated successfully</string>
|
<string name="password_update_success">Password updated successfully</string>
|
||||||
<string name="password_update_failed">Failed to update password</string>
|
<string name="password_update_failed">Failed to update password</string>
|
||||||
<string name="update_failed">Update failed</string>
|
<string name="update_failed">Update failed</string>
|
||||||
|
|
||||||
|
<!-- Settings Menus -->
|
||||||
|
<string name="check_update">Check for Updates</string>
|
||||||
|
<string name="clear_cache">Clear Cache</string>
|
||||||
|
<string name="cancel_account">Cancel Account</string>
|
||||||
|
<string name="tip_contact_us">If you have any questions, please contact us:</string>
|
||||||
|
<string name="user_agreement">User Agreement</string>
|
||||||
|
<string name="privacy_policy">Privacy Policy</string>
|
||||||
|
|
||||||
|
<!-- Cancel Account -->
|
||||||
|
<string name="cancel_account_warning_text">Account data cannot be restored after cancellation, please proceed with caution</string>
|
||||||
|
<string name="current_account">Current Account</string>
|
||||||
|
<string name="cancel_account_btn">Cancel</string>
|
||||||
|
<string name="confirm_cancel_account_user_account">Confirm Cancel Account User Account</string>
|
||||||
|
|
||||||
|
<!-- Home Menu refresh / load more -->
|
||||||
|
<string name="no_more_data">No more data</string>
|
||||||
|
<string name="refreshing">Refreshing…</string>
|
||||||
|
<string name="refresh_hint_pull">Pull down to refresh</string>
|
||||||
|
<string name="refresh_hint_release">Release to refresh</string>
|
||||||
|
<string name="refresh_hint_refreshing">Refreshing…</string>
|
||||||
</resources>
|
</resources>
|
||||||
Reference in New Issue
Block a user