重构添加设备流程

This commit is contained in:
2026-05-25 17:52:19 +08:00
parent fa3ac69752
commit d5be6a9b5f
6 changed files with 157 additions and 172 deletions

View File

@@ -6,10 +6,12 @@ import androidx.recyclerview.widget.RecyclerView
import com.example.defenseapplication.databinding.ItemWifiBinding import com.example.defenseapplication.databinding.ItemWifiBinding
class WifiListAdapter( class WifiListAdapter(
private val wifiList: List<String>, wifiList: List<String>,
private val onItemClick: (String) -> Unit private val onItemClick: (String) -> Unit
) : RecyclerView.Adapter<WifiListAdapter.ViewHolder>() { ) : RecyclerView.Adapter<WifiListAdapter.ViewHolder>() {
private val wifiList = mutableListOf<String>().apply { addAll(wifiList) }
inner class ViewHolder(val binding: ItemWifiBinding) : RecyclerView.ViewHolder(binding.root) { inner class ViewHolder(val binding: ItemWifiBinding) : RecyclerView.ViewHolder(binding.root) {
init { init {
itemView.setOnClickListener { itemView.setOnClickListener {
@@ -35,4 +37,17 @@ class WifiListAdapter(
} }
override fun getItemCount(): Int = wifiList.size override fun getItemCount(): Int = wifiList.size
fun updateData(newList: List<String>) {
wifiList.clear()
wifiList.addAll(newList)
notifyDataSetChanged()
}
fun addData(newList: List<String>) {
val startPosition = wifiList.size
val newItems = newList.filter { !wifiList.contains(it) }
wifiList.addAll(newItems)
notifyItemRangeInserted(startPosition, newItems.size)
}
} }

View File

@@ -0,0 +1,13 @@
package com.example.defenseapplication.bean
data class AddDeviceBean(
val deviceEm: String? = null,//设备型号
val deviceNo: String? = null,//设备编号
val deviceSn: String? = null,//设备序列号
val fwVer: String? = null,//固件版本
val status: String? = null,//状态 1-在线 0-离线 2-故障 3-到期
val wifiName: String? = null,//WiFi名称
val wifiPassword: String? = null,//WiFi密码
val mac: String? = null,//邀请码
val deviceName: String? = null,//设备名称
)

View File

@@ -6,12 +6,8 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.IntentFilter import android.content.IntentFilter
import android.content.pm.PackageManager import android.content.pm.PackageManager
import android.net.ConnectivityManager import android.graphics.Rect
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.net.wifi.ScanResult import android.net.wifi.ScanResult
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager import android.net.wifi.WifiManager
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@@ -26,24 +22,22 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.defenseapplication.R import com.example.defenseapplication.R
import com.example.defenseapplication.adapter.WifiListAdapter import com.example.defenseapplication.adapter.WifiListAdapter
import com.example.defenseapplication.databinding.AddFamilyActivityBinding import com.example.defenseapplication.databinding.AddFamilyActivityBinding
import com.example.defenseapplication.databinding.DialogWifiListBinding import com.example.defenseapplication.databinding.DialogWifiListBinding
import com.gyf.immersionbar.ImmersionBar import com.gyf.immersionbar.ImmersionBar
//选择wifi页面
class AddFamilyActivity : AppCompatActivity() { class AddFamilyActivity : AppCompatActivity() {
private lateinit var binding: AddFamilyActivityBinding private lateinit var binding: AddFamilyActivityBinding
private lateinit var wifiManager: WifiManager private lateinit var wifiManager: WifiManager
private lateinit var connectivityManager: ConnectivityManager
private lateinit var wifiScanReceiver: BroadcastReceiver private lateinit var wifiScanReceiver: BroadcastReceiver
private var popupWindow: PopupWindow? = null private var popupWindow: PopupWindow? = null
private val handler = Handler(Looper.getMainLooper()) private val handler = Handler(Looper.getMainLooper())
private var isConnecting = false private var wifiListAdapter: WifiListAdapter? = null
private var targetWifiName: String = "" private var isLoadingMore = false
private var networkCallback: ConnectivityManager.NetworkCallback? = null
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -53,6 +47,7 @@ class AddFamilyActivity : AppCompatActivity() {
.statusBarDarkFont(true) .statusBarDarkFont(true)
.titleBar(binding.topBar) .titleBar(binding.topBar)
.init() .init()
binding.ivBack.setOnClickListener { binding.ivBack.setOnClickListener {
finish() finish()
} }
@@ -70,8 +65,8 @@ class AddFamilyActivity : AppCompatActivity() {
updateBottomButtonVisibility() updateBottomButtonVisibility()
} }
}) })
wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
wifiScanReceiver = object : BroadcastReceiver() { wifiScanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
@@ -81,12 +76,8 @@ class AddFamilyActivity : AppCompatActivity() {
} }
} }
} }
binding.btnConfirm.setOnClickListener { binding.btnConfirm.setOnClickListener {
//startActivity(Intent(this, ConnectDeviceActivity::class.java))
if (isConnecting) {
return@setOnClickListener
}
val wifiName = binding.etWifiName.text.toString().trim() val wifiName = binding.etWifiName.text.toString().trim()
val wifiPassword = binding.etWifiPassword.text.toString() val wifiPassword = binding.etWifiPassword.text.toString()
@@ -100,143 +91,13 @@ class AddFamilyActivity : AppCompatActivity() {
return@setOnClickListener return@setOnClickListener
} }
isConnecting = true val intent = Intent(this@AddFamilyActivity, ConnectDeviceActivity::class.java)
binding.btnConfirm.isEnabled = false intent.putExtra("wifi_name", wifiName)
intent.putExtra("wifi_password", wifiPassword)
verifyWifiPassword(wifiName, wifiPassword) startActivity(intent)
} }
} }
private fun verifyWifiPassword(wifiName: String, wifiPassword: String) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE)
!= PackageManager.PERMISSION_GRANTED ||
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_NETWORK_STATE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.CHANGE_WIFI_STATE,
Manifest.permission.ACCESS_NETWORK_STATE),
1002)
return
}
targetWifiName = wifiName
if (!wifiManager.isWifiEnabled) {
wifiManager.isWifiEnabled = true
}
val existingConfig = findExistingWifiConfig(wifiName)
var netId: Int
if (existingConfig != null) {
netId = existingConfig.networkId
existingConfig.preSharedKey = "\"$wifiPassword\""
wifiManager.updateNetwork(existingConfig)
} else {
val wifiConfig = createWifiConfig(wifiName, wifiPassword)
netId = wifiManager.addNetwork(wifiConfig)
}
if (netId == -1) {
isConnecting = false
binding.btnConfirm.isEnabled = true
ToastUtils.showError(this, getString(R.string.wifi_connection_failed))
return
}
networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
checkWifiConnected()
}
override fun onCapabilitiesChanged(network: Network, capabilities: NetworkCapabilities) {
super.onCapabilitiesChanged(network, capabilities)
if (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
checkWifiConnected()
}
}
}
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.build()
connectivityManager.registerNetworkCallback(request, networkCallback!!)
wifiManager.enableNetwork(netId, true)
wifiManager.saveConfiguration()
handler.postDelayed({
if (isConnecting) {
isConnecting = false
binding.btnConfirm.isEnabled = true
networkCallback?.let {
try {
connectivityManager.unregisterNetworkCallback(it)
} catch (e: Exception) {
}
}
networkCallback = null
ToastUtils.showError(this, getString(R.string.wifi_connection_failed))
}
}, 15000)
}
private fun findExistingWifiConfig(wifiName: String): WifiConfiguration? {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
return null
}
val configuredNetworks = wifiManager.configuredNetworks
configuredNetworks?.forEach { config ->
if (config.SSID == "\"$wifiName\"") {
return config
}
}
return null
}
private fun checkWifiConnected() {
if (!isConnecting) return
val info = wifiManager.connectionInfo
if (info.ssid == "\"$targetWifiName\"" && info.networkId != -1) {
isConnecting = false
binding.btnConfirm.isEnabled = true
networkCallback?.let {
try {
connectivityManager.unregisterNetworkCallback(it)
} catch (e: Exception) {
}
}
networkCallback = null
runOnUiThread {
ToastUtils.showSuccess(this@AddFamilyActivity, getString(R.string.wifi_connection_success))
val intent = Intent(this@AddFamilyActivity, ConnectDeviceActivity::class.java)
intent.putExtra("wifi_name", targetWifiName)
startActivity(intent)
}
}
}
private fun createWifiConfig(ssid: String, password: String): WifiConfiguration {
val config = WifiConfiguration()
config.SSID = "\"$ssid\""
config.preSharedKey = "\"$password\""
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK)
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN)
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA)
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP)
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP)
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP)
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP)
return config
}
private fun showWifiListDialog() { private fun showWifiListDialog() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED || != PackageManager.PERMISSION_GRANTED ||
@@ -255,10 +116,14 @@ class AddFamilyActivity : AppCompatActivity() {
wifiManager.startScan() wifiManager.startScan()
val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this)) val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this))
val screenHeight = getScreenHeight()
val popupHeight = (screenHeight * 2 / 3).toInt()
popupWindow = PopupWindow( popupWindow = PopupWindow(
dialogBinding.root, dialogBinding.root,
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT popupHeight
).apply { ).apply {
isFocusable = true isFocusable = true
setBackgroundDrawable(null) setBackgroundDrawable(null)
@@ -273,10 +138,54 @@ class AddFamilyActivity : AppCompatActivity() {
dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@AddFamilyActivity) dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@AddFamilyActivity)
val wifiList = getWifiList() val wifiList = getWifiList()
dialogBinding.rvWifiList.adapter = WifiListAdapter(wifiList) { wifiName -> wifiListAdapter = WifiListAdapter(wifiList) { wifiName ->
binding.etWifiName.setText(wifiName) binding.etWifiName.setText(wifiName)
popupWindow?.dismiss() popupWindow?.dismiss()
} }
dialogBinding.rvWifiList.adapter = wifiListAdapter
dialogBinding.swipeRefreshLayout.setOnRefreshListener {
refreshWifiList(dialogBinding)
}
dialogBinding.rvWifiList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = recyclerView.layoutManager as LinearLayoutManager
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
val totalItemCount = layoutManager.itemCount
if (lastVisibleItemPosition == totalItemCount - 1 && dy > 0 && !isLoadingMore && totalItemCount > 0) {
loadMoreWifiList()
}
}
})
}
private fun getScreenHeight(): Int {
val rect = Rect()
window.decorView.getWindowVisibleDisplayFrame(rect)
return rect.height()
}
private fun refreshWifiList(dialogBinding: DialogWifiListBinding) {
dialogBinding.swipeRefreshLayout.isRefreshing = true
handler.postDelayed({
wifiManager.startScan()
val newWifiList = getWifiList()
wifiListAdapter?.updateData(newWifiList)
dialogBinding.swipeRefreshLayout.isRefreshing = false
}, 1000)
}
private fun loadMoreWifiList() {
isLoadingMore = true
handler.postDelayed({
wifiManager.startScan()
val newWifiList = getWifiList()
wifiListAdapter?.addData(newWifiList)
isLoadingMore = false
}, 1000)
} }
private fun updateBottomButtonVisibility() { private fun updateBottomButtonVisibility() {
@@ -315,31 +224,19 @@ class AddFamilyActivity : AppCompatActivity() {
super.onStop() super.onStop()
unregisterReceiver(wifiScanReceiver) unregisterReceiver(wifiScanReceiver)
popupWindow?.dismiss() popupWindow?.dismiss()
networkCallback?.let {
try {
connectivityManager.unregisterNetworkCallback(it)
} catch (e: Exception) {
}
}
networkCallback = null
handler.removeCallbacksAndMessages(null) handler.removeCallbacksAndMessages(null)
} }
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) { override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults) super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) { when (requestCode) {
1002 -> { 1001 -> {
if (grantResults.isNotEmpty() && if (grantResults.isNotEmpty() &&
grantResults.size >= 3 && grantResults.size >= 2 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
grantResults[2] == PackageManager.PERMISSION_GRANTED) { showWifiListDialog()
val wifiName = binding.etWifiName.text.toString().trim()
val wifiPassword = binding.etWifiPassword.text.toString()
verifyWifiPassword(wifiName, wifiPassword)
} else { } else {
isConnecting = false
binding.btnConfirm.isEnabled = true
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show() Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
} }
} }

View File

@@ -97,7 +97,12 @@ class ConnectDeviceActivity : AppCompatActivity() {
// 跳转到下一个界面或关闭当前页面 // 跳转到下一个界面或关闭当前页面
// 使用 Handler 延迟跳转 // 使用 Handler 延迟跳转
Handler(Looper.getMainLooper()).postDelayed({ Handler(Looper.getMainLooper()).postDelayed({
startActivity(Intent(this, SetNameActivity::class.java)) val wifiName = intent.getStringExtra("wifi_name") ?: ""
val wifiPassword = intent.getStringExtra("wifi_password") ?: ""
startActivity(Intent(this, SetNameActivity::class.java).apply {
putExtra("wifi_name", wifiName)
putExtra("wifi_password", wifiPassword)
})
finish() finish()
}, 1000) // 1秒后跳转 }, 1000) // 1秒后跳转
} }

View File

@@ -2,14 +2,24 @@ package com.example.defenseapplication.home
import android.content.Intent import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import com.example.defenseapplication.bean.AddDeviceBean
import com.example.defenseapplication.bean.DeviceBean
import com.example.defenseapplication.databinding.SetNameActivityBinding import com.example.defenseapplication.databinding.SetNameActivityBinding
import com.example.defenseapplication.liveVideo.LiveVideoActivity import com.example.defenseapplication.liveVideo.LiveVideoActivity
import com.example.defenseapplication.utils.RetrofitNetwork
import com.gyf.immersionbar.ImmersionBar import com.gyf.immersionbar.ImmersionBar
//设置名字页面 import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SetNameActivity : AppCompatActivity() { class SetNameActivity : AppCompatActivity() {
private lateinit var binding: SetNameActivityBinding private lateinit var binding: SetNameActivityBinding
private var wifiName: String = ""
private var wifiPassword: String = ""
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
@@ -19,12 +29,49 @@ class SetNameActivity : AppCompatActivity() {
.statusBarDarkFont(true) .statusBarDarkFont(true)
.titleBar(binding.topBar) .titleBar(binding.topBar)
.init() .init()
// 获取传递的 WiFi 名称和密码
wifiName = intent.getStringExtra("wifi_name") ?: ""
wifiPassword = intent.getStringExtra("wifi_password") ?: ""
binding.ivBack.setOnClickListener { binding.ivBack.setOnClickListener {
finish() finish()
} }
binding.btnConfirm.setOnClickListener { binding.btnConfirm.setOnClickListener {
val deviceName = binding.etName.text.toString().trim() val deviceName = binding.etName.text.toString().trim()
startActivity(Intent(this, LiveVideoActivity::class.java).apply {}) if (deviceName.isEmpty()) {
Toast.makeText(this, "请输入设备名称", Toast.LENGTH_SHORT).show()
return@setOnClickListener
}
addDevice(deviceName)
}
}
private fun addDevice(deviceName: String) {
CoroutineScope(Dispatchers.IO).launch {
try {
val deviceBean = AddDeviceBean(
deviceName = deviceName,
wifiName = wifiName,
wifiPassword = wifiPassword,
status = "0"
)
val result = RetrofitNetwork.getNetworkService().addDevice(deviceBean)
withContext(Dispatchers.Main) {
if (result.code == 200) {
Toast.makeText(this@SetNameActivity, "设备添加成功", Toast.LENGTH_SHORT).show()
startActivity(Intent(this@SetNameActivity, LiveVideoActivity::class.java))
finish()
} else {
Toast.makeText(this@SetNameActivity, result.msg ?: "添加失败", Toast.LENGTH_SHORT).show()
}
}
} catch (e: Exception) {
withContext(Dispatchers.Main) {
Toast.makeText(this@SetNameActivity, "网络请求失败", Toast.LENGTH_SHORT).show()
}
}
} }
} }
} }

View File

@@ -8,6 +8,7 @@ import com.example.defenseapplication.bean.GetCodeBean
import bean.LoginBean import bean.LoginBean
import bean.LoginRequest import bean.LoginRequest
import bean.RegisterRequest import bean.RegisterRequest
import com.example.defenseapplication.bean.AddDeviceBean
import com.example.defenseapplication.bean.AddDeviceUserRequest import com.example.defenseapplication.bean.AddDeviceUserRequest
import com.example.defenseapplication.bean.DeleteBean import com.example.defenseapplication.bean.DeleteBean
import com.example.defenseapplication.bean.DeleteDeviceUserRequest import com.example.defenseapplication.bean.DeleteDeviceUserRequest
@@ -73,6 +74,13 @@ interface ApiService {
@GET("/app/appMessage/list") @GET("/app/appMessage/list")
suspend fun getMessage(): GetCodeBean<List<MessageGroup>> suspend fun getMessage(): GetCodeBean<List<MessageGroup>>
/**
* 添加设备并绑定家庭
*/
@POST("/app/addDevice")
suspend fun addDevice(@Body deviceBean: AddDeviceBean): GetCodeBean<AddDeviceBean>
/** /**
* 修改设备信息 * 修改设备信息
*/ */