设备(1)
This commit is contained in:
@@ -1,18 +1,26 @@
|
||||
package com.example.defenseapplication.home
|
||||
|
||||
import android.Manifest
|
||||
import android.app.Activity
|
||||
import android.content.Intent
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.view.View
|
||||
import android.widget.Toast
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.content.ContextCompat
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.example.defenseapplication.R
|
||||
import com.example.defenseapplication.adapter.AddDeviceAdapter
|
||||
import com.example.defenseapplication.adapter.Device
|
||||
import com.example.defenseapplication.databinding.AddDeviceActivityBinding
|
||||
import com.gyf.immersionbar.ImmersionBar
|
||||
import com.maning.mlkitscanner.scan.MNScanManager
|
||||
import com.maning.mlkitscanner.scan.callback.act.MNScanCallback
|
||||
|
||||
//添加设备页面
|
||||
class AddDeviceActivity : AppCompatActivity() {
|
||||
@@ -20,6 +28,86 @@ class AddDeviceActivity : AppCompatActivity() {
|
||||
private lateinit var binding: AddDeviceActivityBinding
|
||||
private lateinit var adapter: AddDeviceAdapter
|
||||
private val mainHandler = Handler(Looper.getMainLooper())
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
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()) {
|
||||
ToastUtils.showToast(this@AddDeviceActivity, "扫码成功: $result")
|
||||
} else {
|
||||
ToastUtils.showToast(this@AddDeviceActivity, "扫码结果为空")
|
||||
}
|
||||
}
|
||||
MNScanManager.RESULT_FAIL -> {
|
||||
val error = data?.getStringExtra(MNScanManager.INTENT_KEY_RESULT_ERROR)
|
||||
ToastUtils.showToast(this@AddDeviceActivity, "扫码失败: $error")
|
||||
}
|
||||
MNScanManager.RESULT_CANCLE -> {
|
||||
ToastUtils.showToast(this@AddDeviceActivity, "扫码取消")
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
binding = AddDeviceActivityBinding.inflate(layoutInflater)
|
||||
@@ -32,6 +120,10 @@ class AddDeviceActivity : AppCompatActivity() {
|
||||
finish()
|
||||
}
|
||||
|
||||
binding.btnScanAdd.setOnClickListener {
|
||||
checkPermissionsAndScan()
|
||||
}
|
||||
|
||||
// 开始播放扫描动画,动画结束后再显示设备列表
|
||||
startScanAnimationThenShowList()
|
||||
}
|
||||
|
||||
@@ -6,15 +6,23 @@ 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.net.wifi.ScanResult
|
||||
import android.net.wifi.WifiConfiguration
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.text.Editable
|
||||
import android.text.TextWatcher
|
||||
import android.view.Gravity
|
||||
import android.view.LayoutInflater
|
||||
import android.view.ViewGroup
|
||||
import android.widget.PopupWindow
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.core.app.ActivityCompat
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
@@ -29,8 +37,13 @@ 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
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
@@ -58,6 +71,7 @@ class AddFamilyActivity : AppCompatActivity() {
|
||||
}
|
||||
})
|
||||
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) {
|
||||
@@ -68,11 +82,161 @@ class AddFamilyActivity : AppCompatActivity() {
|
||||
}
|
||||
}
|
||||
binding.btnConfirm.setOnClickListener {
|
||||
val intent=Intent(this, ConnectDeviceActivity::class.java)
|
||||
startActivity( intent)
|
||||
//startActivity(Intent(this, ConnectDeviceActivity::class.java))
|
||||
if (isConnecting) {
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
val wifiName = binding.etWifiName.text.toString().trim()
|
||||
val wifiPassword = binding.etWifiPassword.text.toString()
|
||||
|
||||
if (wifiName.isEmpty()) {
|
||||
Toast.makeText(this, R.string.enter_wifi_name, Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
if (wifiPassword.isEmpty()) {
|
||||
Toast.makeText(this, R.string.enter_wifi_password, Toast.LENGTH_SHORT).show()
|
||||
return@setOnClickListener
|
||||
}
|
||||
|
||||
isConnecting = true
|
||||
binding.btnConfirm.isEnabled = false
|
||||
|
||||
verifyWifiPassword(wifiName, wifiPassword)
|
||||
}
|
||||
}
|
||||
|
||||
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 ||
|
||||
@@ -151,5 +315,34 @@ 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 -> {
|
||||
if (grantResults.isNotEmpty() &&
|
||||
grantResults.size >= 3 &&
|
||||
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)
|
||||
} else {
|
||||
isConnecting = false
|
||||
binding.btnConfirm.isEnabled = true
|
||||
Toast.makeText(this, R.string.permission_denied, Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import com.example.defenseapplication.bean.DeviceBean
|
||||
import com.example.defenseapplication.bean.FamilyBean
|
||||
import com.example.defenseapplication.bean.SwitchFamilyRequest
|
||||
import com.example.defenseapplication.databinding.HomeMenuFragmentBinding
|
||||
import com.example.defenseapplication.utils.DeviceIdEvent
|
||||
import com.example.defenseapplication.utils.FamilySwitchEvent
|
||||
import com.example.defenseapplication.utils.MessageStatusManager
|
||||
import com.example.defenseapplication.utils.RetrofitNetwork
|
||||
@@ -52,6 +53,10 @@ class HomeMenuFragment : Fragment() {
|
||||
|
||||
private var isFamilyExpanded = false
|
||||
private lateinit var currentFamily: String
|
||||
private var currentPage = 1
|
||||
private val pageSize = 10
|
||||
private var hasMore = true
|
||||
private var isLoading = false
|
||||
|
||||
private val requestPermissionsLauncher = registerForActivityResult(
|
||||
ActivityResultContracts.RequestMultiplePermissions()
|
||||
@@ -222,6 +227,23 @@ class HomeMenuFragment : Fragment() {
|
||||
)
|
||||
}
|
||||
|
||||
binding.swipeRefreshLayout.setOnRefreshListener {
|
||||
refreshDeviceList()
|
||||
}
|
||||
|
||||
binding.rvDeviceList.addOnScrollListener(object : RecyclerView.OnScrollListener() {
|
||||
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
|
||||
super.onScrolled(recyclerView, dx, dy)
|
||||
val layoutManager = recyclerView.layoutManager as GridLayoutManager
|
||||
val lastVisibleItemPosition = layoutManager.findLastVisibleItemPosition()
|
||||
val totalItemCount = layoutManager.itemCount
|
||||
|
||||
if (!isLoading && hasMore && lastVisibleItemPosition >= totalItemCount - 1 && dy > 0) {
|
||||
loadMoreDevices()
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
binding.familyHeaderLayout.setOnClickListener {
|
||||
toggleFamilyList()
|
||||
}
|
||||
@@ -349,8 +371,10 @@ class HomeMenuFragment : Fragment() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun fetchDeviceList() {
|
||||
if (!canViewDevice) return
|
||||
private fun fetchDeviceList(page: Int = 1, isLoadMore: Boolean = false) {
|
||||
if (!canViewDevice || isLoading) return
|
||||
|
||||
isLoading = true
|
||||
|
||||
CoroutineScope(Dispatchers.IO).launch {
|
||||
try {
|
||||
@@ -358,21 +382,49 @@ class HomeMenuFragment : Fragment() {
|
||||
withContext(Dispatchers.Main) {
|
||||
Log.d("DeviceList", "code = ${response.code}, data = ${response.data}")
|
||||
if (response.code == 200 && response.data != null) {
|
||||
deviceBeanList = response.data
|
||||
val newDevices = response.data
|
||||
if (isLoadMore) {
|
||||
deviceBeanList = deviceBeanList + newDevices
|
||||
hasMore = newDevices.size >= pageSize
|
||||
} else {
|
||||
deviceBeanList = newDevices
|
||||
hasMore = newDevices.size >= pageSize
|
||||
}
|
||||
Log.d("DeviceList", "deviceBeanList size = ${deviceBeanList.size}")
|
||||
updateDeviceList()
|
||||
} else {
|
||||
Toast.makeText(requireContext(), response.msg, Toast.LENGTH_SHORT).show()
|
||||
if (isLoadMore) {
|
||||
hasMore = false
|
||||
}
|
||||
}
|
||||
isLoading = false
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
withContext(Dispatchers.Main) {
|
||||
Toast.makeText(requireContext(), R.string.network_error, Toast.LENGTH_SHORT).show()
|
||||
isLoading = false
|
||||
if (isLoadMore) {
|
||||
hasMore = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun refreshDeviceList() {
|
||||
currentPage = 1
|
||||
hasMore = true
|
||||
fetchDeviceList(currentPage, false)
|
||||
binding.swipeRefreshLayout.isRefreshing = false
|
||||
}
|
||||
|
||||
private fun loadMoreDevices() {
|
||||
if (isLoading || !hasMore) return
|
||||
currentPage++
|
||||
fetchDeviceList(currentPage, true)
|
||||
}
|
||||
|
||||
private fun toggleFamilyList() {
|
||||
isFamilyExpanded = !isFamilyExpanded
|
||||
val visibility = if (isFamilyExpanded) View.VISIBLE else View.GONE
|
||||
@@ -396,12 +448,12 @@ class HomeMenuFragment : Fragment() {
|
||||
|
||||
private fun updateDeviceList() {
|
||||
val deviceUiList = deviceBeanList.map {
|
||||
DeviceUi(it.deviceName, it.status == "0")
|
||||
DeviceUi(it.deviceName, it.status, it.id)
|
||||
}
|
||||
|
||||
if (deviceUiList.isEmpty()) {
|
||||
deviceAdapter.submitList(listOf(
|
||||
DeviceUi(getString(R.string.no_device), false)
|
||||
DeviceUi(getString(R.string.no_device), "0")
|
||||
))
|
||||
} else {
|
||||
deviceAdapter.submitList(deviceUiList)
|
||||
@@ -409,10 +461,16 @@ class HomeMenuFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun onDeviceClicked(device: DeviceUi) {
|
||||
if (device.isOnline) return
|
||||
showDefenseDialog(
|
||||
config = DefenseDialogs.deviceOfflineConfig(requireContext())
|
||||
)
|
||||
if (device.isOnline) {
|
||||
DeviceIdEvent.setDeviceId(device.deviceId)
|
||||
val intent = Intent(requireContext(), com.example.defenseapplication.liveVideo.LiveVideoActivity::class.java)
|
||||
intent.putExtra("device_name", device.name)
|
||||
startActivity(intent)
|
||||
} else {
|
||||
showDefenseDialog(
|
||||
config = DefenseDialogs.deviceOfflineConfig(requireContext())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun dpToPx(dp: Int): Int {
|
||||
|
||||
Reference in New Issue
Block a user