Compare commits

...

12 Commits

35 changed files with 334 additions and 96 deletions

View File

@@ -4,7 +4,7 @@
<selectionStates>
<SelectionState runConfigName="app">
<option name="selectionMode" value="DROPDOWN" />
<DropdownSelection timestamp="2026-05-18T09:18:19.023586Z">
<DropdownSelection timestamp="2026-06-22T08:46:41.014465400Z">
<Target type="DEFAULT_BOOT">
<handle>
<DeviceId pluginId="PhysicalDevice" identifier="serial=80bece4" />

View File

@@ -0,0 +1,48 @@
kotlin version: 2.2.10
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker16051875768763165132.tmp
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:30)
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -0,0 +1,48 @@
kotlin version: 2.2.10
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3580585840179793220.tmp
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:30)
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -0,0 +1,48 @@
kotlin version: 2.2.10
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker11763075351170172587.tmp
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
at org.gradle.internal.Factories$1.create(Factories.java:30)
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
at java.base/java.lang.Thread.run(Thread.java:1583)

View File

@@ -36,6 +36,11 @@ android {
buildFeatures {
viewBinding=true
}
lint {
disable += "ExpiredTargetSdkVersion"
checkReleaseBuilds = false
abortOnError = false
}
}
dependencies {
@@ -69,14 +74,8 @@ dependencies {
// Kotlin 协程
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3")
// CameraX 用于相机预览
implementation("androidx.camera:camera-camera2:1.3.0")
implementation("androidx.camera:camera-lifecycle:1.3.0")
implementation("androidx.camera:camera-view:1.3.0")
// Google ML Kit 人脸检测
implementation("com.google.mlkit:face-detection:16.1.5")
// 图形绘制库(绘制人脸框)
implementation("com.github.bumptech.glide:glide:4.15.1")
//Glide 依赖
implementation("com.github.bumptech.glide:glide:4.16.0")
// ZXing 二维码扫描库
@@ -87,8 +86,6 @@ dependencies {
implementation("com.geyifeng.immersionbar:immersionbar-ktx:3.2.2")
implementation("com.wdullaer:materialdatetimepicker:4.2.3") // 经典稳定
implementation("androidx.core:core-ktx:1.12.0")
// Android-PickerView 时间选择器
implementation("com.contrarywind:Android-PickerView:4.1.9")
//二维码三方库
implementation("com.github.maning0303:MNMLKitScanner:V1.0.4")
implementation("com.google.mlkit:barcode-scanning:17.0.2")

View File

@@ -0,0 +1,18 @@
package com.ckkj.defense_device.bean
data class InviterInfoBean(
val nickName: String? = null,
val idCard: String? = null,
val phonenumber: String? = null,
val avatar: String? = null,
val id: String? = null,
val parentId: String? = null,
val userId: String? = null,
val mac: String? = null,
val status: String? = null,
) {
fun resolveParentId(): String? =
parentId?.takeIf { it.isNotBlank() }
?: userId?.takeIf { it.isNotBlank() }
?: id?.takeIf { it.isNotBlank() }
}

View File

@@ -7,7 +7,7 @@ import android.content.pm.PackageManager
import android.graphics.Color
import android.os.Build
import android.graphics.Rect
import android.graphics.drawable.GradientDrawable
import android.os.Bundle
import android.util.Log
import android.util.TypedValue
@@ -263,12 +263,7 @@ class HomeMenuFragment : Fragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// 为 LinearLayout 设置渐变背景
setGradientBackground(
view = binding.gradientLayout,
startColor = resources.getColor(R.color.gradientLayout1),
endColor = resources.getColor(R.color.gradientLayout2)
)
binding.gradientLayout.setBackgroundColor(Color.TRANSPARENT)
binding.message.setOnClickListener {
val intent = Intent(requireContext(), MessageActivity::class.java)
startActivity(intent)
@@ -589,17 +584,6 @@ class HomeMenuFragment : Fragment() {
}
}
private fun setGradientBackground(
view: View,
startColor: Int,
endColor: Int,
orientation: GradientDrawable.Orientation = GradientDrawable.Orientation.TL_BR
) {
val gradientDrawable = GradientDrawable(orientation, intArrayOf(startColor, endColor))
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
view.background = gradientDrawable
}
override fun onDestroyView() {
super.onDestroyView()
binding.rvFamilyList.adapter = null

View File

@@ -49,7 +49,7 @@ class PersonalFragment : Fragment() {
.titleBar(binding.headerLayout)
.init()
Glide.with(this)
.load(R.mipmap.img)
.load("")
.circleCrop()
.into(binding.ivAvatar)
binding.headerLayout.setOnClickListener {
@@ -267,6 +267,7 @@ class PersonalFragment : Fragment() {
} else {
getString(R.string.member)
}
binding.tvRoleTag.visibility = View.VISIBLE
}
}

View File

@@ -60,7 +60,9 @@ class SetNameActivity : AppCompatActivity() {
withContext(Dispatchers.Main) {
if (result.code == 200) {
Toast.makeText(this@SetNameActivity, "设备添加成功", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@SetNameActivity, LiveVideoActivity::class.java))
startActivity(Intent(this@SetNameActivity, HomeActivity::class.java).apply {
putExtra(HomeActivity.EXTRA_REFRESH, true)
})
finish()
} else {
Toast.makeText(this@SetNameActivity, result.msg ?: "添加失败", Toast.LENGTH_SHORT).show()

View File

@@ -31,6 +31,7 @@ class AutoModeActivity : AppCompatActivity() {
private var selectedStartMinute = 0
private var selectedEndHour = 10
private var selectedEndMinute = 0
private var optionPassword: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -42,6 +43,8 @@ class AutoModeActivity : AppCompatActivity() {
.titleBar(binding.topBar)
.init()
optionPassword = intent.getStringExtra("optionPassword")
initListener()
loadCurrentSettings()
@@ -177,7 +180,8 @@ class AutoModeActivity : AppCompatActivity() {
id = deviceId,
workMode = selectedMode,
startTime = startTime,
endTime = endTime
endTime = endTime,
optionPassword = optionPassword
)
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
withContext(Dispatchers.Main) {

View File

@@ -27,6 +27,7 @@ class SettingsActivity : BaseActivity() {
private var alertAudio: String? = null
private var audioContent: String? = null
private var isPasswordVerified = false
private var verifiedPassword: String? = null
override fun onResume() {
super.onResume()
@@ -55,15 +56,15 @@ class SettingsActivity : BaseActivity() {
if (isPasswordVerified) {
val dialog = RecognitionModeDialog(this)
dialog.setOnConfirmListener { mode ->
updateRecognitionMode(mode)
updateRecognitionMode(mode, verifiedPassword)
}
dialog.show()
} else {
showPasswordDialog {
showPasswordDialog { inputPassword ->
isPasswordVerified = true
val dialog = RecognitionModeDialog(this)
dialog.setOnConfirmListener { mode ->
updateRecognitionMode(mode)
updateRecognitionMode(mode, inputPassword)
}
dialog.show()
}
@@ -94,22 +95,24 @@ class SettingsActivity : BaseActivity() {
}
binding.itemWaterGunSetting.setOnClickListener {
if (isPasswordVerified) {
navigateToWaterGunSettings()
navigateToWaterGunSettings(verifiedPassword)
} else {
showPasswordDialog {
showPasswordDialog { inputPassword ->
isPasswordVerified = true
navigateToWaterGunSettings()
navigateToWaterGunSettings(inputPassword)
}
}
}
binding.itemAutoMode.setOnClickListener {
if (isPasswordVerified) {
val intent = Intent(this, AutoModeActivity::class.java)
intent.putExtra("optionPassword", verifiedPassword)
startActivity(intent)
} else {
showPasswordDialog {
showPasswordDialog { inputPassword ->
isPasswordVerified = true
val intent = Intent(this, AutoModeActivity::class.java)
intent.putExtra("optionPassword", inputPassword)
startActivity(intent)
}
}
@@ -258,7 +261,7 @@ class SettingsActivity : BaseActivity() {
}
}
private fun updateRecognitionMode(mode: String) {
private fun updateRecognitionMode(mode: String, optionPassword: String?) {
val deviceId = DeviceIdEvent.getDeviceId()
if (deviceId.isNullOrEmpty()) {
Toast.makeText(this, "设备ID为空", Toast.LENGTH_SHORT).show()
@@ -276,6 +279,7 @@ class SettingsActivity : BaseActivity() {
val deviceBean = com.ckkj.defense_device.bean.DeviceBean(
id = deviceId,
patternPerception = patternPerception,
optionPassword = optionPassword
)
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
withContext(Dispatchers.Main) {
@@ -328,7 +332,7 @@ class SettingsActivity : BaseActivity() {
}
}
private fun showPasswordDialog(onVerified: () -> Unit) {
private fun showPasswordDialog(onVerified: (String) -> Unit) {
passwordDialog = PasswordInputDialog(this).apply {
setOnConfirmListener { inputPassword ->
CoroutineScope(Dispatchers.IO).launch {
@@ -338,7 +342,8 @@ class SettingsActivity : BaseActivity() {
withContext(Dispatchers.Main) {
if (response.code == 200) {
dismiss()
onVerified()
verifiedPassword = inputPassword
onVerified(inputPassword)
} else {
Toast.makeText(
this@SettingsActivity,
@@ -365,8 +370,9 @@ class SettingsActivity : BaseActivity() {
passwordDialog.show()
}
private fun navigateToWaterGunSettings() {
private fun navigateToWaterGunSettings(optionPassword: String? = null) {
val intent = Intent(this, WaterGunSettingsActivity::class.java)
intent.putExtra("optionPassword", optionPassword)
val deviceId = DeviceIdEvent.getDeviceId()
if (!deviceId.isNullOrEmpty()) {
CoroutineScope(Dispatchers.IO).launch {

View File

@@ -24,6 +24,7 @@ class WaterGunSettingsActivity : BaseActivity() {
private var currentStrikeRange: String = "7"
private var currentStrikeInterval: String = "3"
private var currentContainer: String = "容器4"
private var optionPassword: String? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -41,6 +42,7 @@ class WaterGunSettingsActivity : BaseActivity() {
currentStrikeRange = intent.getStringExtra("strikeRange") ?: "7"
currentStrikeInterval = intent.getStringExtra("strikeInterval") ?: "3"
currentContainer = intent.getStringExtra("container") ?: "容器4"
optionPassword = intent.getStringExtra("optionPassword")
// 显示初始值
binding.tvDistance.text = "${currentStrikeRange}m"
@@ -100,7 +102,8 @@ class WaterGunSettingsActivity : BaseActivity() {
try {
val deviceBean = DeviceBean(
id = deviceId,
strikeRange = distance
strikeRange = distance,
optionPassword = optionPassword
)
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
withContext(Dispatchers.Main) {
@@ -131,7 +134,8 @@ class WaterGunSettingsActivity : BaseActivity() {
try {
val deviceBean = DeviceBean(
id = deviceId,
strikeInterval = interval
strikeInterval = interval,
optionPassword = optionPassword
)
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
withContext(Dispatchers.Main) {
@@ -162,7 +166,8 @@ class WaterGunSettingsActivity : BaseActivity() {
try {
val deviceBean = DeviceBean(
id = deviceId,
container = container
container = container,
optionPassword = optionPassword
)
val response = RetrofitNetwork.getNetworkService().updateDeviceInfo(deviceBean)
withContext(Dispatchers.Main) {

View File

@@ -108,11 +108,10 @@ class ForgetPasswordActivity : AppCompatActivity() {
* 开始验证码按钮倒计时
*/
private fun startCountDown() {
binding.sendCodeBtn.isEnabled = false
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
override fun onTick(millisUntilFinished: Long) {
val secondsRemaining = (millisUntilFinished / 1000).toInt()
binding.sendCodeBtn.text = "${secondsRemaining}秒后重试"
binding.sendCodeBtn.isEnabled = false
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
}
override fun onFinish() {
@@ -127,7 +126,7 @@ class ForgetPasswordActivity : AppCompatActivity() {
private fun resetSendButton() {
countDownTimer?.cancel()
countDownTimer = null
binding.sendCodeBtn.text = "发送验证码"
binding.sendCodeBtn.text = getString(R.string.resend_code)
binding.sendCodeBtn.isEnabled = true
}

View File

@@ -15,6 +15,7 @@ import bean.LoginRequest
import com.ckkj.defense_device.R
import com.ckkj.defense_device.databinding.ActivityLoginBinding
import com.ckkj.defense_device.home.HomeActivity
import com.ckkj.defense_device.utils.ApiConfig
import com.ckkj.defense_device.utils.RetrofitNetwork
import com.ckkj.defense_device.utils.UserinfoUtil
import com.gyf.immersionbar.ImmersionBar
@@ -27,11 +28,13 @@ class LoginActivity : AppCompatActivity() {
private lateinit var binding: ActivityLoginBinding
private var currentLoginMode = LoginMode.SMS
private var countDownTimer: CountDownTimer? = null
enum class LoginMode { SMS, PASSWORD }
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ApiConfig.resetAuthRedirectFlag()
binding = ActivityLoginBinding.inflate(layoutInflater)
setContentView(binding.root)
@@ -167,25 +170,24 @@ class LoginActivity : AppCompatActivity() {
binding.registerText.setOnClickListener {
val intent= Intent(this, RegisterActivity::class.java)
startActivity(intent)
Toast.makeText(this, R.string.redirect_register_page, Toast.LENGTH_SHORT).show()
}
binding.forgetText.setOnClickListener {
val intent= Intent(this, ForgetPasswordActivity::class.java)
startActivity(intent)
Toast.makeText(this, R.string.forgot_password_page, Toast.LENGTH_SHORT).show()
}
}
private fun startCountDown() {
binding.sendCodeBtn.isEnabled = false
object : CountDownTimer(60000, 1000) {
countDownTimer = object : CountDownTimer(60000, 1000) {
override fun onTick(millisUntilFinished: Long) {
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
}
override fun onFinish() {
binding.sendCodeBtn.text = getString(R.string.send_code)
binding.sendCodeBtn.text = getString(R.string.resend_code)
binding.sendCodeBtn.isEnabled = true
countDownTimer = null
}
}.start()
}
@@ -287,4 +289,10 @@ class LoginActivity : AppCompatActivity() {
gradientDrawable.gradientType = GradientDrawable.LINEAR_GRADIENT
view.background = gradientDrawable
}
override fun onDestroy() {
super.onDestroy()
countDownTimer?.cancel()
countDownTimer = null
}
}

View File

@@ -100,11 +100,10 @@ class RegisterActivity : AppCompatActivity() {
}
private fun startCountDown() {
binding.sendCodeBtn.isEnabled = false
countDownTimer = object : CountDownTimer(COUNTDOWN_DURATION, COUNTDOWN_INTERVAL) {
override fun onTick(millisUntilFinished: Long) {
val secondsRemaining = (millisUntilFinished / 1000).toInt()
binding.sendCodeBtn.text = "${secondsRemaining}秒后重试"
binding.sendCodeBtn.isEnabled = false
binding.sendCodeBtn.text = getString(R.string.countdown_retry, millisUntilFinished / 1000)
}
override fun onFinish() {
@@ -116,7 +115,7 @@ class RegisterActivity : AppCompatActivity() {
private fun resetSendButton() {
countDownTimer?.cancel()
countDownTimer = null
binding.sendCodeBtn.text = getString(R.string.send_code)
binding.sendCodeBtn.text = getString(R.string.resend_code)
binding.sendCodeBtn.isEnabled = true
isSendingCode = false
}

View File

@@ -163,7 +163,7 @@ class RetrievePasswordActivity : AppCompatActivity() {
override fun onFinish() {
isCountingDown = false
binding.btnGetCode.isEnabled = true
binding.btnGetCode.text = getString(R.string.get_verification_code)
binding.btnGetCode.text = getString(R.string.resend_code)
}
}.start()
}

View File

@@ -1,8 +1,14 @@
package com.ckkj.defense_device.utils
import android.annotation.SuppressLint
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.widget.Toast
import com.blankj.utilcode.util.Utils
import com.ckkj.defense_device.bean.BaseInfo
import com.ckkj.defense_device.login.LoginActivity
import com.google.gson.Gson
import com.google.gson.JsonParser
import okhttp3.Interceptor
@@ -24,10 +30,17 @@ object ApiConfig {
@Volatile
public var authToken: String = ""
@Volatile
private var isRedirectingToLogin = false
fun updateAuthToken(token: String) {
authToken = token
}
fun resetAuthRedirectFlag() {
isRedirectingToLogin = false
}
fun hasAuthToken(): Boolean {
return authToken.isNotBlank()
}
@@ -116,8 +129,8 @@ object ApiConfig {
val businessCode = if (jsonObject.has("code")) jsonObject.get("code").asInt else 0
if (httpCode == 401 || httpCode == 424 || businessCode == 401) {
clearUserLoginInfo()
val msg = if (jsonObject.has("msg")) jsonObject.get("msg").asString else "登录已过期,请重新登录"
redirectToLogin(msg)
return@Interceptor buildFakeErrorResponse(request, msg, code = if (businessCode != 0) businessCode else httpCode)
}
@@ -179,12 +192,36 @@ object ApiConfig {
private fun buildAuthorizationValue(token: String): String {
return if (token.startsWith("Bearer ")) token else "Bearer $token"
}
//401跳转登录界面
private fun redirectToLogin(msg: String) {
Handler(Looper.getMainLooper()).post {
if (isRedirectingToLogin) return@post
val current = ActivityManager.getCurrentActivity()
if (current is LoginActivity) return@post
isRedirectingToLogin = true
clearUserLoginInfo()
val context = current ?: Utils.getApp()
ActivityManager.finishAllActivities()
val intent = Intent(context, LoginActivity::class.java).apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
}
context.startActivity(intent)
if (msg.isNotBlank()) {
Toast.makeText(Utils.getApp(), msg, Toast.LENGTH_SHORT).show()
}
}
}
private fun clearUserLoginInfo() {
try {
authToken = ""
UserinfoUtil.clearUserInfo()
} catch (e: Exception) {
e.printStackTrace()
authToken = ""
}
}
}

View File

@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_enabled="false" android:color="@color/white"/>
<item android:color="@color/white"/>
</selector>

View 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_enabled="false">
<shape android:shape="rectangle">
<solid android:color="@color/gray"/>
<corners android:radius="16dp"/>
</shape>
</item>
<item>
<shape android:shape="rectangle">
<solid android:color="@color/green"/>
<corners android:radius="16dp"/>
</shape>
</item>
</selector>

View File

@@ -156,16 +156,17 @@
<!-- 发送验证码按钮 -->
<android.widget.Button
android:id="@+id/sendCodeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="110dp"
android:layout_height="36dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/send_sms_code"
android:textSize="16sp"
android:textColor="@color/white"
android:background="@drawable/rounded_blue_bg"
android:paddingHorizontal="12dp"
android:maxWidth="120dp"
android:textSize="14sp"
android:textColor="@color/send_code_text_color"
android:background="@drawable/send_code_btn_selector"
android:elevation="0dp"
android:stateListAnimator="@null"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -15,9 +15,7 @@
android:layout_height="wrap_content"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:paddingStart="16dp"
android:paddingEnd="16dp">
app:layout_constraintEnd_toEndOf="parent">
<ImageView
android:id="@+id/backIcon"
android:layout_width="24dp"
@@ -142,19 +140,20 @@
<!-- 发送验证码按钮 -->
<android.widget.Button
android:id="@+id/sendCodeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/send_code"
android:textSize="16sp"
android:layout_width="110dp"
android:layout_height="36dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/send_sms_code"
android:textSize="14sp"
android:textColor="@color/white"
android:background="@drawable/rounded_blue_bg"
android:paddingHorizontal="12dp"
android:maxWidth="120dp"
android:background="@drawable/send_code_btn_selector"
android:elevation="0dp"
android:stateListAnimator="@null"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
android:elevation="0dp"
android:stateListAnimator="@null"
android:layout_marginStart="12dp" />
</androidx.constraintlayout.widget.ConstraintLayout>

View File

@@ -3,6 +3,7 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@mipmap/home_back"
tools:context=".home.HomeMenuFragment">
<LinearLayout
@@ -136,8 +137,12 @@
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipeRefreshLayout"
android:layout_width="match_parent"
android:layout_marginLeft="12dp"
android:layout_marginRight="12dp"
android:layout_marginTop="12dp"
android:layout_height="0dp"
android:layout_weight="1">
android:layout_weight="1"
android:background="@android:color/transparent">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/rvDeviceList"
@@ -149,6 +154,7 @@
android:clipToPadding="false"
android:nestedScrollingEnabled="false"
android:paddingBottom="16dp"
android:background="@android:color/transparent"
tools:listitem="@layout/item_device" />
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

View File

@@ -197,9 +197,10 @@
<!-- 底部按钮区域 -->
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_height="0dp"
android:layout_marginHorizontal="16dp"
android:layout_marginTop="42dp"
android:layout_gravity="bottom"
android:layout_marginBottom="10dp"
android:orientation="horizontal"
android:gravity="bottom">

View File

@@ -41,7 +41,7 @@
android:id="@+id/tvNickname"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/enter_nickname"
android:text=""
android:textColor="@color/black"
android:textSize="16dp"
android:textStyle="bold" />
@@ -54,10 +54,11 @@
android:background="@drawable/rounded_blue_bg"
android:gravity="center"
android:paddingHorizontal="8dp"
android:text="@string/admin"
android:text=""
android:textColor="@color/white"
android:textSize="11sp"
android:textStyle="bold" />
android:textStyle="bold"
android:visibility="gone"/>
</LinearLayout>
<TextView
@@ -65,7 +66,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="4dp"
android:text="13589898989"
android:text=""
android:textColor="#666666"
android:textSize="16dp" />
</LinearLayout>

View File

@@ -140,16 +140,17 @@
<!-- 发送验证码按钮 -->
<android.widget.Button
android:id="@+id/sendCodeBtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="110dp"
android:layout_height="36dp"
android:minWidth="0dp"
android:minHeight="0dp"
android:text="@string/send_sms_code"
android:textSize="16sp"
android:textSize="14sp"
android:textColor="@color/white"
android:background="@drawable/rounded_blue_bg"
android:paddingHorizontal="12dp"
android:maxWidth="120dp"
android:background="@drawable/send_code_btn_selector"
android:elevation="0dp"
android:stateListAnimator="@null"
android:gravity="center"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"

View File

@@ -82,17 +82,19 @@
<android.widget.Button
android:id="@+id/btnGetCode"
android:layout_width="wrap_content"
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/rounded_blue_bg"
android:paddingHorizontal="16dp"
android:text="@string/get_verification_code"
android:background="@drawable/send_code_btn_selector"
android:text="@string/send_sms_code"
android:textColor="@color/white"
android:elevation="0dp"
android:stateListAnimator="@null"
android:gravity="center"
android:textSize="14sp" />
</RelativeLayout>

View File

@@ -77,6 +77,7 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/save"
android:textColor="@color/white"
android:layout_marginEnd="20dp"
android:layout_marginStart="20dp"
android:layout_marginBottom="90dp"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 901 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 63 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 183 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 592 B

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 296 KiB

View File

@@ -2,7 +2,7 @@
<resources>
<!-- App Name -->
<string name="app_name">防御</string>
<string name="app_name">防御</string>
<!-- Common -->
<string name="confirm">确定</string>
@@ -340,6 +340,7 @@
<string name="enter_phone_number">请输入手机号</string>
<string name="enter_verification_code">请输入验证码</string>
<string name="send_code">发送验证码</string>
<string name="resend_code">重新发送</string>
<string name="enter_new_password">请输入新密码</string>
<string name="enter_password_again">请再次输入新密码</string>
<string name="determine">确定</string>

View File

@@ -329,6 +329,7 @@
<string name="enter_phone_number">Enter phone number</string>
<string name="enter_verification_code">Enter verification code</string>
<string name="send_code">Send Code</string>
<string name="resend_code">Resend</string>
<string name="enter_new_password">Enter new password</string>
<string name="enter_password_again">Enter password again</string>
<string name="determine">Confirm</string>