Compare commits
14 Commits
d30c025874
...
ef4dfb0307
| Author | SHA1 | Date | |
|---|---|---|---|
| ef4dfb0307 | |||
| 086f1226a1 | |||
| 5cf30411c1 | |||
| 76e4949dd7 | |||
| 4a16010bd6 | |||
| b55d9a4b38 | |||
| 6a1cfaeda9 | |||
| f57975ef1e | |||
| 548d501a44 | |||
| a997190480 | |||
| 631f9831c3 | |||
| b2c3ed9015 | |||
| 6bd31327db | |||
| 7e362038b3 |
48
.kotlin/errors/errors-1780537656129.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker7700090853507788345.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1780537656460.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker12680940025563006602.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
48
.kotlin/errors/errors-1781138120653.log
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
kotlin version: 2.2.10
|
||||||
|
error message: java.nio.file.AccessDeniedException: C:\Users\Administrator\AppData\Local\kotlin\daemon\kotlin-daemon-client-tsmarker3894271637508823813.tmp
|
||||||
|
|
||||||
|
error message: Daemon compilation failed: Could not connect to Kotlin compile daemon
|
||||||
|
java.lang.RuntimeException: Could not connect to Kotlin compile daemon
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemon(GradleKotlinCompilerWork.kt:214)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.compileWithDaemonOrFallbackImpl(GradleKotlinCompilerWork.kt:159)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleKotlinCompilerWork.run(GradleKotlinCompilerWork.kt:111)
|
||||||
|
at org.jetbrains.kotlin.compilerRunner.GradleCompilerRunnerWithWorkers$GradleKotlinCompilerWorkAction.execute(GradleCompilerRunnerWithWorkers.kt:74)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerServer.execute(DefaultWorkerServer.java:68)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:64)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1$1.create(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.internal.classloader.ClassLoaderUtils.executeInClassloader(ClassLoaderUtils.java:102)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.lambda$execute$0(NoIsolationWorkerFactory.java:61)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:44)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker$1.call(AbstractWorker.java:41)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:209)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$CallableBuildOperationWorker.execute(DefaultBuildOperationRunner.java:204)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:66)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner$2.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:166)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.execute(DefaultBuildOperationRunner.java:59)
|
||||||
|
at org.gradle.internal.operations.DefaultBuildOperationRunner.call(DefaultBuildOperationRunner.java:53)
|
||||||
|
at org.gradle.workers.internal.AbstractWorker.executeWrappedInBuildOperation(AbstractWorker.java:41)
|
||||||
|
at org.gradle.workers.internal.NoIsolationWorkerFactory$1.execute(NoIsolationWorkerFactory.java:58)
|
||||||
|
at org.gradle.workers.internal.DefaultWorkerExecutor.lambda$submitWork$0(DefaultWorkerExecutor.java:176)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runExecution(DefaultConditionalExecutionQueue.java:194)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.access$700(DefaultConditionalExecutionQueue.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner$1.run(DefaultConditionalExecutionQueue.java:169)
|
||||||
|
at org.gradle.internal.Factories$1.create(Factories.java:30)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.lambda$withLocksAcquired$0(DefaultWorkerLeaseService.java:269)
|
||||||
|
at org.gradle.internal.work.ResourceLockStatistics$1.measure(ResourceLockStatistics.java:42)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocksAcquired(DefaultWorkerLeaseService.java:267)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.withLocks(DefaultWorkerLeaseService.java:259)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:127)
|
||||||
|
at org.gradle.internal.work.DefaultWorkerLeaseService.runAsWorkerThread(DefaultWorkerLeaseService.java:132)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.runBatch(DefaultConditionalExecutionQueue.java:164)
|
||||||
|
at org.gradle.internal.work.DefaultConditionalExecutionQueue$ExecutionRunner.run(DefaultConditionalExecutionQueue.java:133)
|
||||||
|
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
|
||||||
|
at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
|
||||||
|
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:64)
|
||||||
|
at org.gradle.internal.concurrent.AbstractManagedExecutor$1.run(AbstractManagedExecutor.java:47)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1144)
|
||||||
|
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:642)
|
||||||
|
at java.base/java.lang.Thread.run(Thread.java:1583)
|
||||||
|
|
||||||
|
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
android:fullBackupContent="@xml/backup_rules"
|
android:fullBackupContent="@xml/backup_rules"
|
||||||
android:icon="@mipmap/logo"
|
android:icon="@mipmap/logo"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
|
android:networkSecurityConfig="@xml/network_security_config"
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.DefenseApplication">
|
android:theme="@style/Theme.DefenseApplication">
|
||||||
@@ -42,6 +43,9 @@
|
|||||||
<activity
|
<activity
|
||||||
android:name=".personal.InvitationCodeActivity"
|
android:name=".personal.InvitationCodeActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
<activity
|
||||||
|
android:name=".personal.JoinFamilyInviteActivity"
|
||||||
|
android:exported="false" />
|
||||||
<activity
|
<activity
|
||||||
android:name=".liveVideo.StrikePositionActivity"
|
android:name=".liveVideo.StrikePositionActivity"
|
||||||
android:exported="false" />
|
android:exported="false" />
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ class AddDeviceAdapter(
|
|||||||
private val onItemClick: (Device) -> Unit
|
private val onItemClick: (Device) -> Unit
|
||||||
) : RecyclerView.Adapter<AddDeviceAdapter.ViewHolder>() {
|
) : RecyclerView.Adapter<AddDeviceAdapter.ViewHolder>() {
|
||||||
|
|
||||||
|
private val defaultIcons = listOf(R.mipmap.img1, R.mipmap.img2, R.mipmap.img3)
|
||||||
|
|
||||||
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
|
||||||
val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2)
|
val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2)
|
||||||
val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2)
|
val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2)
|
||||||
@@ -47,7 +49,9 @@ class AddDeviceAdapter(
|
|||||||
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: ViewHolder, position: Int) {
|
||||||
val device = devices[position]
|
val device = devices[position]
|
||||||
holder.tvName.text = device.name
|
holder.tvName.text = device.name
|
||||||
holder.ivIcon.setImageResource(R.mipmap.img)
|
|
||||||
|
val iconResId = defaultIcons[position % defaultIcons.size]
|
||||||
|
holder.ivIcon.setImageResource(iconResId)
|
||||||
|
|
||||||
// 点击事件
|
// 点击事件
|
||||||
holder.itemView.setOnClickListener { onItemClick(device) }
|
holder.itemView.setOnClickListener { onItemClick(device) }
|
||||||
|
|||||||
@@ -3,25 +3,18 @@ package com.ckkj.defense_device.adapter
|
|||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.ckkj.defense_device.databinding.ItemDeviceBinding
|
import com.ckkj.defense_device.databinding.ItemDeviceBinding
|
||||||
|
|
||||||
data class DeviceUi(
|
|
||||||
val name: String,
|
|
||||||
val status: String,
|
|
||||||
val deviceId: String = ""
|
|
||||||
) {
|
|
||||||
val isOnline: Boolean
|
|
||||||
get() = status == "1"
|
|
||||||
}
|
|
||||||
|
|
||||||
class DeviceAdapter(
|
class DeviceAdapter(
|
||||||
private val onItemClick: (DeviceUi) -> Unit = {}
|
private val onItemClick: (DeviceBean) -> Unit = {}
|
||||||
) : RecyclerView.Adapter<DeviceAdapter.DeviceViewHolder>() {
|
) : RecyclerView.Adapter<DeviceAdapter.DeviceViewHolder>() {
|
||||||
|
|
||||||
private val items = mutableListOf<DeviceUi>()
|
private val items = mutableListOf<DeviceBean>()
|
||||||
|
|
||||||
fun submitList(deviceList: List<DeviceUi>) {
|
fun submitList(deviceList: List<DeviceBean>) {
|
||||||
items.clear()
|
items.clear()
|
||||||
items.addAll(deviceList)
|
items.addAll(deviceList)
|
||||||
notifyDataSetChanged()
|
notifyDataSetChanged()
|
||||||
@@ -33,15 +26,25 @@ class DeviceAdapter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onBindViewHolder(holder: DeviceViewHolder, position: Int) {
|
override fun onBindViewHolder(holder: DeviceViewHolder, position: Int) {
|
||||||
holder.bind(items[position])
|
holder.bind(items[position], position)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getItemCount(): Int = items.size
|
override fun getItemCount(): Int = items.size
|
||||||
|
|
||||||
|
private val defaultIcons = listOf(R.mipmap.img1, R.mipmap.img2, R.mipmap.img3)
|
||||||
|
|
||||||
inner class DeviceViewHolder(private val binding: ItemDeviceBinding) :
|
inner class DeviceViewHolder(private val binding: ItemDeviceBinding) :
|
||||||
RecyclerView.ViewHolder(binding.root) {
|
RecyclerView.ViewHolder(binding.root) {
|
||||||
|
|
||||||
fun bind(item: DeviceUi) {
|
fun bind(item: DeviceBean, position: Int) {
|
||||||
|
if (item.deviceImg.isNullOrEmpty()) {
|
||||||
|
val iconResId = defaultIcons[position % defaultIcons.size]
|
||||||
|
binding.ivDeviceIcon.setImageResource(iconResId)
|
||||||
|
} else {
|
||||||
|
Glide.with(binding.root.context)
|
||||||
|
.load(item.deviceImg)
|
||||||
|
.into(binding.ivDeviceIcon)
|
||||||
|
}
|
||||||
binding.tvDeviceType.text = item.name
|
binding.tvDeviceType.text = item.name
|
||||||
when (item.status) {
|
when (item.status) {
|
||||||
"1" -> {
|
"1" -> {
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ package com.ckkj.defense_device.bean
|
|||||||
* 统一返回数据基类(根据你的后端实际字段调整)
|
* 统一返回数据基类(根据你的后端实际字段调整)
|
||||||
*/
|
*/
|
||||||
data class BaseInfo(
|
data class BaseInfo(
|
||||||
val message: String? = null,
|
val msg: String? = null,
|
||||||
val code: Int = 0,
|
val code: Int = 0,
|
||||||
val data: Any? = null
|
val data: Any? = null
|
||||||
)
|
)
|
||||||
@@ -27,4 +27,13 @@ data class DeviceBean(
|
|||||||
val wifiPassword: String? = null,//WiFi密码
|
val wifiPassword: String? = null,//WiFi密码
|
||||||
val workMode: String? = null,//工作模式 0-自动 1-半自动
|
val workMode: String? = null,//工作模式 0-自动 1-半自动
|
||||||
val optionPassword: String? = null, //操作密码
|
val optionPassword: String? = null, //操作密码
|
||||||
)
|
) {
|
||||||
|
val deviceId: String
|
||||||
|
get() = id ?: ""
|
||||||
|
|
||||||
|
val name: String
|
||||||
|
get() = deviceName ?: ""
|
||||||
|
|
||||||
|
val isOnline: Boolean
|
||||||
|
get() = status == "1"
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
|
||||||
|
data class JoinTheFamilyBean(
|
||||||
|
val parentId: String,
|
||||||
|
val inviteCode: String,
|
||||||
|
)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class RecommendationCodeBean(
|
||||||
|
val inviteCode: String? = null,
|
||||||
|
val code: String? = null,
|
||||||
|
val expireTime: Long? = null,
|
||||||
|
val expire: Long? = null
|
||||||
|
)
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class SelectInviterInfoBean(
|
||||||
|
val code: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
package com.ckkj.defense_device.bean
|
||||||
|
|
||||||
|
data class UpdateFamilyUserRequest(
|
||||||
|
val id: String,
|
||||||
|
val optionPassword: String,
|
||||||
|
val optionStatus: String,
|
||||||
|
val status: String,
|
||||||
|
)
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.ckkj.defense_device.home
|
package com.ckkj.defense_device.home
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
@@ -7,6 +8,10 @@ import com.ckkj.defense_device.base.BaseActivity
|
|||||||
import com.ckkj.defense_device.databinding.HomeActivityBinding
|
import com.ckkj.defense_device.databinding.HomeActivityBinding
|
||||||
|
|
||||||
class HomeActivity : BaseActivity() {
|
class HomeActivity : BaseActivity() {
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val EXTRA_REFRESH = "extra_refresh"
|
||||||
|
}
|
||||||
// ViewBinding 核心对象
|
// ViewBinding 核心对象
|
||||||
private lateinit var binding: HomeActivityBinding
|
private lateinit var binding: HomeActivityBinding
|
||||||
|
|
||||||
@@ -49,6 +54,28 @@ class HomeActivity : BaseActivity() {
|
|||||||
binding.ivProfile.setImageResource(R.mipmap.profile_checked)
|
binding.ivProfile.setImageResource(R.mipmap.profile_checked)
|
||||||
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_selected))
|
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_selected))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
handleRefreshIntent(intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onNewIntent(intent: Intent?) {
|
||||||
|
super.onNewIntent(intent)
|
||||||
|
if (intent != null) {
|
||||||
|
setIntent(intent)
|
||||||
|
handleRefreshIntent(intent)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun handleRefreshIntent(intent: Intent) {
|
||||||
|
if (intent.getBooleanExtra(EXTRA_REFRESH, false)) {
|
||||||
|
intent.removeExtra(EXTRA_REFRESH)
|
||||||
|
switchFragment(homeMenuFragment)
|
||||||
|
binding.ivHome.setImageResource(R.mipmap.home_checked)
|
||||||
|
binding.tvHome.setTextColor(resources.getColor(R.color.ic_selected))
|
||||||
|
binding.ivProfile.setImageResource(R.mipmap.profile)
|
||||||
|
binding.tvProfile.setTextColor(resources.getColor(R.color.ic_normal))
|
||||||
|
homeMenuFragment.refreshHomeData()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -23,13 +23,14 @@ import androidx.recyclerview.widget.LinearLayoutManager
|
|||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
import com.ckkj.defense_device.adapter.DeviceAdapter
|
import com.ckkj.defense_device.adapter.DeviceAdapter
|
||||||
import com.ckkj.defense_device.adapter.DeviceUi
|
|
||||||
import com.ckkj.defense_device.adapter.FamilyAdapter
|
import com.ckkj.defense_device.adapter.FamilyAdapter
|
||||||
import com.ckkj.defense_device.bean.DeviceBean
|
import com.ckkj.defense_device.bean.DeviceBean
|
||||||
import com.ckkj.defense_device.bean.FamilyBean
|
import com.ckkj.defense_device.bean.FamilyBean
|
||||||
import com.ckkj.defense_device.bean.SwitchFamilyRequest
|
import com.ckkj.defense_device.bean.SwitchFamilyRequest
|
||||||
|
import com.ckkj.defense_device.bean.SelectInviterInfoBean
|
||||||
import com.ckkj.defense_device.databinding.HomeMenuFragmentBinding
|
import com.ckkj.defense_device.databinding.HomeMenuFragmentBinding
|
||||||
import com.ckkj.defense_device.liveVideo.LiveVideoActivity
|
import com.ckkj.defense_device.liveVideo.LiveVideoActivity
|
||||||
|
import com.ckkj.defense_device.personal.JoinFamilyInviteActivity
|
||||||
import com.ckkj.defense_device.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
import com.ckkj.defense_device.utils.DeviceUpdateEvent
|
import com.ckkj.defense_device.utils.DeviceUpdateEvent
|
||||||
import com.ckkj.defense_device.utils.FamilySwitchEvent
|
import com.ckkj.defense_device.utils.FamilySwitchEvent
|
||||||
@@ -37,6 +38,7 @@ import com.ckkj.defense_device.utils.MessageStatusManager
|
|||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
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.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
|
||||||
@@ -45,6 +47,7 @@ import kotlinx.coroutines.CoroutineScope
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.json.JSONObject
|
||||||
//主页碎片
|
//主页碎片
|
||||||
class HomeMenuFragment : Fragment() {
|
class HomeMenuFragment : Fragment() {
|
||||||
// ViewBinding
|
// ViewBinding
|
||||||
@@ -122,23 +125,86 @@ class HomeMenuFragment : Fragment() {
|
|||||||
MNScanManager.RESULT_SUCCESS -> {
|
MNScanManager.RESULT_SUCCESS -> {
|
||||||
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
||||||
if (!result.isNullOrEmpty()) {
|
if (!result.isNullOrEmpty()) {
|
||||||
ToastUtils.showToast(requireContext(), "扫码成功: $result")
|
val inviteCode = parseInviteCode(result[0])
|
||||||
|
if (inviteCode.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(requireContext(), "无效的邀请码", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
ToastUtils.showToast(requireContext(), "扫码结果为空")
|
fetchInviterInfo(inviteCode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(requireContext(), "扫码结果为空", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
MNScanManager.RESULT_FAIL -> {
|
MNScanManager.RESULT_FAIL -> {
|
||||||
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||||
ToastUtils.showToast(requireContext(), "扫码失败: $error")
|
Toast.makeText(requireContext(), "扫码失败: $error", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
MNScanManager.RESULT_CANCLE -> {
|
MNScanManager.RESULT_CANCLE -> {
|
||||||
ToastUtils.showToast(requireContext(), "扫码取消")
|
Toast.makeText(requireContext(), "扫码取消", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun parseInviteCode(scanResult: String): String? {
|
||||||
|
val trimmed = scanResult.trim()
|
||||||
|
if (trimmed.isEmpty()) return null
|
||||||
|
return try {
|
||||||
|
if (trimmed.startsWith("{")) {
|
||||||
|
JSONObject(trimmed).optString("code").takeIf { it.isNotEmpty() }
|
||||||
|
} else {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInviterInfo(inviteCode: String) {
|
||||||
|
val loadingDialog = LoadingDialog(requireActivity()).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.selectInviterInfo(SelectInviterInfoBean(code = inviteCode))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val inviter = response.data
|
||||||
|
val parentId = inviter.resolveParentId()
|
||||||
|
if (parentId.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
getString(R.string.network_error),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
val intent = Intent(requireContext(), JoinFamilyInviteActivity::class.java).apply {
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_INVITE_CODE, inviteCode)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_NICK_NAME, inviter.nickName)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_AVATAR, inviter.avatar)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_PARENT_ID, parentId)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_USER_ID, inviter.userId)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
requireContext(),
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
private val unreadCountChangeListener = object : MessageStatusManager.UnreadCountChangeListener {
|
||||||
override fun onUnreadCountChanged(count: Int) {
|
override fun onUnreadCountChanged(count: Int) {
|
||||||
updateUnreadCountUI(count)
|
updateUnreadCountUI(count)
|
||||||
@@ -200,8 +266,8 @@ class HomeMenuFragment : Fragment() {
|
|||||||
// 为 LinearLayout 设置渐变背景
|
// 为 LinearLayout 设置渐变背景
|
||||||
setGradientBackground(
|
setGradientBackground(
|
||||||
view = binding.gradientLayout,
|
view = binding.gradientLayout,
|
||||||
startColor = Color.parseColor("#EBDCED"),
|
startColor = resources.getColor(R.color.gradientLayout1),
|
||||||
endColor = Color.parseColor("#CAF4FF")
|
endColor = resources.getColor(R.color.gradientLayout2)
|
||||||
)
|
)
|
||||||
binding.message.setOnClickListener {
|
binding.message.setOnClickListener {
|
||||||
val intent = Intent(requireContext(), MessageActivity::class.java)
|
val intent = Intent(requireContext(), MessageActivity::class.java)
|
||||||
@@ -285,6 +351,10 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun refreshHomeData() {
|
||||||
|
fetchFamilyList()
|
||||||
|
}
|
||||||
|
|
||||||
private fun fetchFamilyList() {
|
private fun fetchFamilyList() {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -321,18 +391,22 @@ class HomeMenuFragment : Fragment() {
|
|||||||
Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
|
Log.d("HomeMenuFragment", "canViewDevice = $canViewDevice")
|
||||||
if (canViewDevice) {
|
if (canViewDevice) {
|
||||||
binding.tvDeviceTitle.visibility = View.VISIBLE
|
binding.tvDeviceTitle.visibility = View.VISIBLE
|
||||||
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
binding.rvDeviceList.visibility = View.VISIBLE
|
binding.rvDeviceList.visibility = View.VISIBLE
|
||||||
binding.message.visibility = View.VISIBLE
|
binding.message.visibility = View.VISIBLE
|
||||||
binding.addFamily.visibility = View.VISIBLE
|
binding.addFamily.visibility = View.VISIBLE
|
||||||
binding.add.visibility = View.VISIBLE
|
binding.add.visibility = View.VISIBLE
|
||||||
binding.layoutNoPermission.visibility = View.GONE
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
} else {
|
} else {
|
||||||
binding.tvDeviceTitle.visibility = View.GONE
|
binding.tvDeviceTitle.visibility = View.GONE
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
binding.rvDeviceList.visibility = View.GONE
|
binding.rvDeviceList.visibility = View.GONE
|
||||||
binding.message.visibility = View.GONE
|
binding.message.visibility = View.GONE
|
||||||
binding.addFamily.visibility = View.GONE
|
binding.addFamily.visibility = View.GONE
|
||||||
binding.add.visibility = View.GONE
|
binding.add.visibility = View.GONE
|
||||||
binding.layoutNoPermission.visibility = View.VISIBLE
|
binding.layoutNoPermission.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -390,9 +464,12 @@ class HomeMenuFragment : Fragment() {
|
|||||||
hasMore = newDevices.size >= pageSize
|
hasMore = newDevices.size >= pageSize
|
||||||
}
|
}
|
||||||
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
||||||
|
showDeviceContent()
|
||||||
updateDeviceList()
|
updateDeviceList()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
noNetwork()
|
||||||
|
val errorMsg = response.msg.ifBlank { getString(R.string.network_error) }
|
||||||
|
Toast.makeText(requireContext(), errorMsg, Toast.LENGTH_SHORT).show()
|
||||||
if (isLoadMore) {
|
if (isLoadMore) {
|
||||||
hasMore = false
|
hasMore = false
|
||||||
}
|
}
|
||||||
@@ -401,6 +478,7 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
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) {
|
||||||
@@ -445,21 +523,31 @@ class HomeMenuFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateDeviceList() {
|
private fun showDeviceContent() {
|
||||||
val deviceUiList = deviceBeanList.map {
|
binding.swipeRefreshLayout.visibility = View.VISIBLE
|
||||||
DeviceUi(it.deviceName ?: "", it.status ?: "", it.id ?: "")
|
binding.rvDeviceList.visibility = View.VISIBLE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceUiList.isEmpty()) {
|
private fun noNetwork() {
|
||||||
|
binding.swipeRefreshLayout.visibility = View.GONE
|
||||||
|
binding.rvDeviceList.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateDeviceList() {
|
||||||
|
if (deviceBeanList.isEmpty()) {
|
||||||
deviceAdapter.submitList(listOf(
|
deviceAdapter.submitList(listOf(
|
||||||
DeviceUi(getString(R.string.no_device), "0")
|
DeviceBean(deviceName = getString(R.string.no_device), status = "0")
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
deviceAdapter.submitList(deviceUiList)
|
deviceAdapter.submitList(deviceBeanList)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun onDeviceClicked(device: DeviceUi) {
|
private fun onDeviceClicked(device: DeviceBean) {
|
||||||
if (device.isOnline) {
|
if (device.isOnline) {
|
||||||
DeviceIdEvent.setDeviceId(device.deviceId)
|
DeviceIdEvent.setDeviceId(device.deviceId)
|
||||||
val intent = Intent(requireContext(), LiveVideoActivity::class.java)
|
val intent = Intent(requireContext(), LiveVideoActivity::class.java)
|
||||||
|
|||||||
@@ -125,7 +125,7 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (allMessages.isEmpty()) {
|
if (allMessages.isEmpty()) {
|
||||||
showEmptyState()
|
noNetwork()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
@@ -152,6 +152,12 @@ class MessageActivity : AppCompatActivity() {
|
|||||||
binding.emptyLayout.visibility = View.GONE
|
binding.emptyLayout.visibility = View.GONE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.rvMessageList.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork.visibility = View.VISIBLE
|
||||||
|
binding.tvNoMoreData.visibility = View.GONE
|
||||||
|
}
|
||||||
|
|
||||||
private fun showNoMoreDataHint() {
|
private fun showNoMoreDataHint() {
|
||||||
binding.tvNoMoreData.visibility = View.VISIBLE
|
binding.tvNoMoreData.visibility = View.VISIBLE
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import com.ckkj.defense_device.utils.LanguageUtil
|
|||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
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.utils.ActivityManager
|
import com.ckkj.defense_device.utils.ActivityManager
|
||||||
|
import com.ckkj.defense_device.view.CustomDialogFragmentText
|
||||||
import com.ckkj.defense_device.view.FamilySwitchDialog
|
import com.ckkj.defense_device.view.FamilySwitchDialog
|
||||||
import com.ckkj.defense_device.view.LanguageDialog
|
import com.ckkj.defense_device.view.LanguageDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
@@ -100,6 +101,13 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
// 退出登录点击事件
|
// 退出登录点击事件
|
||||||
binding.btnLogout.setOnClickListener {
|
binding.btnLogout.setOnClickListener {
|
||||||
|
val dialog = CustomDialogFragmentText()
|
||||||
|
.setTitle(getString(R.string.tip))
|
||||||
|
.setMessage(getString(R.string.logout_confirm))
|
||||||
|
.setShowInput(false)
|
||||||
|
.setNegativeText(getString(R.string.cancel))
|
||||||
|
.setPositiveText(getString(R.string.confirm))
|
||||||
|
.setOnConfirmListener {
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().logout()
|
val response = RetrofitNetwork.getNetworkService().logout()
|
||||||
@@ -122,6 +130,8 @@ class PersonalFragment : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dialog.show(childFragmentManager, "logout_dialog")
|
||||||
|
}
|
||||||
fetchCurrentFamily()
|
fetchCurrentFamily()
|
||||||
return binding.root
|
return binding.root
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package com.ckkj.defense_device.liveVideo
|
|||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.Editable
|
import android.text.Editable
|
||||||
import android.text.TextWatcher
|
import android.text.TextWatcher
|
||||||
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
@@ -95,19 +96,33 @@ class AddLinkedUserActivity : AppCompatActivity() {
|
|||||||
Toast.makeText(this@AddLinkedUserActivity, "暂无家庭成员数据", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "暂无家庭成员数据", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
hide()
|
||||||
Toast.makeText(this@AddLinkedUserActivity, "请求失败: ${response.msg}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "请求失败: ${response.msg}", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
android.util.Log.e("AddLinkedUserActivity", "网络请求异常", e)
|
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
|
noNetwork()
|
||||||
Toast.makeText(this@AddLinkedUserActivity, "网络请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@AddLinkedUserActivity, "网络请求失败: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun hide() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvAddLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvAddLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateFamilyMemberList(familyMembersList: List<FamilyMembersBean>) {
|
private fun updateFamilyMemberList(familyMembersList: List<FamilyMembersBean>) {
|
||||||
fullUserItemList.clear()
|
fullUserItemList.clear()
|
||||||
familyMembersList.forEach { member ->
|
familyMembersList.forEach { member ->
|
||||||
|
|||||||
@@ -257,6 +257,7 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
updateFamilyMembersList(response.data as List<FamilyMembersBean>)
|
updateFamilyMembersList(response.data as List<FamilyMembersBean>)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
hide()
|
||||||
Toast.makeText(this@LinkedUserActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LinkedUserActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,11 +265,24 @@ class LinkedUserActivity : AppCompatActivity() {
|
|||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
binding.swipeRefresh.isRefreshing = false
|
binding.swipeRefresh.isRefreshing = false
|
||||||
Toast.makeText(this@LinkedUserActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
|
noNetwork()
|
||||||
|
Toast.makeText(this@LinkedUserActivity, R.string.network_request_failed, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
private fun hide() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoPermission?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
private fun noNetwork() {
|
||||||
|
binding.searchLayout.visibility = View.GONE
|
||||||
|
binding.rvLinkedUser.visibility = View.GONE
|
||||||
|
binding.butting?.visibility = View.GONE
|
||||||
|
binding.layoutNoNetwork?.visibility = View.VISIBLE
|
||||||
|
}
|
||||||
|
|
||||||
private fun updateDeviceUserList(deviceUserList: List<DeviceUserBean>) {
|
private fun updateDeviceUserList(deviceUserList: List<DeviceUserBean>) {
|
||||||
fullUserList.clear()
|
fullUserList.clear()
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class LiveVideoActivity : BaseActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun initVideoPlayer() {
|
private fun initVideoPlayer() {
|
||||||
val videoUrl = "https://www.w3schools.com/html/movie.mp4"//"https://test-streams.mux.dev/x36xhzz/x36xhzz.m3u8"
|
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
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import androidx.lifecycle.lifecycleScope
|
|||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
||||||
import com.ckkj.defense_device.bean.ObtainInviterInformationRequest
|
import com.ckkj.defense_device.bean.ObtainInviterInformationRequest
|
||||||
|
import com.ckkj.defense_device.bean.UpdateFamilyUserRequest
|
||||||
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.ckkj.defense_device.personal.PasswordInputDialog
|
import com.ckkj.defense_device.personal.PasswordInputDialog
|
||||||
import com.ckkj.defense_device.utils.DeviceIdEvent
|
import com.ckkj.defense_device.utils.DeviceIdEvent
|
||||||
@@ -26,6 +27,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
private var userId: String = ""
|
private var userId: String = ""
|
||||||
private var isPasswordVerified: Boolean = false
|
private var isPasswordVerified: Boolean = false
|
||||||
private lateinit var passwordDialog: PasswordInputDialog
|
private lateinit var passwordDialog: PasswordInputDialog
|
||||||
|
private var optionPassword: String = ""
|
||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
@@ -87,10 +89,12 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
binding.swUserStatus.setOnCheckedChangeListener { _, isChecked ->
|
binding.swUserStatus.setOnCheckedChangeListener { _, isChecked ->
|
||||||
if (!isPasswordVerified) {
|
if (!isPasswordVerified) {
|
||||||
binding.swUserStatus.isChecked = !isChecked
|
binding.swUserStatus.isChecked = !isChecked
|
||||||
showPasswordDialog {
|
showPasswordDialog(isChecked) {
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
binding.swUserStatus.isChecked = isChecked
|
binding.swUserStatus.isChecked = isChecked
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
updateFamilyUserStatus(isChecked)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,7 +103,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showPasswordDialog(onVerified: () -> Unit) {
|
private fun showPasswordDialog(status: Boolean, onVerified: () -> Unit) {
|
||||||
passwordDialog = PasswordInputDialog(this).apply {
|
passwordDialog = PasswordInputDialog(this).apply {
|
||||||
setOnConfirmListener { inputPassword ->
|
setOnConfirmListener { inputPassword ->
|
||||||
lifecycleScope.launch {
|
lifecycleScope.launch {
|
||||||
@@ -109,6 +113,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
dismiss()
|
dismiss()
|
||||||
|
updateFamilyUserStatus(status, inputPassword)
|
||||||
onVerified()
|
onVerified()
|
||||||
} else {
|
} else {
|
||||||
Toast.makeText(
|
Toast.makeText(
|
||||||
@@ -135,6 +140,48 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun updateFamilyUserStatus(status: Boolean) {
|
||||||
|
updateFamilyUserStatus(status, optionPassword)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateFamilyUserStatus(status: Boolean, password: String) {
|
||||||
|
if (userId.isEmpty()) {
|
||||||
|
Toast.makeText(this, "用户ID为空", Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (password.isNotEmpty()) {
|
||||||
|
optionPassword = password
|
||||||
|
}
|
||||||
|
|
||||||
|
lifecycleScope.launch {
|
||||||
|
try {
|
||||||
|
val request = UpdateFamilyUserRequest(
|
||||||
|
id = userId,
|
||||||
|
optionPassword = optionPassword,
|
||||||
|
optionStatus = "status",
|
||||||
|
status = if (status) "1" else "0"
|
||||||
|
)
|
||||||
|
val response = RetrofitNetwork.getNetworkService().updateFamilyUser(request)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
if (response.code == 200) {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, "状态修改成功", Toast.LENGTH_SHORT).show()
|
||||||
|
DeviceUserUpdateEvent.notifyUpdate()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, response.msg ?: "状态修改失败", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.swUserStatus.isChecked = !status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
e.printStackTrace()
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
Toast.makeText(this@UserDetailsActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
|
||||||
|
binding.swUserStatus.isChecked = !status
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun showDeleteDialog() {
|
private fun showDeleteDialog() {
|
||||||
val dialog = CustomDialogFragmentText()
|
val dialog = CustomDialogFragmentText()
|
||||||
dialog.setTitle(getString(R.string.tip))
|
dialog.setTitle(getString(R.string.tip))
|
||||||
@@ -146,7 +193,7 @@ class UserDetailsActivity : AppCompatActivity() {
|
|||||||
if (isPasswordVerified) {
|
if (isPasswordVerified) {
|
||||||
deleteDeviceUser()
|
deleteDeviceUser()
|
||||||
} else {
|
} else {
|
||||||
showPasswordDialog {
|
showPasswordDialog(false) {
|
||||||
isPasswordVerified = true
|
isPasswordVerified = true
|
||||||
deleteDeviceUser()
|
deleteDeviceUser()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -79,8 +79,7 @@ class VoiceSettingsActivity : AppCompatActivity() {
|
|||||||
private fun updateDeviceAlertAudio() {
|
private fun updateDeviceAlertAudio() {
|
||||||
deviceId?.let { id ->
|
deviceId?.let { id ->
|
||||||
val newAlertAudio = if (binding.swWarningVoice.isChecked) "1" else "0"
|
val newAlertAudio = if (binding.swWarningVoice.isChecked) "1" else "0"
|
||||||
// 只有状态发生变化时才请求
|
// 点击返回时总是触发网络请求
|
||||||
if (newAlertAudio != originalAlertAudio) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
val deviceBean = DeviceBean(id = id, alertAudio = newAlertAudio)
|
val deviceBean = DeviceBean(id = id, alertAudio = newAlertAudio)
|
||||||
@@ -89,20 +88,23 @@ class VoiceSettingsActivity : AppCompatActivity() {
|
|||||||
if (response.code == 200 && response.data != null) {
|
if (response.code == 200 && response.data != null) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, "修改成功", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, "修改成功", Toast.LENGTH_SHORT).show()
|
||||||
} else {
|
} else {
|
||||||
|
// 仅在状态实际发生变化时才显示错误提示
|
||||||
|
if (newAlertAudio != originalAlertAudio) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, response.msg, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, response.msg, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
// 仅在状态实际发生变化时才显示失败提示
|
||||||
|
if (newAlertAudio != originalAlertAudio) {
|
||||||
Toast.makeText(this@VoiceSettingsActivity, "修改失败", Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@VoiceSettingsActivity, "修改失败", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
finish()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -10,6 +10,7 @@ import bean.ForgotRequest
|
|||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
import com.ckkj.defense_device.databinding.ForgetPasswordActivityBinding
|
import com.ckkj.defense_device.databinding.ForgetPasswordActivityBinding
|
||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.google.firebase.crashlytics.buildtools.reloc.org.apache.http.util.TextUtils
|
import com.google.firebase.crashlytics.buildtools.reloc.org.apache.http.util.TextUtils
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
@@ -20,6 +21,7 @@ import java.util.regex.Pattern
|
|||||||
|
|
||||||
class ForgetPasswordActivity : AppCompatActivity() {
|
class ForgetPasswordActivity : AppCompatActivity() {
|
||||||
private lateinit var binding: ForgetPasswordActivityBinding
|
private lateinit var binding: ForgetPasswordActivityBinding
|
||||||
|
private var isLoading = false
|
||||||
private var countDownTimer: CountDownTimer? = null
|
private var countDownTimer: CountDownTimer? = null
|
||||||
private var isSendingCode = false
|
private var isSendingCode = false
|
||||||
|
|
||||||
@@ -63,9 +65,11 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
binding.btnNext.setOnClickListener {
|
binding.btnNext.setOnClickListener {
|
||||||
|
if (!isLoading) {
|
||||||
performResetPassword()
|
performResetPassword()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun isPhoneNumberValid(phone: String): Boolean {
|
private fun isPhoneNumberValid(phone: String): Boolean {
|
||||||
if (TextUtils.isEmpty(phone)) return false
|
if (TextUtils.isEmpty(phone)) return false
|
||||||
@@ -163,8 +167,11 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
isLoading = true
|
||||||
binding.btnNext.isEnabled = false
|
binding.btnNext.isEnabled = false
|
||||||
binding.btnNext.text = "重置中..."
|
val loadingDialog = LoadingDialog(this)
|
||||||
|
.setMessage(getString(R.string.resetting))
|
||||||
|
.apply { show() }
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -175,8 +182,9 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
)
|
)
|
||||||
val response = RetrofitNetwork.getNetworkService().forgotPassword(forgotRequest)
|
val response = RetrofitNetwork.getNetworkService().forgotPassword(forgotRequest)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = "确定"
|
|
||||||
|
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@ForgetPasswordActivity, R.string.reset_success, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, R.string.reset_success, Toast.LENGTH_SHORT).show()
|
||||||
@@ -187,8 +195,9 @@ class ForgetPasswordActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = "确定"
|
|
||||||
Toast.makeText(this@ForgetPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@ForgetPasswordActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import android.graphics.Color
|
|||||||
import android.graphics.drawable.GradientDrawable
|
import android.graphics.drawable.GradientDrawable
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.CountDownTimer
|
import android.os.CountDownTimer
|
||||||
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
@@ -194,6 +195,7 @@ class LoginActivity : AppCompatActivity() {
|
|||||||
try {
|
try {
|
||||||
val response = RetrofitNetwork.getNetworkService().getCode(phone)
|
val response = RetrofitNetwork.getNetworkService().getCode(phone)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
|
Log.d("VerificationCode", "code = ${response.code}, msg = ${response.msg}")
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@LoginActivity, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@LoginActivity, getString(R.string.code_sent_to, phone), Toast.LENGTH_SHORT).show()
|
||||||
startCountDown()
|
startCountDown()
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import bean.RegisterRequest
|
|||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
import com.ckkj.defense_device.databinding.RegisterActivityBinding
|
import com.ckkj.defense_device.databinding.RegisterActivityBinding
|
||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
@@ -158,7 +159,9 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
isLoading = true
|
isLoading = true
|
||||||
binding.btnNext.isEnabled = false
|
binding.btnNext.isEnabled = false
|
||||||
binding.btnNext.text = getString(R.string.registering)
|
val loadingDialog = LoadingDialog(this)
|
||||||
|
.setMessage(getString(R.string.registering))
|
||||||
|
.apply { show() }
|
||||||
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
try {
|
try {
|
||||||
@@ -174,8 +177,8 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
val response = RetrofitNetwork.getNetworkService().register(registerRequest)
|
val response = RetrofitNetwork.getNetworkService().register(registerRequest)
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = getString(R.string.next_step)
|
|
||||||
|
|
||||||
if (response.code == 200) {
|
if (response.code == 200) {
|
||||||
Toast.makeText(this@RegisterActivity, R.string.register_success, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@RegisterActivity, R.string.register_success, Toast.LENGTH_SHORT).show()
|
||||||
@@ -190,8 +193,8 @@ class RegisterActivity : AppCompatActivity() {
|
|||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
withContext(Dispatchers.Main) {
|
withContext(Dispatchers.Main) {
|
||||||
isLoading = false
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
binding.btnNext.isEnabled = true
|
binding.btnNext.isEnabled = true
|
||||||
binding.btnNext.text = getString(R.string.next_step)
|
|
||||||
Toast.makeText(this@RegisterActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this@RegisterActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,32 +1,45 @@
|
|||||||
package com.ckkj.defense_device.personal
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.Manifest
|
||||||
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.os.Environment
|
import android.os.Environment
|
||||||
|
import android.util.Log
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.activity.result.contract.ActivityResultContracts
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import com.google.android.material.bottomsheet.BottomSheetDialog
|
import com.google.android.material.bottomsheet.BottomSheetDialog
|
||||||
import androidx.core.content.ContextCompat
|
import androidx.core.content.ContextCompat
|
||||||
import com.ckkj.defense_device.R
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.bean.RecommendationCodeBean
|
||||||
|
import com.ckkj.defense_device.bean.SelectInviterInfoBean
|
||||||
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
import com.ckkj.defense_device.bean.VerifyOptionPasswordRequest
|
||||||
import com.ckkj.defense_device.databinding.DialogExpireTimeBinding
|
import com.ckkj.defense_device.databinding.DialogExpireTimeBinding
|
||||||
import com.ckkj.defense_device.databinding.InvitationCodeActivityBinding
|
import com.ckkj.defense_device.databinding.InvitationCodeActivityBinding
|
||||||
import com.ckkj.defense_device.utils.RetrofitNetwork
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.google.gson.Gson
|
||||||
import com.google.zxing.BarcodeFormat
|
import com.google.zxing.BarcodeFormat
|
||||||
import com.google.zxing.EncodeHintType
|
import com.google.zxing.EncodeHintType
|
||||||
import com.google.zxing.qrcode.QRCodeWriter
|
import com.google.zxing.qrcode.QRCodeWriter
|
||||||
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel
|
||||||
import com.gyf.immersionbar.ImmersionBar
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import com.maning.mlkitscanner.scan.MNScanManager
|
||||||
|
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||||
import kotlinx.coroutines.CoroutineScope
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.json.JSONObject
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileOutputStream
|
import java.io.FileOutputStream
|
||||||
import java.util.Hashtable
|
import java.util.Hashtable
|
||||||
@@ -44,7 +57,24 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
private var isLoading = false // 是否正在加载
|
private var isLoading = false // 是否正在加载
|
||||||
private var hasGeneratedQrCode = false // 是否已经生成过二维码
|
private var hasGeneratedQrCode = false // 是否已经生成过二维码
|
||||||
|
|
||||||
|
private val requestPermissionsLauncher = registerForActivityResult(
|
||||||
|
ActivityResultContracts.RequestMultiplePermissions()
|
||||||
|
) { permissions ->
|
||||||
|
val cameraGranted = permissions[Manifest.permission.CAMERA] ?: false
|
||||||
|
val storageGranted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
permissions[Manifest.permission.READ_MEDIA_IMAGES] ?: false
|
||||||
|
} else {
|
||||||
|
permissions[Manifest.permission.READ_EXTERNAL_STORAGE] ?: false
|
||||||
|
}
|
||||||
|
if (cameraGranted && storageGranted) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val TAG = "InvitationCodeActivity"
|
||||||
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
const val EXPIRE_24H = 24 * 60 * 60 * 1000L
|
||||||
const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L
|
const val EXPIRE_7D = 7 * 24 * 60 * 60 * 1000L
|
||||||
}
|
}
|
||||||
@@ -90,15 +120,136 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
// 撤销邀请按钮
|
// 撤销邀请按钮
|
||||||
binding.btnCancelInvite.setOnClickListener {
|
binding.btnCancelInvite.setOnClickListener {
|
||||||
showPasswordDialog {
|
if (generatedInviteCode.isEmpty()) {
|
||||||
cancelInvitation()
|
ToastUtils.showError(this, getString(R.string.qr_code_expired))
|
||||||
|
return@setOnClickListener
|
||||||
|
}
|
||||||
|
showPasswordDialog { password, dialog ->
|
||||||
|
cancelInvitation(password, dialog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 生成/重新生成按钮
|
// 生成/重新生成按钮
|
||||||
binding.btnRegenerate.setOnClickListener {
|
binding.btnRegenerate.setOnClickListener {
|
||||||
showPasswordDialog {
|
showPasswordDialog { password, dialog ->
|
||||||
generateOrRegenerateInvitation()
|
generateOrRegenerateInvitation(password, dialog)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.sys.setOnClickListener {
|
||||||
|
checkPermissionsAndScan()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun checkPermissionsAndScan() {
|
||||||
|
val cameraPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
|
||||||
|
val storagePermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES)
|
||||||
|
} else {
|
||||||
|
ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|
||||||
|
}
|
||||||
|
if (cameraPermission == PackageManager.PERMISSION_GRANTED &&
|
||||||
|
storagePermission == PackageManager.PERMISSION_GRANTED
|
||||||
|
) {
|
||||||
|
startScan()
|
||||||
|
} else {
|
||||||
|
val permissionsToRequest = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.READ_MEDIA_IMAGES
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
arrayOf(
|
||||||
|
Manifest.permission.CAMERA,
|
||||||
|
Manifest.permission.WRITE_EXTERNAL_STORAGE
|
||||||
|
)
|
||||||
|
}
|
||||||
|
requestPermissionsLauncher.launch(permissionsToRequest)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startScan() {
|
||||||
|
MNScanManager.startScan(this, object : MNScanCallback {
|
||||||
|
override fun onActivityResult(resultCode: Int, data: Intent?) {
|
||||||
|
when (resultCode) {
|
||||||
|
MNScanManager.RESULT_SUCCESS -> {
|
||||||
|
val result = data?.getStringArrayListExtra(MNScanManager.INTENT_KEY_RESULT_SUCCESS)
|
||||||
|
if (!result.isNullOrEmpty()) {
|
||||||
|
val inviteCode = parseInviteCode(result[0])
|
||||||
|
if (inviteCode.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "无效的邀请码", Toast.LENGTH_SHORT).show()
|
||||||
|
} else {
|
||||||
|
fetchInviterInfo(inviteCode)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码结果为空", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_FAIL -> {
|
||||||
|
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码失败: $error", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
MNScanManager.RESULT_CANCLE -> {
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, "扫码取消", Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun parseInviteCode(scanResult: String): String? {
|
||||||
|
val trimmed = scanResult.trim()
|
||||||
|
if (trimmed.isEmpty()) return null
|
||||||
|
return try {
|
||||||
|
if (trimmed.startsWith("{")) {
|
||||||
|
JSONObject(trimmed).optString("code").takeIf { it.isNotEmpty() }
|
||||||
|
} else {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
trimmed
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun fetchInviterInfo(inviteCode: String) {
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.selectInviterInfo(SelectInviterInfoBean(code = inviteCode))
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200 && response.data != null) {
|
||||||
|
val inviter = response.data
|
||||||
|
val parentId = inviter.resolveParentId()
|
||||||
|
if (parentId.isNullOrEmpty()) {
|
||||||
|
Toast.makeText(
|
||||||
|
this@InvitationCodeActivity,
|
||||||
|
getString(R.string.network_error),
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
return@withContext
|
||||||
|
}
|
||||||
|
val intent = Intent(this@InvitationCodeActivity, JoinFamilyInviteActivity::class.java).apply {
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_INVITE_CODE, inviteCode)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_NICK_NAME, inviter.nickName)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_AVATAR, inviter.avatar)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_PARENT_ID, parentId)
|
||||||
|
putExtra(JoinFamilyInviteActivity.EXTRA_USER_ID, inviter.userId)
|
||||||
|
}
|
||||||
|
startActivity(intent)
|
||||||
|
} else {
|
||||||
|
Toast.makeText(
|
||||||
|
this@InvitationCodeActivity,
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(this@InvitationCodeActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,14 +257,56 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
/**
|
/**
|
||||||
* 生成或重新生成邀请码
|
* 生成或重新生成邀请码
|
||||||
*/
|
*/
|
||||||
private fun generateOrRegenerateInvitation() {
|
private fun generateOrRegenerateInvitation(password: String, passwordDialog: PasswordInputDialog) {
|
||||||
// 根据当前选择的时效生成邀请码
|
if (isLoading) return
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.generateRecommendationCode(VerifyOptionPasswordRequest(password))
|
||||||
|
Log.d(TAG, "生成推荐码响应: code=${response.code}, msg=${response.msg}, data=${response.data}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
val parsed = parseRecommendationCode(response.data)
|
||||||
|
if (parsed != null) {
|
||||||
|
passwordDialog.dismiss()
|
||||||
|
generatedInviteCode = parsed.first
|
||||||
|
expireTimestamp = parsed.second
|
||||||
|
qrCodeContent =
|
||||||
|
"{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
||||||
|
Log.d(
|
||||||
|
TAG,
|
||||||
|
"推荐码生成成功: Code=$generatedInviteCode, expireTimestamp=$expireTimestamp, qrContent=$qrCodeContent"
|
||||||
|
)
|
||||||
generateQRCode()
|
generateQRCode()
|
||||||
showQrCode()
|
showQrCode()
|
||||||
// 更新按钮文字为"重新生成"
|
|
||||||
binding.btnRegenerate.text = getString(R.string.regenerate)
|
binding.btnRegenerate.text = getString(R.string.regenerate)
|
||||||
hasGeneratedQrCode = true
|
hasGeneratedQrCode = true
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
ToastUtils.showSuccess(this@InvitationCodeActivity, getString(R.string.operation_success))
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "推荐码解析失败, raw data=${response.data}")
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Log.w(TAG, "生成推荐码失败: code=${response.code}, msg=${response.msg}")
|
||||||
|
passwordDialog.showError(
|
||||||
|
response.msg.ifEmpty { getString(R.string.password_error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "生成推荐码异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showExpireTimeDialog() {
|
private fun showExpireTimeDialog() {
|
||||||
@@ -151,9 +344,6 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
binding.tvExpireTime.text = getString(R.string.expire_7d)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 显示二维码并生成
|
|
||||||
showQrCode()
|
|
||||||
generateQRCode()
|
|
||||||
expireTimeDialog?.dismiss()
|
expireTimeDialog?.dismiss()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,22 +363,28 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun generateQRCode() {
|
private fun generateQRCode() {
|
||||||
// 检查二维码是否过期,如果过期则生成新的邀请码
|
if (qrCodeContent.isEmpty()) return
|
||||||
val isExpired = expireTimestamp > 0 && System.currentTimeMillis() > expireTimestamp
|
val qrBitmap = createQRCodeWithLogo(qrCodeContent, 400, 400)
|
||||||
val content = if (qrCodeContent.isNotEmpty() && !isExpired) qrCodeContent else generateInviteCode()
|
|
||||||
val qrBitmap = createQRCodeWithLogo(content, 400, 400)
|
|
||||||
binding.ivQrCode.setImageBitmap(qrBitmap)
|
binding.ivQrCode.setImageBitmap(qrBitmap)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateInviteCode(): String {
|
private fun parseRecommendationCode(data: Any?): Pair<String, Long>? {
|
||||||
val timestamp = System.currentTimeMillis()
|
if (data == null) return null
|
||||||
expireTimestamp = timestamp + expireTimeInMillis
|
return when (data) {
|
||||||
generatedInviteCode = "INV${timestamp}"
|
is String -> {
|
||||||
qrCodeContent = "{\"type\":\"invite\",\"code\":\"$generatedInviteCode\",\"expire\":$expireTimestamp}"
|
if (data.isEmpty()) null
|
||||||
// 输出日志,方便调试验证
|
else Pair(data, System.currentTimeMillis() + expireTimeInMillis)
|
||||||
android.util.Log.d("InvitationCode", "生成的二维码内容: $qrCodeContent")
|
}
|
||||||
android.util.Log.d("InvitationCode", "推荐码: $generatedInviteCode, 过期时间戳: $expireTimestamp")
|
else -> {
|
||||||
return qrCodeContent
|
val bean = Gson().fromJson(Gson().toJson(data), RecommendationCodeBean::class.java)
|
||||||
|
val code = bean.inviteCode?.takeIf { it.isNotEmpty() }
|
||||||
|
?: bean.code?.takeIf { it.isNotEmpty() }
|
||||||
|
?: return null
|
||||||
|
val expire = bean.expireTime ?: bean.expire
|
||||||
|
?: (System.currentTimeMillis() + expireTimeInMillis)
|
||||||
|
Pair(code, expire)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
* 这段代码生成带Logo的二维码:
|
* 这段代码生成带Logo的二维码:
|
||||||
@@ -415,55 +611,61 @@ class InvitationCodeActivity : AppCompatActivity() {
|
|||||||
/**
|
/**
|
||||||
* 撤销邀请
|
* 撤销邀请
|
||||||
*/
|
*/
|
||||||
private fun cancelInvitation() {
|
private fun cancelInvitation(password: String, passwordDialog: PasswordInputDialog) {
|
||||||
// 撤销邀请逻辑
|
if (isLoading) return
|
||||||
|
if (generatedInviteCode.isEmpty()) {
|
||||||
|
passwordDialog.showError(getString(R.string.qr_code_expired))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.revokeInvitation(VerifyOptionPasswordRequest(password))
|
||||||
|
Log.d(TAG, "撤销邀请响应: code=${response.code}, msg=${response.msg}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
passwordDialog.dismiss()
|
||||||
hideQrCode()
|
hideQrCode()
|
||||||
generatedInviteCode = ""
|
generatedInviteCode = ""
|
||||||
qrCodeContent = ""
|
qrCodeContent = ""
|
||||||
expireTimestamp = 0
|
expireTimestamp = 0
|
||||||
hasGeneratedQrCode = false
|
hasGeneratedQrCode = false
|
||||||
// 恢复按钮文字为"生成邀请码"
|
|
||||||
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
binding.btnRegenerate.text = getString(R.string.generate_invite_code)
|
||||||
// 显示提示
|
ToastUtils.showSuccess(this@InvitationCodeActivity, getString(R.string.operation_success))
|
||||||
ToastUtils.showSuccess(this, getString(R.string.operation_success))
|
} else {
|
||||||
|
passwordDialog.showError(
|
||||||
|
response.msg.ifEmpty { getString(R.string.password_error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "撤销邀请异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
passwordDialog.showError(getString(R.string.network_error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 显示密码输入对话框
|
* 显示密码输入对话框
|
||||||
* @param onSuccess 验证成功后的回调
|
|
||||||
*/
|
*/
|
||||||
private fun showPasswordDialog(onSuccess: () -> Unit) {
|
private fun showPasswordDialog(onConfirm: (String, PasswordInputDialog) -> Unit) {
|
||||||
val dialog = PasswordInputDialog(this)
|
val dialog = PasswordInputDialog(this)
|
||||||
dialog.setTitle(getString(R.string.input_op_pwd))
|
dialog.setTitle(getString(R.string.input_op_pwd))
|
||||||
dialog.setOnConfirmListener { password ->
|
dialog.setOnConfirmListener { password ->
|
||||||
verifyPassword(password, dialog, onSuccess)
|
onConfirm(password, dialog)
|
||||||
}
|
}
|
||||||
dialog.show()
|
dialog.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 验证操作密码
|
|
||||||
*/
|
|
||||||
private fun verifyPassword(password: String, dialog: PasswordInputDialog, onSuccess: () -> Unit) {
|
|
||||||
CoroutineScope(Dispatchers.IO).launch {
|
|
||||||
try {
|
|
||||||
val response = RetrofitNetwork.getNetworkService()
|
|
||||||
.verifyOptionPassword(VerifyOptionPasswordRequest(password))
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
if (response.code == 200) {
|
|
||||||
dialog.dismiss()
|
|
||||||
onSuccess.invoke()
|
|
||||||
} else {
|
|
||||||
dialog.showError(getString(R.string.password_error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (e: Exception) {
|
|
||||||
withContext(Dispatchers.Main) {
|
|
||||||
dialog.showError(getString(R.string.network_error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
package com.ckkj.defense_device.personal
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.util.Log
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import com.bumptech.glide.Glide
|
||||||
|
import com.bumptech.glide.request.RequestOptions
|
||||||
|
import com.ckkj.defense_device.R
|
||||||
|
import com.ckkj.defense_device.bean.JoinTheFamilyBean
|
||||||
|
import com.ckkj.defense_device.databinding.JoinFamilyInviteActivityBinding
|
||||||
|
import com.ckkj.defense_device.home.HomeActivity
|
||||||
|
import com.ckkj.defense_device.utils.RetrofitNetwork
|
||||||
|
import com.ckkj.defense_device.view.LoadingDialog
|
||||||
|
import com.gyf.immersionbar.ImmersionBar
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
|
||||||
|
// 邀请加入家庭
|
||||||
|
class JoinFamilyInviteActivity : AppCompatActivity() {
|
||||||
|
|
||||||
|
private lateinit var binding: JoinFamilyInviteActivityBinding
|
||||||
|
private var isLoading = false
|
||||||
|
|
||||||
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
|
super.onCreate(savedInstanceState)
|
||||||
|
binding = JoinFamilyInviteActivityBinding.inflate(layoutInflater)
|
||||||
|
setContentView(binding.root)
|
||||||
|
|
||||||
|
ImmersionBar.with(this)
|
||||||
|
.statusBarDarkFont(true)
|
||||||
|
.titleBar(binding.topBar)
|
||||||
|
.init()
|
||||||
|
|
||||||
|
binding.ivBack.setOnClickListener { finish() }
|
||||||
|
binding.btnJoinNow.setOnClickListener { joinFamily() }
|
||||||
|
displayInviterInfo()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun joinFamily() {
|
||||||
|
if (isLoading) return
|
||||||
|
|
||||||
|
val parentId = intent.getStringExtra(EXTRA_USER_ID).orEmpty()
|
||||||
|
val inviteCode = intent.getStringExtra(EXTRA_INVITE_CODE).orEmpty()
|
||||||
|
if (parentId.isEmpty() || inviteCode.isEmpty()) {
|
||||||
|
Log.e(TAG, "加入家庭参数无效: parentId=$parentId, inviteCode=$inviteCode")
|
||||||
|
Toast.makeText(this, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.e(TAG, "加入家庭请求: parentId=$parentId, inviteCode=$inviteCode")
|
||||||
|
isLoading = true
|
||||||
|
val loadingDialog = LoadingDialog(this).apply { show() }
|
||||||
|
CoroutineScope(Dispatchers.IO).launch {
|
||||||
|
try {
|
||||||
|
val response = RetrofitNetwork.getNetworkService()
|
||||||
|
.joinTheFamily(JoinTheFamilyBean(parentId = parentId, inviteCode = inviteCode))
|
||||||
|
Log.e(TAG, "加入家庭响应: code=${response.code}, msg=${response.msg}, data=${response.data}")
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
if (response.code == 200) {
|
||||||
|
Log.e(TAG, "加入家庭成功,返回首页刷新")
|
||||||
|
ToastUtils.showSuccess(this@JoinFamilyInviteActivity, getString(R.string.operation_success))
|
||||||
|
val homeIntent = Intent(this@JoinFamilyInviteActivity, HomeActivity::class.java).apply {
|
||||||
|
flags = Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP
|
||||||
|
putExtra(HomeActivity.EXTRA_REFRESH, true)
|
||||||
|
}
|
||||||
|
startActivity(homeIntent)
|
||||||
|
finish()
|
||||||
|
} else {
|
||||||
|
Log.e(TAG, "加入家庭失败: code=${response.code}, msg=${response.msg}")
|
||||||
|
Toast.makeText(
|
||||||
|
this@JoinFamilyInviteActivity,
|
||||||
|
response.msg.ifBlank { getString(R.string.network_error) },
|
||||||
|
Toast.LENGTH_SHORT
|
||||||
|
).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "加入家庭请求异常", e)
|
||||||
|
withContext(Dispatchers.Main) {
|
||||||
|
isLoading = false
|
||||||
|
loadingDialog.dismiss()
|
||||||
|
Toast.makeText(this@JoinFamilyInviteActivity, R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun displayInviterInfo() {
|
||||||
|
val nickName = intent.getStringExtra(EXTRA_NICK_NAME).orEmpty()
|
||||||
|
val avatar = intent.getStringExtra(EXTRA_AVATAR)
|
||||||
|
|
||||||
|
binding.tvNickname.text = nickName.ifEmpty { getString(R.string.nickname_placeholder) }
|
||||||
|
binding.tvInviteMessage.text = getString(
|
||||||
|
R.string.invite_join_family_message,
|
||||||
|
nickName.ifEmpty { getString(R.string.nickname_placeholder) }
|
||||||
|
)
|
||||||
|
|
||||||
|
val requestOptions = RequestOptions()
|
||||||
|
.placeholder(R.mipmap.img)
|
||||||
|
.error(R.mipmap.img)
|
||||||
|
|
||||||
|
Glide.with(this)
|
||||||
|
.load(avatar)
|
||||||
|
.apply(requestOptions)
|
||||||
|
.circleCrop()
|
||||||
|
.into(binding.ivAvatar)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val TAG = "JoinFamilyInviteActivity"
|
||||||
|
const val EXTRA_INVITE_CODE = "invite_code"
|
||||||
|
const val EXTRA_NICK_NAME = "nick_name"
|
||||||
|
const val EXTRA_AVATAR = "avatar"
|
||||||
|
const val EXTRA_PARENT_ID = "parent_id"
|
||||||
|
const val EXTRA_USER_ID = "user_id"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -138,7 +138,7 @@ object ApiConfig {
|
|||||||
*/
|
*/
|
||||||
private fun buildFakeErrorResponse(request: Request, msg: String, code: Int = 1): Response {
|
private fun buildFakeErrorResponse(request: Request, msg: String, code: Int = 1): Response {
|
||||||
val baseInfo = BaseInfo(
|
val baseInfo = BaseInfo(
|
||||||
message = msg,
|
msg = msg,
|
||||||
code = code,
|
code = code,
|
||||||
data = null,
|
data = null,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -14,11 +14,15 @@ import com.ckkj.defense_device.bean.DeleteBean
|
|||||||
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
import com.ckkj.defense_device.bean.DeleteDeviceUserRequest
|
||||||
import com.ckkj.defense_device.bean.DeviceAlarmResponse
|
import com.ckkj.defense_device.bean.DeviceAlarmResponse
|
||||||
import com.ckkj.defense_device.bean.FamilyMembersBean
|
import com.ckkj.defense_device.bean.FamilyMembersBean
|
||||||
|
import com.ckkj.defense_device.bean.InviterInfoBean
|
||||||
|
import com.ckkj.defense_device.bean.JoinTheFamilyBean
|
||||||
import com.ckkj.defense_device.bean.MessageBean
|
import com.ckkj.defense_device.bean.MessageBean
|
||||||
import com.ckkj.defense_device.bean.MessageListResponse
|
import com.ckkj.defense_device.bean.MessageListResponse
|
||||||
import com.ckkj.defense_device.bean.ObtainInviterInformationBean
|
import com.ckkj.defense_device.bean.ObtainInviterInformationBean
|
||||||
import com.ckkj.defense_device.bean.ObtainInviterInformationRequest
|
import com.ckkj.defense_device.bean.ObtainInviterInformationRequest
|
||||||
|
import com.ckkj.defense_device.bean.SelectInviterInfoBean
|
||||||
import com.ckkj.defense_device.bean.SwitchFamilyRequest
|
import com.ckkj.defense_device.bean.SwitchFamilyRequest
|
||||||
|
import com.ckkj.defense_device.bean.UpdateFamilyUserRequest
|
||||||
import com.ckkj.defense_device.bean.UpdatePassword
|
import com.ckkj.defense_device.bean.UpdatePassword
|
||||||
import com.ckkj.defense_device.bean.UpdateUserInfo
|
import com.ckkj.defense_device.bean.UpdateUserInfo
|
||||||
import com.ckkj.defense_device.bean.UploadResponse
|
import com.ckkj.defense_device.bean.UploadResponse
|
||||||
@@ -191,7 +195,7 @@ interface ApiService {
|
|||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取邀请人信息
|
* 获取家庭成员信息
|
||||||
*/
|
*/
|
||||||
@POST("/app/obtainInviterInformation")
|
@POST("/app/obtainInviterInformation")
|
||||||
suspend fun obtainInviterInformation(@Body request: ObtainInviterInformationRequest): GetCodeBean<ObtainInviterInformationBean>
|
suspend fun obtainInviterInformation(@Body request: ObtainInviterInformationRequest): GetCodeBean<ObtainInviterInformationBean>
|
||||||
@@ -250,8 +254,22 @@ interface ApiService {
|
|||||||
/**
|
/**
|
||||||
* 修改家庭用户状态
|
* 修改家庭用户状态
|
||||||
*/
|
*/
|
||||||
//@POST("/app/updateFamilyUser")
|
@POST("/app/updateFamilyUser")
|
||||||
|
suspend fun updateFamilyUser(@Body request: UpdateFamilyUserRequest): GetCodeBean<Any>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取邀请人信息
|
||||||
|
*/
|
||||||
|
@POST("/app/selectInviterInfo")
|
||||||
|
suspend fun selectInviterInfo(@Body request: SelectInviterInfoBean): GetCodeBean<InviterInfoBean>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加入xxx家庭
|
||||||
|
*/
|
||||||
|
@POST("/app/joinTheFamily")
|
||||||
|
suspend fun joinTheFamily(@Body request: JoinTheFamilyBean): GetCodeBean<Any>
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ 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"
|
||||||
|
|
||||||
private var retrofit: Retrofit? = null
|
private var retrofit: Retrofit? = null
|
||||||
private val gson = Gson()
|
private val gson = Gson()
|
||||||
|
|||||||
@@ -5,5 +5,5 @@
|
|||||||
<stroke
|
<stroke
|
||||||
android:width="1dp"
|
android:width="1dp"
|
||||||
android:color="@color/green" />
|
android:color="@color/green" />
|
||||||
<corners android:radius="8dp" />
|
<corners android:radius="25dp" />
|
||||||
</shape>
|
</shape>
|
||||||
@@ -2,5 +2,5 @@
|
|||||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:shape="rectangle">
|
android:shape="rectangle">
|
||||||
<solid android:color="@color/green" />
|
<solid android:color="@color/green" />
|
||||||
<corners android:radius="8dp" />
|
<corners android:radius="25dp" />
|
||||||
</shape>
|
</shape>
|
||||||
@@ -164,6 +164,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:maxWidth="120dp"
|
android:maxWidth="120dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@@ -223,6 +225,8 @@
|
|||||||
android:layout_marginTop="40dp"
|
android:layout_marginTop="40dp"
|
||||||
android:text="@string/login"
|
android:text="@string/login"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/smsRowLayout"
|
app:layout_constraintTop_toBottomOf="@+id/smsRowLayout"
|
||||||
|
|||||||
@@ -123,6 +123,8 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16dp"
|
android:textSize="16dp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|||||||
@@ -80,6 +80,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:text="@string/select_wifi"
|
android:text="@string/select_wifi"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -88,8 +88,41 @@
|
|||||||
android:paddingBottom="16dp"/>
|
android:paddingBottom="16dp"/>
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<!-- 空页面 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoPermission"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="244dp"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
android:src="@mipmap/default_page"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
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
|
||||||
|
android:id="@+id/butting"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
@@ -102,6 +135,8 @@
|
|||||||
android:text="@string/confirm"
|
android:text="@string/confirm"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg" />
|
android:background="@drawable/rounded_blue_bg" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -105,6 +105,8 @@
|
|||||||
android:textAllCaps="false"
|
android:textAllCaps="false"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/etConfirmPassword" />
|
app:layout_constraintTop_toBottomOf="@+id/etConfirmPassword" />
|
||||||
|
|||||||
@@ -287,6 +287,8 @@
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|||||||
@@ -107,6 +107,8 @@
|
|||||||
android:textSize="17sp"
|
android:textSize="17sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
android:background="@drawable/bg_capture_face_button"
|
android:background="@drawable/bg_capture_face_button"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textColor="#F2FFFFFF" />
|
android:textColor="#F2FFFFFF" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -153,6 +153,8 @@
|
|||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:layout_marginStart="12dp" />
|
android:layout_marginStart="12dp" />
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -251,6 +253,8 @@
|
|||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
app:cornerRadius="12dp"
|
app:cornerRadius="12dp"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|||||||
@@ -168,6 +168,22 @@
|
|||||||
android:src="@mipmap/default_page" />
|
android:src="@mipmap/default_page" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
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>
|
||||||
|
|
||||||
<View
|
<View
|
||||||
|
|||||||
@@ -118,6 +118,7 @@
|
|||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
<!-- 使用智能文字和图标 -->
|
<!-- 使用智能文字和图标 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/sys"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_gravity="center_horizontal"
|
android:layout_gravity="center_horizontal"
|
||||||
@@ -125,16 +126,16 @@
|
|||||||
android:gravity="center_vertical">
|
android:gravity="center_vertical">
|
||||||
|
|
||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="20dp"
|
android:layout_width="24dp"
|
||||||
android:layout_height="20dp"
|
android:layout_height="24dp"
|
||||||
android:src="@drawable/syis" />
|
android:src="@mipmap/syis" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:textColor="@color/green"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:text="@string/use_smart_defense_app"
|
android:text="@string/use_smart_defense_app"
|
||||||
android:textColor="@color/black"
|
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
@@ -211,6 +212,8 @@
|
|||||||
android:layout_marginEnd="12dp"
|
android:layout_marginEnd="12dp"
|
||||||
android:text="@string/cancel_invite"
|
android:text="@string/cancel_invite"
|
||||||
android:textColor="@color/green"
|
android:textColor="@color/green"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:background="@drawable/bg_blue_border_round"
|
android:background="@drawable/bg_blue_border_round"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
@@ -223,6 +226,8 @@
|
|||||||
android:text="@string/regenerate"
|
android:text="@string/regenerate"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/bg_blue_round"
|
android:background="@drawable/bg_blue_round"
|
||||||
android:textAllCaps="false" />
|
android:textAllCaps="false" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
90
app/src/main/res/layout/join_family_invite_activity.xml
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
|
android:id="@+id/main"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:background="@color/white"
|
||||||
|
tools:context=".personal.JoinFamilyInviteActivity">
|
||||||
|
|
||||||
|
<androidx.constraintlayout.widget.ConstraintLayout
|
||||||
|
android:id="@+id/topBar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="56dp"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivBack"
|
||||||
|
android:layout_width="24dp"
|
||||||
|
android:layout_height="24dp"
|
||||||
|
android:layout_marginStart="16dp"
|
||||||
|
android:contentDescription="@string/back"
|
||||||
|
android:src="@mipmap/back"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/contentLayout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:gravity="center_horizontal"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
app:layout_constraintBottom_toTopOf="@id/btnJoinNow"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@id/topBar"
|
||||||
|
app:layout_constraintVertical_bias="0.35">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/ivAvatar"
|
||||||
|
android:layout_width="88dp"
|
||||||
|
android:layout_height="88dp"
|
||||||
|
android:contentDescription="@string/avatar"
|
||||||
|
android:scaleType="centerCrop"
|
||||||
|
android:src="@mipmap/img"/>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvNickname"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="20dp"
|
||||||
|
android:text="@string/nickname_placeholder"
|
||||||
|
android:textColor="@color/black"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textStyle="bold" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/tvInviteMessage"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
|
android:gravity="center"
|
||||||
|
android:text="@string/invite_join_family_message_preview"
|
||||||
|
android:textColor="@color/gray"
|
||||||
|
android:textSize="14sp" />
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
<android.widget.Button
|
||||||
|
android:id="@+id/btnJoinNow"
|
||||||
|
android:layout_width="0dp"
|
||||||
|
android:layout_height="48dp"
|
||||||
|
android:layout_marginHorizontal="16dp"
|
||||||
|
android:layout_marginBottom="40dp"
|
||||||
|
android:background="@drawable/rounded_blue_bg"
|
||||||
|
android:text="@string/join_now"
|
||||||
|
android:textColor="@color/white"
|
||||||
|
android:textSize="16sp"
|
||||||
|
android:textStyle="bold"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
@@ -35,6 +35,12 @@
|
|||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="0dp"
|
||||||
|
android:layout_weight="1"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
<!-- 搜索区域 -->
|
<!-- 搜索区域 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
android:id="@+id/searchLayout"
|
android:id="@+id/searchLayout"
|
||||||
@@ -72,23 +78,64 @@
|
|||||||
android:singleLine="true"/>
|
android:singleLine="true"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
<!-- 列表区域 -->
|
|
||||||
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
<!-- 内容区域 -->
|
||||||
android:id="@+id/swipeRefresh"
|
<FrameLayout
|
||||||
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">
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
|
||||||
|
android:id="@+id/swipeRefresh"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<com.yanzhenjie.recyclerview.SwipeRecyclerView
|
<com.yanzhenjie.recyclerview.SwipeRecyclerView
|
||||||
android:id="@+id/rvLinkedUser"
|
android:id="@+id/rvLinkedUser"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent"/>
|
||||||
android:paddingHorizontal="16dp"
|
|
||||||
android:paddingTop="8dp"
|
|
||||||
android:paddingBottom="16dp"/>
|
|
||||||
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>
|
||||||
|
|
||||||
|
<!-- 空页面 -->
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoPermission"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="244dp"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
android:src="@mipmap/default_page"/>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
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>
|
||||||
|
|
||||||
|
</FrameLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
<!-- 底部按钮 -->
|
<!-- 底部按钮 -->
|
||||||
<LinearLayout
|
<LinearLayout
|
||||||
|
android:id="@+id/butting"
|
||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -102,6 +149,8 @@
|
|||||||
android:text="@string/add_linked_user"
|
android:text="@string/add_linked_user"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg" />
|
android:background="@drawable/rounded_blue_bg" />
|
||||||
<!-- 悬浮加号按钮 -->
|
<!-- 悬浮加号按钮 -->
|
||||||
<ImageView
|
<ImageView
|
||||||
|
|||||||
@@ -58,7 +58,22 @@
|
|||||||
<ImageView
|
<ImageView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:src="@mipmap/no_message" />
|
android:src="@mipmap/default_page_img_name" />
|
||||||
|
</LinearLayout>
|
||||||
|
<LinearLayout
|
||||||
|
android:id="@+id/layoutNoNetwork"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:gravity="center"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:paddingHorizontal="32dp"
|
||||||
|
android:visibility="gone">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:layout_width="244dp"
|
||||||
|
android:layout_height="131dp"
|
||||||
|
android:src="@mipmap/no_network_img_name" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
|||||||
@@ -148,6 +148,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:paddingHorizontal="12dp"
|
android:paddingHorizontal="12dp"
|
||||||
android:maxWidth="120dp"
|
android:maxWidth="120dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
@@ -293,6 +295,8 @@
|
|||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
app:cornerRadius="12dp"
|
app:cornerRadius="12dp"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ tools:context=".login.RegisterSuccessActivity">
|
|||||||
android:textColor="@color/black"
|
android:textColor="@color/black"
|
||||||
android:textSize="16sp"
|
android:textSize="16sp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
|
||||||
app:layout_constraintBottom_toBottomOf="@id/backIcon"
|
app:layout_constraintBottom_toBottomOf="@id/backIcon"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
@@ -80,6 +81,8 @@ tools:context=".login.RegisterSuccessActivity">
|
|||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="14dp"
|
android:textSize="14dp"
|
||||||
android:textStyle="bold"
|
android:textStyle="bold"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
|||||||
@@ -91,6 +91,8 @@
|
|||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:text="@string/get_verification_code"
|
android:text="@string/get_verification_code"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</RelativeLayout>
|
</RelativeLayout>
|
||||||
|
|
||||||
@@ -131,6 +133,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:text="@string/confirm_reset_password_btn"
|
android:text="@string/confirm_reset_password_btn"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -81,6 +81,8 @@
|
|||||||
android:text="@string/complete"
|
android:text="@string/complete"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
android:textSize="16dp"
|
android:textSize="16dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textStyle="bold" />
|
android:textStyle="bold" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:text="@string/submit"
|
android:text="@string/submit"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="16sp" />
|
android:textSize="16sp" />
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|||||||
@@ -182,6 +182,8 @@
|
|||||||
android:textSize="16dp"
|
android:textSize="16dp"
|
||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:padding="0dp"
|
android:padding="0dp"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:layout_margin="0dp"/>
|
android:layout_margin="0dp"/>
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
@@ -72,7 +72,7 @@
|
|||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_weight="1"/>
|
android:layout_weight="1"/>
|
||||||
|
|
||||||
<Button
|
<android.widget.Button
|
||||||
android:id="@+id/btnSave"
|
android:id="@+id/btnSave"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -80,7 +80,9 @@
|
|||||||
android:layout_marginEnd="20dp"
|
android:layout_marginEnd="20dp"
|
||||||
android:layout_marginStart="20dp"
|
android:layout_marginStart="20dp"
|
||||||
android:layout_marginBottom="90dp"
|
android:layout_marginBottom="90dp"
|
||||||
android:backgroundTint="@color/green" />
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
|
android:background="@drawable/rounded_blue_bg" />
|
||||||
|
|
||||||
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
@@ -80,6 +80,8 @@
|
|||||||
android:background="@drawable/rounded_blue_bg"
|
android:background="@drawable/rounded_blue_bg"
|
||||||
android:text="@string/select_wifi"
|
android:text="@string/select_wifi"
|
||||||
android:textColor="@color/white"
|
android:textColor="@color/white"
|
||||||
|
android:elevation="0dp"
|
||||||
|
android:stateListAnimator="@null"
|
||||||
android:textSize="14sp" />
|
android:textSize="14sp" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
|
||||||
|
|||||||
BIN
app/src/main/res/mipmap-xhdpi/img1.png
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
app/src/main/res/mipmap-xhdpi/img2.png
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
app/src/main/res/mipmap-xhdpi/img3.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/mipmap-xhdpi/syis.png
Normal file
|
After Width: | Height: | Size: 540 B |
BIN
app/src/main/res/mipmap-xxhdpi/default_page_img_name.png
Normal file
|
After Width: | Height: | Size: 8.0 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/img1.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/img2.png
Normal file
|
After Width: | Height: | Size: 34 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/img3.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/no_network_img_name.png
Normal file
|
After Width: | Height: | Size: 9.5 KiB |
BIN
app/src/main/res/mipmap-xxhdpi/syis.png
Normal file
|
After Width: | Height: | Size: 956 B |
BIN
app/src/main/res/mipmap-xxxhdpi/default_page_img_name.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/img1.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/img2.png
Normal file
|
After Width: | Height: | Size: 58 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/img3.png
Normal file
|
After Width: | Height: | Size: 50 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/no_network_img_name.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
app/src/main/res/mipmap-xxxhdpi/syis.png
Normal file
|
After Width: | Height: | Size: 813 B |
@@ -48,6 +48,7 @@
|
|||||||
<string name="reset_password">重置密码</string>
|
<string name="reset_password">重置密码</string>
|
||||||
<string name="new_password">新密码</string>
|
<string name="new_password">新密码</string>
|
||||||
<string name="reset_success">密码重置成功</string>
|
<string name="reset_success">密码重置成功</string>
|
||||||
|
<string name="resetting">重置中...</string>
|
||||||
|
|
||||||
<!-- Face Login/Verification -->
|
<!-- Face Login/Verification -->
|
||||||
<string name="face_login">人脸登录</string>
|
<string name="face_login">人脸登录</string>
|
||||||
@@ -109,6 +110,10 @@
|
|||||||
<string name="enter_family_name">请输入家庭名称</string>
|
<string name="enter_family_name">请输入家庭名称</string>
|
||||||
<string name="create_family">创建家庭</string>
|
<string name="create_family">创建家庭</string>
|
||||||
<string name="join_family">加入家庭</string>
|
<string name="join_family">加入家庭</string>
|
||||||
|
<string name="join_now">立即加入</string>
|
||||||
|
<string name="nickname_placeholder">这里是昵称</string>
|
||||||
|
<string name="invite_join_family_message">邀请你加入%s的家庭</string>
|
||||||
|
<string name="invite_join_family_message_preview">邀请你加入这里是昵称的家庭</string>
|
||||||
<string name="family_code">家庭码</string>
|
<string name="family_code">家庭码</string>
|
||||||
<string name="enter_family_code">请输入家庭码</string>
|
<string name="enter_family_code">请输入家庭码</string>
|
||||||
<string name="family_with_normal">的家庭</string>
|
<string name="family_with_normal">的家庭</string>
|
||||||
|
|||||||
@@ -20,5 +20,7 @@
|
|||||||
<color name="green_light">#E8F7F7</color>
|
<color name="green_light">#E8F7F7</color>
|
||||||
<color name="gray_divider">#E5E5E5</color>
|
<color name="gray_divider">#E5E5E5</color>
|
||||||
<color name="orange">#FF9800</color>
|
<color name="orange">#FF9800</color>
|
||||||
|
<color name="gradientLayout1">#EBDCED</color>
|
||||||
|
<color name="gradientLayout2">#CAF4FF</color>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -44,6 +44,7 @@
|
|||||||
<string name="reset_password">Reset Password</string>
|
<string name="reset_password">Reset Password</string>
|
||||||
<string name="new_password">New Password</string>
|
<string name="new_password">New Password</string>
|
||||||
<string name="reset_success">Password reset successful</string>
|
<string name="reset_success">Password reset successful</string>
|
||||||
|
<string name="resetting">Resetting...</string>
|
||||||
|
|
||||||
<!-- Face Login/Verification -->
|
<!-- Face Login/Verification -->
|
||||||
<string name="face_capture_hint">Please align your face within the frame</string>
|
<string name="face_capture_hint">Please align your face within the frame</string>
|
||||||
@@ -104,6 +105,10 @@
|
|||||||
<string name="enter_family_name">Enter family name</string>
|
<string name="enter_family_name">Enter family name</string>
|
||||||
<string name="create_family">Create Family</string>
|
<string name="create_family">Create Family</string>
|
||||||
<string name="join_family">Join Family</string>
|
<string name="join_family">Join Family</string>
|
||||||
|
<string name="join_now">Join Now</string>
|
||||||
|
<string name="nickname_placeholder">Nickname</string>
|
||||||
|
<string name="invite_join_family_message">Inviting you to join %s\'s family</string>
|
||||||
|
<string name="invite_join_family_message_preview">Inviting you to join Nickname\'s family</string>
|
||||||
<string name="family_code">Family Code</string>
|
<string name="family_code">Family Code</string>
|
||||||
<string name="enter_family_code">Enter family code</string>
|
<string name="enter_family_code">Enter family code</string>
|
||||||
|
|
||||||
|
|||||||
6
app/src/main/res/xml/network_security_config.xml
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<network-security-config>
|
||||||
|
<domain-config cleartextTrafficPermitted="true">
|
||||||
|
<domain includeSubdomains="true">service.reinkun.com</domain>
|
||||||
|
</domain-config>
|
||||||
|
</network-security-config>
|
||||||