From c91b646857809ebf35b45e7c158e748b2f936d66 Mon Sep 17 00:00:00 2001 From: maxinyu Date: Mon, 11 May 2026 09:43:31 +0800 Subject: [PATCH] =?UTF-8?q?WiFi=E7=AE=A1=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/main/AndroidManifest.xml | 3 + .../adapter/AddDeviceAdapter.kt | 2 +- .../adapter/AddLinkedUserAdapter.kt | 37 +++++ .../liveVideo/AddLinkedUserActivity.kt | 61 ++++++++ .../liveVideo/LinkedUserActivity.kt | 6 +- .../liveVideo/SettingsActivity.kt | 6 +- .../liveVideo/WiFiManagementActivity.kt | 141 ++++++++++++++++- .../main/res/drawable/check_box_selector.xml | 5 + .../res/layout/add_linked_user_activity.xml | 96 ++++++++++++ .../main/res/layout/item_add_linked_user.xml | 23 +++ .../res/layout/wifi_management_activity.xml | 143 +++++++++++++++--- app/src/main/res/values-zh/strings.xml | 7 +- app/src/main/res/values/strings.xml | 6 +- 13 files changed, 501 insertions(+), 35 deletions(-) create mode 100644 app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt create mode 100644 app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt create mode 100644 app/src/main/res/drawable/check_box_selector.xml create mode 100644 app/src/main/res/layout/add_linked_user_activity.xml create mode 100644 app/src/main/res/layout/item_add_linked_user.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index f88e4a5..28a58c9 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -25,6 +25,9 @@ android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.DefenseApplication"> + diff --git a/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt index e6f181a..9f8306e 100644 --- a/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt +++ b/app/src/main/java/com/example/defenseapplication/adapter/AddDeviceAdapter.kt @@ -17,7 +17,7 @@ class AddDeviceAdapter(private val devices: List, private val onItemClic inner class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) { val ivIcon: ImageView = itemView.findViewById(R.id.ivDeviceIcon2) - val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2) // 注意:ID 要和布局中一致 + val tvName: TextView = itemView.findViewById(R.id.tvDeviceName2) // ID 要和布局中一致 } override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { diff --git a/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt b/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt new file mode 100644 index 0000000..c13e848 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/adapter/AddLinkedUserAdapter.kt @@ -0,0 +1,37 @@ +package com.example.defenseapplication.adapter + +import android.view.LayoutInflater +import android.view.ViewGroup +import androidx.recyclerview.widget.RecyclerView +import com.example.defenseapplication.databinding.ItemAddLinkedUserBinding + +data class UserItem(val name: String, val phone: String) + +class AddLinkedUserAdapter( + private val data: List, + private val selectedIds: MutableSet, + private val onItemClick: (String, Boolean) -> Unit +) : RecyclerView.Adapter() { + + inner class ViewHolder(val binding: ItemAddLinkedUserBinding) : RecyclerView.ViewHolder(binding.root) { + fun bind(item: UserItem) { + binding.tvUserName.text = "${item.name}-${item.phone}" + binding.cbSelect.isChecked = selectedIds.contains(item.phone) + binding.cbSelect.setOnClickListener { + val isChecked = binding.cbSelect.isChecked + onItemClick(item.phone, isChecked) + } + } + } + + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { + val binding = ItemAddLinkedUserBinding.inflate(LayoutInflater.from(parent.context), parent, false) + return ViewHolder(binding) + } + + override fun onBindViewHolder(holder: ViewHolder, position: Int) { + holder.bind(data[position]) + } + + override fun getItemCount(): Int = data.size +} \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt new file mode 100644 index 0000000..030ea96 --- /dev/null +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/AddLinkedUserActivity.kt @@ -0,0 +1,61 @@ +package com.example.defenseapplication.liveVideo + +import android.os.Bundle +import android.widget.Toast +import androidx.appcompat.app.AppCompatActivity +import androidx.recyclerview.widget.LinearLayoutManager +import com.example.defenseapplication.R +import com.example.defenseapplication.adapter.AddLinkedUserAdapter +import com.example.defenseapplication.adapter.UserItem +import com.example.defenseapplication.databinding.AddLinkedUserActivityBinding +import com.gyf.immersionbar.ImmersionBar + +class AddLinkedUserActivity : AppCompatActivity() { + private lateinit var binding: AddLinkedUserActivityBinding + private val selectedPhoneSet = mutableSetOf() + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + binding = AddLinkedUserActivityBinding.inflate(layoutInflater) + setContentView(binding.root) + + ImmersionBar.with(this) + .statusBarDarkFont(true) + .titleBar(binding.topBar) + .init() + + initRecyclerView() + initListener() + } + + private fun initRecyclerView() { + val mockData = listOf( + UserItem("王五", "13566666666"), + UserItem("赵六", "15733333333") + ) + + binding.rvAddLinkedUser.layoutManager = LinearLayoutManager(this) + binding.rvAddLinkedUser.adapter = + AddLinkedUserAdapter(mockData, selectedPhoneSet) { phone, isChecked -> + if (isChecked) { + selectedPhoneSet.add(phone) + } else { + selectedPhoneSet.remove(phone) + } + } + } + + private fun initListener() { + binding.btnAddLinkedUser.setOnClickListener { + if (selectedPhoneSet.isEmpty()) { + Toast.makeText(this, getString(R.string.please_select_at_least_one_user), Toast.LENGTH_SHORT).show() + } else { + val message = getString(R.string.selected_users_voice, selectedPhoneSet.size) + Toast.makeText(this, message, Toast.LENGTH_SHORT).show() + } + } + binding.ivBack.setOnClickListener { + finish() + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt index c388afb..da1edc6 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/LinkedUserActivity.kt @@ -12,7 +12,7 @@ import com.example.defenseapplication.adapter.LinkedUserAdapter import com.example.defenseapplication.databinding.LinkedUserActivityBinding import com.example.defenseapplication.view.CustomDialogFragmentText import com.gyf.immersionbar.ImmersionBar - +//关联用户页面 class LinkedUserActivity : AppCompatActivity() { private lateinit var binding: LinkedUserActivityBinding @@ -176,8 +176,8 @@ class LinkedUserActivity : AppCompatActivity() { } binding.btnAddLinkedUser.setOnClickListener { - val intent = Intent(this, LinkedUserSearchActivity::class.java) - startActivityForResult(intent, REQUEST_CODE_SEARCH) + val intent = Intent(this, AddLinkedUserActivity::class.java) + startActivity(intent) } } diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt index 5d77568..00bd7b4 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/SettingsActivity.kt @@ -78,8 +78,10 @@ class SettingsActivity : BaseActivity() { val intent = Intent(this, LinkedUserActivity::class.java) startActivity( intent) } - - + binding.itemWifiManage.setOnClickListener { + val intent = Intent(this, WiFiManagementActivity::class.java) + startActivity(intent) + } } } diff --git a/app/src/main/java/com/example/defenseapplication/liveVideo/WiFiManagementActivity.kt b/app/src/main/java/com/example/defenseapplication/liveVideo/WiFiManagementActivity.kt index 5a8ea3c..6f234fa 100644 --- a/app/src/main/java/com/example/defenseapplication/liveVideo/WiFiManagementActivity.kt +++ b/app/src/main/java/com/example/defenseapplication/liveVideo/WiFiManagementActivity.kt @@ -1,18 +1,36 @@ package com.example.defenseapplication.liveVideo +import android.Manifest +import android.content.BroadcastReceiver +import android.content.Context +import android.content.Intent +import android.content.IntentFilter +import android.content.pm.PackageManager +import android.net.wifi.ScanResult +import android.net.wifi.WifiManager import android.os.Bundle -import androidx.activity.enableEdgeToEdge +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 androidx.appcompat.app.AppCompatActivity -import androidx.core.view.ViewCompat -import androidx.core.view.WindowInsetsCompat +import androidx.core.app.ActivityCompat +import androidx.recyclerview.widget.LinearLayoutManager import com.example.defenseapplication.R -import com.example.defenseapplication.databinding.DeviceInfoActivityBinding -import com.example.defenseapplication.databinding.LinkedUserActivityBinding +import com.example.defenseapplication.adapter.WifiListAdapter +import com.example.defenseapplication.databinding.DialogWifiListBinding import com.example.defenseapplication.databinding.WifiManagementActivityBinding import com.gyf.immersionbar.ImmersionBar class WiFiManagementActivity : AppCompatActivity() { + private lateinit var binding: WifiManagementActivityBinding + private lateinit var wifiManager: WifiManager + private lateinit var wifiScanReceiver: BroadcastReceiver + private var popupWindow: PopupWindow? = null + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = WifiManagementActivityBinding.inflate(layoutInflater) @@ -24,5 +42,118 @@ class WiFiManagementActivity : AppCompatActivity() { binding.ivBack.setOnClickListener { finish() } + + binding.btnSelectWifi.setOnClickListener { + showWifiListDialog() + } + + binding.etWifiName.addTextChangedListener(object : TextWatcher { + override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {} + + override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {} + + override fun afterTextChanged(s: Editable?) { + updateBottomButtonVisibility() + } + }) + wifiManager = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager + + wifiScanReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) + if (success) { + updateWifiList() + } + } + } + //点击确定成功失败吐司 + binding.btnConfirm.setOnClickListener { +// if(){ +// ToastUtils.showSuccess(this, getString(R.string.wifi_connection_success)) +// }else{ +// ToastUtils.showError(this, getString(R.string.wifi_connection_failed)) +// } + + } + } + + private fun showWifiListDialog() { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED || + ActivityCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE), + 1001) + return + } + + if (!wifiManager.isWifiEnabled) { + wifiManager.isWifiEnabled = true + } + + wifiManager.startScan() + + val dialogBinding = DialogWifiListBinding.inflate(LayoutInflater.from(this)) + popupWindow = PopupWindow( + dialogBinding.root, + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT + ).apply { + isFocusable = true + setBackgroundDrawable(null) + setOnDismissListener { + binding.maskView.visibility = android.view.View.GONE + } + showAtLocation(window.decorView, Gravity.BOTTOM, 0, 0) + } + + binding.maskView.visibility = android.view.View.VISIBLE + + dialogBinding.rvWifiList.layoutManager = LinearLayoutManager(this@WiFiManagementActivity) + + val wifiList = getWifiList() + dialogBinding.rvWifiList.adapter = WifiListAdapter(wifiList) { wifiName -> + binding.etWifiName.setText(wifiName) + popupWindow?.dismiss() + } + } + + private fun updateBottomButtonVisibility() { + val wifiName = binding.etWifiName.text.toString().trim() + binding.bottomButtonLayout.visibility = + if (wifiName.isNotEmpty()) android.view.View.VISIBLE else android.view.View.GONE + } + + private fun getWifiList(): List { + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) + != PackageManager.PERMISSION_GRANTED) { + return emptyList() + } + val results: List = wifiManager.scanResults + return results.map { it.SSID }.distinct() + } + + private fun updateWifiList() { + popupWindow?.contentView?.findViewById(R.id.rvWifiList)?.let { recyclerView -> + val wifiList = getWifiList() + recyclerView.adapter = WifiListAdapter(wifiList) { wifiName -> + binding.etWifiName.setText(wifiName) + popupWindow?.dismiss() + } + } + } + + override fun onStart() { + super.onStart() + val intentFilter = IntentFilter() + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) + registerReceiver(wifiScanReceiver, intentFilter) + } + + override fun onStop() { + super.onStop() + unregisterReceiver(wifiScanReceiver) + popupWindow?.dismiss() } } \ No newline at end of file diff --git a/app/src/main/res/drawable/check_box_selector.xml b/app/src/main/res/drawable/check_box_selector.xml new file mode 100644 index 0000000..3b67b1e --- /dev/null +++ b/app/src/main/res/drawable/check_box_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/add_linked_user_activity.xml b/app/src/main/res/layout/add_linked_user_activity.xml new file mode 100644 index 0000000..7a95740 --- /dev/null +++ b/app/src/main/res/layout/add_linked_user_activity.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/item_add_linked_user.xml b/app/src/main/res/layout/item_add_linked_user.xml new file mode 100644 index 0000000..a3c744a --- /dev/null +++ b/app/src/main/res/layout/item_add_linked_user.xml @@ -0,0 +1,23 @@ + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/wifi_management_activity.xml b/app/src/main/res/layout/wifi_management_activity.xml index 7206d2d..541792b 100644 --- a/app/src/main/res/layout/wifi_management_activity.xml +++ b/app/src/main/res/layout/wifi_management_activity.xml @@ -1,36 +1,141 @@ - - + android:layout_height="match_parent" + android:orientation="vertical"> - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/values-zh/strings.xml b/app/src/main/res/values-zh/strings.xml index cce4d72..863d088 100644 --- a/app/src/main/res/values-zh/strings.xml +++ b/app/src/main/res/values-zh/strings.xml @@ -206,7 +206,8 @@ 设备型号 自动布防开始时间 自动布防结束时间 - + 请至少选择一个用户 + 已选择 %d 个用户,语音 个人信息 @@ -231,8 +232,8 @@ 请输入WiFi密码 连接 连接中... - 连接失败 - 连接成功 + WiFi连接失败 + WiFi连接成功 提示 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 39c6d1c..50eaf27 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -181,6 +181,8 @@ Device model Auto arm start time Auto arm End time + Please select at least one user + %d user(s) selected, voice @@ -203,8 +205,8 @@ Enter WiFi password Connect Connecting... - Connection failed - Connected successfully + WiFi Connection failed + WiFi Connected successfully Tip