重构添加设备流程

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
class WifiListAdapter(
private val wifiList: List<String>,
wifiList: List<String>,
private val onItemClick: (String) -> Unit
) : RecyclerView.Adapter<WifiListAdapter.ViewHolder>() {
private val wifiList = mutableListOf<String>().apply { addAll(wifiList) }
inner class ViewHolder(val binding: ItemWifiBinding) : RecyclerView.ViewHolder(binding.root) {
init {
itemView.setOnClickListener {
@@ -35,4 +37,17 @@ class WifiListAdapter(
}
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.IntentFilter
import android.content.pm.PackageManager
import android.net.ConnectivityManager
import android.net.Network
import android.net.NetworkCapabilities
import android.net.NetworkRequest
import android.graphics.Rect
import android.net.wifi.ScanResult
import android.net.wifi.WifiConfiguration
import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.Handler
@@ -26,24 +22,22 @@ import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.example.defenseapplication.R
import com.example.defenseapplication.adapter.WifiListAdapter
import com.example.defenseapplication.databinding.AddFamilyActivityBinding
import com.example.defenseapplication.databinding.DialogWifiListBinding
import com.gyf.immersionbar.ImmersionBar
//选择wifi页面
class AddFamilyActivity : AppCompatActivity() {
private lateinit var binding: AddFamilyActivityBinding
private lateinit var wifiManager: WifiManager
private lateinit var connectivityManager: ConnectivityManager
private lateinit var wifiScanReceiver: BroadcastReceiver
private var popupWindow: PopupWindow? = null
private val handler = Handler(Looper.getMainLooper())
private var isConnecting = false
private var targetWifiName: String = ""
private var networkCallback: ConnectivityManager.NetworkCallback? = null
private var wifiListAdapter: WifiListAdapter? = null
private var isLoadingMore = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -53,6 +47,7 @@ class AddFamilyActivity : AppCompatActivity() {
.statusBarDarkFont(true)
.titleBar(binding.topBar)
.init()
binding.ivBack.setOnClickListener {
finish()
}
@@ -70,8 +65,8 @@ class AddFamilyActivity : AppCompatActivity() {
updateBottomButtonVisibility()
}
})
wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
connectivityManager = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
wifiScanReceiver = object : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
@@ -81,12 +76,8 @@ class AddFamilyActivity : AppCompatActivity() {
}
}
}
binding.btnConfirm.setOnClickListener {
//startActivity(Intent(this, ConnectDeviceActivity::class.java))
if (isConnecting) {
return@setOnClickListener
}
binding.btnConfirm.setOnClickListener {
val wifiName = binding.etWifiName.text.toString().trim()
val wifiPassword = binding.etWifiPassword.text.toString()
@@ -100,143 +91,13 @@ class AddFamilyActivity : AppCompatActivity() {
return@setOnClickListener
}
isConnecting = true
binding.btnConfirm.isEnabled = false
verifyWifiPassword(wifiName, wifiPassword)
val intent = Intent(this@AddFamilyActivity, ConnectDeviceActivity::class.java)
intent.putExtra("wifi_name", wifiName)
intent.putExtra("wifi_password", 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() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED ||
@@ -255,10 +116,14 @@ class AddFamilyActivity : AppCompatActivity() {
wifiManager.startScan()
val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this))
val screenHeight = getScreenHeight()
val popupHeight = (screenHeight * 2 / 3).toInt()
popupWindow = PopupWindow(
dialogBinding.root,
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT
popupHeight
).apply {
isFocusable = true
setBackgroundDrawable(null)
@@ -273,10 +138,54 @@ class AddFamilyActivity : AppCompatActivity() {
dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@AddFamilyActivity)
val wifiList = getWifiList()
dialogBinding.rvWifiList.adapter = WifiListAdapter(wifiList) { wifiName ->
wifiListAdapter = WifiListAdapter(wifiList) { wifiName ->
binding.etWifiName.setText(wifiName)
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() {
@@ -315,31 +224,19 @@ class AddFamilyActivity : AppCompatActivity() {
super.onStop()
unregisterReceiver(wifiScanReceiver)
popupWindow?.dismiss()
networkCallback?.let {
try {
connectivityManager.unregisterNetworkCallback(it)
} catch (e: Exception) {
}
}
networkCallback = null
handler.removeCallbacksAndMessages(null)
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
when (requestCode) {
1002 -> {
1001 -> {
if (grantResults.isNotEmpty() &&
grantResults.size >= 3 &&
grantResults.size >= 2 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED &&
grantResults[1] == PackageManager.PERMISSION_GRANTED &&
grantResults[2] == PackageManager.PERMISSION_GRANTED) {
val wifiName = binding.etWifiName.text.toString().trim()
val wifiPassword = binding.etWifiPassword.text.toString()
verifyWifiPassword(wifiName, wifiPassword)
grantResults[1] == PackageManager.PERMISSION_GRANTED) {
showWifiListDialog()
} else {
isConnecting = false
binding.btnConfirm.isEnabled = true
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
}
}

View File

@@ -97,7 +97,12 @@ class ConnectDeviceActivity : AppCompatActivity() {
// 跳转到下一个界面或关闭当前页面
// 使用 Handler 延迟跳转
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()
}, 1000) // 1秒后跳转
}

View File

@@ -2,14 +2,24 @@ package com.example.defenseapplication.home
import android.content.Intent
import android.os.Bundle
import android.widget.Toast
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.liveVideo.LiveVideoActivity
import com.example.defenseapplication.utils.RetrofitNetwork
import com.gyf.immersionbar.ImmersionBar
//设置名字页面
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class SetNameActivity : AppCompatActivity() {
private lateinit var binding: SetNameActivityBinding
private var wifiName: String = ""
private var wifiPassword: String = ""
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@@ -19,12 +29,49 @@ class SetNameActivity : AppCompatActivity() {
.statusBarDarkFont(true)
.titleBar(binding.topBar)
.init()
// 获取传递的 WiFi 名称和密码
wifiName = intent.getStringExtra("wifi_name") ?: ""
wifiPassword = intent.getStringExtra("wifi_password") ?: ""
binding.ivBack.setOnClickListener {
finish()
}
binding.btnConfirm.setOnClickListener {
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.LoginRequest
import bean.RegisterRequest
import com.example.defenseapplication.bean.AddDeviceBean
import com.example.defenseapplication.bean.AddDeviceUserRequest
import com.example.defenseapplication.bean.DeleteBean
import com.example.defenseapplication.bean.DeleteDeviceUserRequest
@@ -73,6 +74,13 @@ interface ApiService {
@GET("/app/appMessage/list")
suspend fun getMessage(): GetCodeBean<List<MessageGroup>>
/**
* 添加设备并绑定家庭
*/
@POST("/app/addDevice")
suspend fun addDevice(@Body deviceBean: AddDeviceBean): GetCodeBean<AddDeviceBean>
/**
* 修改设备信息
*/