增加左上角点击关闭页面,增加启动网络检测和连接功能,删除手机端测试布局;
This commit is contained in:
@@ -1,9 +1,17 @@
|
||||
package com.shuwei.intelligent.shelves.activity
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Intent
|
||||
import android.graphics.Color
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.util.Log
|
||||
import android.view.KeyEvent
|
||||
import android.view.animation.RotateAnimation
|
||||
import androidx.activity.viewModels
|
||||
import androidx.core.graphics.toColorInt
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.lifecycle.repeatOnLifecycle
|
||||
@@ -15,6 +23,7 @@ import com.shuwei.intelligent.shelves.net.NetViewModel
|
||||
import com.shuwei.intelligent.shelves.net.UiState
|
||||
import com.shuwei.intelligent.shelves.net.UrlConfig
|
||||
import com.shuwei.intelligent.shelves.utils.AppUtil
|
||||
import com.shuwei.intelligent.shelves.utils.NetworkUtils
|
||||
import com.shuwei.intelligent.shelves.utils.QRCodeUtil
|
||||
import com.shuwei.intelligent.shelves.utils.SpTool
|
||||
import com.shuwei.intelligent.shelves.utils.ext.dp
|
||||
@@ -39,6 +48,9 @@ class InitActivity : BaseActivity() {
|
||||
private lateinit var binding: ActivityInitBinding
|
||||
|
||||
private val viewModel: NetViewModel by viewModels()
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private var startTime = 0L // 倒计时开始时间
|
||||
private var lastNetworkCheckTime = 0L // 上次检测网络的时间
|
||||
|
||||
@SuppressLint("HardwareIds")
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
@@ -73,7 +85,8 @@ class InitActivity : BaseActivity() {
|
||||
binding.ivQrCode.invisible()
|
||||
binding.btnInit.invisible()
|
||||
|
||||
countDown()
|
||||
// countDown()
|
||||
initViews()
|
||||
}
|
||||
|
||||
private fun countDown() {
|
||||
@@ -161,4 +174,142 @@ class InitActivity : BaseActivity() {
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 初始化控件事件
|
||||
*/
|
||||
private fun initViews() {
|
||||
// 连接网络按钮点击事件
|
||||
binding.btnConnectNetwork.setOnClickListener {
|
||||
openNetworkSettings()
|
||||
}
|
||||
|
||||
// 启动加载动画 - 持续旋转
|
||||
startLoadingAnimation()
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动加载动画 - ImageView 持续旋转
|
||||
*/
|
||||
private fun startLoadingAnimation() {
|
||||
val rotateAnimation = RotateAnimation(
|
||||
0f, 360f,
|
||||
RotateAnimation.RELATIVE_TO_SELF, 0.5f,
|
||||
RotateAnimation.RELATIVE_TO_SELF, 0.5f
|
||||
).apply {
|
||||
duration = 1200 // 旋转周期 1.2 秒
|
||||
repeatCount = RotateAnimation.INFINITE // 无限循环
|
||||
repeatMode = RotateAnimation.RESTART
|
||||
}
|
||||
binding.ivLoading.startAnimation(rotateAnimation)
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
if (NetworkUtils.isNetworkConnected(this)) {
|
||||
navigateToHome()
|
||||
return
|
||||
}
|
||||
startCountdown()
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
// 页面不可见时停止倒计时
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
}
|
||||
|
||||
/**
|
||||
* 启动 60 秒倒计时
|
||||
*/
|
||||
private fun startCountdown() {
|
||||
startTime = SystemClock.elapsedRealtime()
|
||||
lastNetworkCheckTime = 0
|
||||
binding.llNetwork.setBackgroundColor(Color.TRANSPARENT)
|
||||
binding.llLoading.visibility = android.view.View.VISIBLE
|
||||
binding.llNetworkButton.visibility = android.view.View.GONE
|
||||
binding.tvCountdown.text = "60秒"
|
||||
scheduleCountdown()
|
||||
}
|
||||
|
||||
/**
|
||||
* 定时更新倒计时
|
||||
* 使用 SystemClock.elapsedRealtime() 确保精确计时
|
||||
*/
|
||||
private fun scheduleCountdown() {
|
||||
handler.postDelayed({
|
||||
val elapsedTime = SystemClock.elapsedRealtime() - startTime
|
||||
val remainingTime = 60 - (elapsedTime / 1000).toInt()
|
||||
val currentNetworkCheckTime = (elapsedTime / 1000).toInt()
|
||||
|
||||
// 每 10 秒检测一次网络
|
||||
if (currentNetworkCheckTime > 0 && currentNetworkCheckTime % 10 == 0 && currentNetworkCheckTime != lastNetworkCheckTime.toInt()) {
|
||||
lastNetworkCheckTime = currentNetworkCheckTime.toLong()
|
||||
checkNetworkConnection()
|
||||
}
|
||||
|
||||
// 倒计时未结束,继续更新 UI
|
||||
if (remainingTime > 0) {
|
||||
binding.tvCountdown.text = "${remainingTime}秒"
|
||||
scheduleCountdown()
|
||||
} else {
|
||||
// 倒计时结束,最后检测一次网络
|
||||
if (NetworkUtils.isNetworkConnected(this)) {
|
||||
navigateToHome()
|
||||
} else {
|
||||
// 网络未连接,显示"连接网络"按钮
|
||||
showNetworkButton()
|
||||
}
|
||||
}
|
||||
}, 100) // 每 100ms 检查一次,确保精确性
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测网络连接
|
||||
*/
|
||||
private fun checkNetworkConnection() {
|
||||
if (NetworkUtils.isNetworkConnected(this)) {
|
||||
// 网络连接成功,停止倒计时并跳转到 HomeActivity
|
||||
handler.removeCallbacksAndMessages(null)
|
||||
navigateToHome()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳转到 HomeActivity
|
||||
*/
|
||||
private fun navigateToHome() {
|
||||
startActivity<HomeActivity>()
|
||||
finish()
|
||||
}
|
||||
|
||||
/**
|
||||
* 显示"连接网络"按钮
|
||||
*/
|
||||
private fun showNetworkButton() {
|
||||
binding.llNetwork.setBackgroundColor("#5C77F7".toColorInt())
|
||||
binding.llLoading.visibility = android.view.View.GONE
|
||||
binding.llNetworkButton.visibility = android.view.View.VISIBLE
|
||||
}
|
||||
|
||||
/**
|
||||
* 打开系统网络设置页面
|
||||
*/
|
||||
private fun openNetworkSettings() {
|
||||
val intent = Intent(android.provider.Settings.ACTION_WIFI_SETTINGS)
|
||||
startActivity(intent)
|
||||
}
|
||||
|
||||
/**
|
||||
* 禁用返回键
|
||||
*/
|
||||
override fun onKeyDown(keyCode: Int, event: KeyEvent?): Boolean {
|
||||
return if (keyCode == KeyEvent.KEYCODE_BACK) {
|
||||
// 禁用返回键,不执行任何操作
|
||||
true
|
||||
} else {
|
||||
super.onKeyDown(keyCode, event)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,66 +1,66 @@
|
||||
package com.shuwei.intelligent.shelves.activity
|
||||
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||
import com.shuwei.intelligent.shelves.databinding.ActivitySettingBinding
|
||||
import com.shuwei.intelligent.shelves.utils.KeyboardUtil
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Date
|
||||
import java.util.Locale
|
||||
|
||||
class SettingActivity: BaseActivity() {
|
||||
|
||||
private lateinit var binding: ActivitySettingBinding
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = ActivitySettingBinding.inflate(layoutInflater)
|
||||
setBackground()
|
||||
setContentView(binding.root)
|
||||
binding.btnSendCmd.setOnClickListener{
|
||||
val cmd = binding.etInputCmd.text.toString().trim()
|
||||
if (cmd.isBlank()) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
var record = binding.tvCmdRecord.text.toString().trim()
|
||||
record = cmd+"\n"+record
|
||||
binding.tvCmdRecord.text = record
|
||||
val realCmd = "${HomeActivity.HEADER}0F01${cmd}${HomeActivity.FOOTER}"
|
||||
sendCmd(realCmd)
|
||||
}
|
||||
binding.ivBack.setOnClickListener { finish() }
|
||||
binding.root.setOnClickListener { v ->
|
||||
KeyboardUtil.hideKeyboard(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun updateDateTime() {
|
||||
val sdf = SimpleDateFormat(ShelfActivity.YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA)
|
||||
val dateTime = sdf.format(Date())
|
||||
val arr = dateTime.split("***")
|
||||
updateLeftStatus(arr[0])
|
||||
updateRightStatus(arr[1])
|
||||
}
|
||||
|
||||
private val handler = Handler(Looper.getMainLooper())
|
||||
private val updateTask = object : Runnable {
|
||||
override fun run() {
|
||||
updateDateTime()
|
||||
handler.postDelayed(this, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
hideStatusBar()
|
||||
handler.post(updateTask)
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
handler.removeCallbacks(updateTask)
|
||||
}
|
||||
|
||||
}
|
||||
//package com.shuwei.intelligent.shelves.activity
|
||||
//
|
||||
//import android.os.Bundle
|
||||
//import android.os.Handler
|
||||
//import android.os.Looper
|
||||
//import com.shuwei.intelligent.shelves.base.BaseActivity
|
||||
//import com.shuwei.intelligent.shelves.databinding.ActivitySettingBinding
|
||||
//import com.shuwei.intelligent.shelves.utils.KeyboardUtil
|
||||
//import java.text.SimpleDateFormat
|
||||
//import java.util.Date
|
||||
//import java.util.Locale
|
||||
//
|
||||
//class SettingActivity: BaseActivity() {
|
||||
//
|
||||
// private lateinit var binding: ActivitySettingBinding
|
||||
// override fun onCreate(savedInstanceState: Bundle?) {
|
||||
// super.onCreate(savedInstanceState)
|
||||
// binding = ActivitySettingBinding.inflate(layoutInflater)
|
||||
// setBackground()
|
||||
// setContentView(binding.root)
|
||||
// binding.btnSendCmd.setOnClickListener{
|
||||
// val cmd = binding.etInputCmd.text.toString().trim()
|
||||
// if (cmd.isBlank()) {
|
||||
// return@setOnClickListener
|
||||
// }
|
||||
// var record = binding.tvCmdRecord.text.toString().trim()
|
||||
// record = cmd+"\n"+record
|
||||
// binding.tvCmdRecord.text = record
|
||||
// val realCmd = "${HomeActivity.HEADER}0F01${cmd}${HomeActivity.FOOTER}"
|
||||
// sendCmd(realCmd)
|
||||
// }
|
||||
// binding.ivBack.setOnClickListener { finish() }
|
||||
// binding.root.setOnClickListener { v ->
|
||||
// KeyboardUtil.hideKeyboard(v)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// private fun updateDateTime() {
|
||||
// val sdf = SimpleDateFormat(ShelfActivity.YYYY_MM_DD__EEEE_HH_MM_SS, Locale.CHINA)
|
||||
// val dateTime = sdf.format(Date())
|
||||
// val arr = dateTime.split("***")
|
||||
// updateLeftStatus(arr[0])
|
||||
// updateRightStatus(arr[1])
|
||||
// }
|
||||
//
|
||||
// private val handler = Handler(Looper.getMainLooper())
|
||||
// private val updateTask = object : Runnable {
|
||||
// override fun run() {
|
||||
// updateDateTime()
|
||||
// handler.postDelayed(this, 1000)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun onResume() {
|
||||
// super.onResume()
|
||||
// hideStatusBar()
|
||||
// handler.post(updateTask)
|
||||
// }
|
||||
//
|
||||
// override fun onPause() {
|
||||
// super.onPause()
|
||||
// handler.removeCallbacks(updateTask)
|
||||
// }
|
||||
//
|
||||
//}
|
||||
@@ -11,21 +11,21 @@ import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import com.gyf.immersionbar.BarHide
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.shuwei.intelligent.shelves.activity.HomeActivity
|
||||
import com.shuwei.intelligent.shelves.activity.HomeActivity.Companion.LIGHT_CLOSE
|
||||
import com.shuwei.intelligent.shelves.activity.HomeActivity.Companion.LIGHT_OPEN
|
||||
import com.shuwei.intelligent.shelves.R
|
||||
import com.shuwei.intelligent.shelves.activity.LogActivity
|
||||
import com.shuwei.intelligent.shelves.activity.SettingActivity
|
||||
import com.shuwei.intelligent.shelves.databinding.ActivityBaseBinding
|
||||
import com.shuwei.intelligent.shelves.serial.SerialPortManager
|
||||
import com.shuwei.intelligent.shelves.utils.FileLogger
|
||||
import com.shuwei.intelligent.shelves.utils.ext.clickWithDebounce
|
||||
import com.shuwei.intelligent.shelves.utils.ext.startActivity
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import com.shuwei.intelligent.shelves.utils.ext.setOnDoubleClickListener
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
open class BaseActivity : AppCompatActivity() {
|
||||
val TAG = this.javaClass.simpleName
|
||||
@@ -46,6 +46,7 @@ open class BaseActivity : AppCompatActivity() {
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
hideSystemBars()
|
||||
binding = ActivityBaseBinding.inflate(layoutInflater)
|
||||
setContentView(binding.root)
|
||||
statusBarDarkFont()
|
||||
@@ -66,17 +67,21 @@ open class BaseActivity : AppCompatActivity() {
|
||||
// }
|
||||
|
||||
lightSwitchClick()
|
||||
|
||||
binding.tvLeftStatus.setOnDoubleClickListener {
|
||||
finish()
|
||||
}
|
||||
}
|
||||
|
||||
fun hideStatusBar() {
|
||||
// enableEdgeToEdge()
|
||||
// val uiOptions = (View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏
|
||||
// or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) // 隐藏导航栏(可选)
|
||||
// window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
|
||||
ImmersionBar.with(this)
|
||||
.hideBar(BarHide.FLAG_HIDE_STATUS_BAR)
|
||||
.init()
|
||||
//// enableEdgeToEdge()
|
||||
//// val uiOptions = (View.SYSTEM_UI_FLAG_FULLSCREEN // 隐藏状态栏
|
||||
//// or View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) // 隐藏导航栏(可选)
|
||||
//// window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_FULLSCREEN
|
||||
//
|
||||
// ImmersionBar.with(this)
|
||||
// .hideBar(BarHide.FLAG_HIDE_STATUS_BAR)
|
||||
// .init()
|
||||
}
|
||||
|
||||
fun statusBarDarkFont() {
|
||||
@@ -157,13 +162,13 @@ open class BaseActivity : AppCompatActivity() {
|
||||
switchLight(tag.not())
|
||||
}
|
||||
binding.tvRightStatus.clickWithDebounce {
|
||||
if (this is HomeActivity) {
|
||||
startActivity<LogActivity> {
|
||||
putExtra(LogActivity.IS_LOG_DIR, true)
|
||||
}
|
||||
return@clickWithDebounce
|
||||
}
|
||||
startActivity<SettingActivity> { }
|
||||
// if (this is HomeActivity) {
|
||||
// startActivity<LogActivity> {
|
||||
// putExtra(LogActivity.IS_LOG_DIR, true)
|
||||
// }
|
||||
// return@clickWithDebounce
|
||||
// }
|
||||
// startActivity<SettingActivity> { }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -181,4 +186,34 @@ open class BaseActivity : AppCompatActivity() {
|
||||
fileLogger.log(message)
|
||||
}
|
||||
|
||||
/**
|
||||
* 窗口焦点变化时回调
|
||||
* 场景:弹出 Dialog 后焦点丢失,Dialog 消失后焦点恢复,此时需重新隐藏系统栏,
|
||||
* 避免系统栏在 Dialog 关闭后意外"复活"
|
||||
*/
|
||||
override fun onWindowFocusChanged(hasFocus: Boolean) {
|
||||
super.onWindowFocusChanged(hasFocus)
|
||||
if (hasFocus) {
|
||||
hideSystemBars()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 隐藏状态栏和导航栏
|
||||
* 使用 WindowInsetsControllerCompat(Androidx 推荐方式,向下兼容性好)
|
||||
* - 状态栏:完全隐藏
|
||||
* - 导航栏:完全隐藏,底部上滑时临时出现,松手后自动收回(BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE)
|
||||
*/
|
||||
private fun hideSystemBars() {
|
||||
// 允许布局延伸到系统栏区域(edge-to-edge),避免内容被系统栏遮挡
|
||||
WindowCompat.setDecorFitsSystemWindows(window, false)
|
||||
WindowInsetsControllerCompat(window, window.decorView).apply {
|
||||
// 同时隐藏状态栏和导航栏
|
||||
hide(WindowInsetsCompat.Type.systemBars())
|
||||
// 底部上滑时临时显示导航栏,松手后自动隐藏(沉浸式 Sticky 模式)
|
||||
systemBarsBehavior =
|
||||
WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
package com.shuwei.intelligent.shelves.utils
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.NetworkCapabilities
|
||||
|
||||
/**
|
||||
* 网络连接检测工具类
|
||||
* 提供检测设备网络连接状态的功能
|
||||
*/
|
||||
object NetworkUtils {
|
||||
|
||||
/**
|
||||
* 检测设备是否连接到网络
|
||||
* @param context 应用上下文
|
||||
* @return true 表示已连接网络,false 表示未连接
|
||||
*/
|
||||
fun isNetworkConnected(context: Context): Boolean {
|
||||
val connectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||
val network = connectivityManager.activeNetwork ?: return false
|
||||
val capabilities = connectivityManager.getNetworkCapabilities(network) ?: return false
|
||||
return capabilities.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
|
||||
}
|
||||
}
|
||||
@@ -25,6 +25,7 @@ import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import android.content.ClipData
|
||||
import android.content.ClipboardManager
|
||||
import android.os.SystemClock
|
||||
|
||||
fun Context.toast(
|
||||
message: String?,
|
||||
@@ -175,3 +176,22 @@ fun String.copyTextToClipboard(context: Context) {
|
||||
Toast.makeText(context, "文本已复制到剪贴板", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
/**
|
||||
* 为View添加双击点击事件的扩展函数
|
||||
*/
|
||||
fun View.setOnDoubleClickListener(onDoubleClickListener: (View) -> Unit) {
|
||||
var lastClickTime = 0L
|
||||
var lastClickView: View? = null
|
||||
|
||||
this.setOnClickListener { view ->
|
||||
val currentTime = SystemClock.elapsedRealtime()
|
||||
if (lastClickView === view && currentTime - lastClickTime < 500) {
|
||||
// 双击事件触发
|
||||
onDoubleClickListener(view)
|
||||
lastClickTime = 0
|
||||
} else {
|
||||
lastClickTime = currentTime
|
||||
lastClickView = view
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user