zhaoyadi vor 8 Monaten
Ursprung
Commit
4dd5140ac8

+ 4 - 0
xiaodou/src/main/AndroidManifest.xml

@@ -18,6 +18,10 @@
 
     <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
     <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+    <uses-permission
+        android:name="android.permission.NEARBY_WIFI_DEVICES"
+        android:usesPermissionFlags="neverForLocation"
+        tools:targetApi="s" />
 
     <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
     <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

+ 143 - 33
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEService.kt

@@ -4,7 +4,11 @@ import android.annotation.SuppressLint
 import android.app.Service
 import android.bluetooth.BluetoothAdapter
 import android.bluetooth.BluetoothDevice
+import android.bluetooth.BluetoothGatt
+import android.bluetooth.BluetoothGattCallback
+import android.bluetooth.BluetoothGattCharacteristic
 import android.bluetooth.BluetoothManager
+import android.bluetooth.BluetoothProfile
 import android.bluetooth.le.ScanCallback
 import android.bluetooth.le.ScanFilter
 import android.bluetooth.le.ScanResult
@@ -19,7 +23,10 @@ import android.util.Log
 import androidx.core.app.NotificationChannelCompat
 import androidx.core.app.NotificationCompat
 import androidx.core.app.NotificationManagerCompat
+import androidx.core.content.ContextCompat
+import com.luojigou.xiaodou.ble.XDBLEUtils
 import com.luojigou.xiaodou.ble.XDScanBLEDevice
+import com.luojigou.xiaodou.wifi.XDScanWifiInfo
 import java.util.UUID
 import kotlin.concurrent.thread
 
@@ -29,10 +36,16 @@ class XDScanBLEService : Service() {
     companion object {
         const val ACTION_START_SCAN = "com.luojigou.xiaodou.ble.ACTION_START_SCAN"
         const val ACTION_STOP_SCAN = "com.luojigou.xiaodou.ble.ACTION_STOP_SCAN"
+        const val ACTION_RESTART_SCAN = "com.luojigou.xiaodou.ble.ACTION_RESTART_SCAN"
 
         const val ACTION_SCAN_RESULT = "com.luojigou.xiaodou.ble.ACTION_SCAN_RESULT"
         const val ACTION_SCAN_RESULT_DATA = "com.luojigou.xiaodou.ble.ACTION_SCAN_RESULT_DATA"
 
+        const val ACTION_SELECT_BLE_DEVICE = "com.luojigou.xiaodou.ble.ACTION_SELECT_BLE_DEVICE"
+        const val ACTION_SELECT_BLE_DEVICE_DATA = "com.luojigou.xiaodou.ble.ACTION_SELECT_BLE_DEVICE_DATA"
+        const val ACTION_SELECT_WIFI_DEVICE = "com.luojigou.xiaodou.ble.ACTION_SELECT_WIFI_DEVICE"
+        const val ACTION_SELECT_WIFI_DEVICE_DATA = "com.luojigou.xiaodou.ble.ACTION_SELECT_WIFI_DEVICE_DATA"
+
         const val ACTION_CONNECT_WIFI = "com.luojigou.xiaodou.ble.ACTION_CONNECT_WIFI"
         const val ACTION_CONNECT_WIFI_RESULT_ERROR = "com.luojigou.xiaodou.ble.ACTION_CONNECT_WIFI_RESULT_ERROR"
         const val ACTION_CONNECT_WIFI_RESULT_SUCCESS = "com.luojigou.xiaodou.ble.ACTION_CONNECT_WIFI_RESULT_SUCCESS"
@@ -45,13 +58,71 @@ class XDScanBLEService : Service() {
         private val bleChannelName = "BLE-CHANNEL"
     }
 
-    private val deviceMap: MutableMap<XDScanBLEDevice, BluetoothDevice> = HashMap()
+    private val bluetoothDevices: MutableMap<XDScanBLEDevice, BluetoothDevice> = HashMap()
 
     private lateinit var bluetoothManager: BluetoothManager
 
     private lateinit var bluetoothAdapter: BluetoothAdapter
 
-    private lateinit var bluetoothReceiver: BroadcastReceiver
+    /// 选择要连接的蓝牙设备
+    private var selectBluetoothDevice: XDScanBLEDevice? = null
+
+    /// 选择要连接的wifi网络
+    private var selectWifiInfo: XDScanWifiInfo? = null
+
+    private var bluetoothReceiver: BroadcastReceiver = object : BroadcastReceiver() {
+        override fun onReceive(context: Context?, intent: Intent) {
+            when (intent.action) {
+                ACTION_RESTART_SCAN -> {
+                    bluetoothDevices.clear()
+                    startScan()
+                }
+
+                ACTION_CONNECT_WIFI -> {
+                    val device = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                        intent.getParcelableExtra("device", XDScanBLEDevice::class.java)
+                    } else {
+                        intent.getParcelableExtra<XDScanBLEDevice>("device")
+                    }
+                    val ssid = intent.getStringExtra("ssid")
+                    val password = intent.getStringExtra("password")
+                    connectWifi(device!!, ssid!!, password!!)
+                }
+
+                ACTION_SELECT_BLE_DEVICE -> {
+                    val bleDevice = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                        intent.getParcelableExtra(
+                            ACTION_SELECT_BLE_DEVICE_DATA, XDScanBLEDevice::class.java
+                        )
+                    } else {
+                        intent.getParcelableExtra<XDScanBLEDevice>(ACTION_SELECT_BLE_DEVICE)
+                    }
+
+                    if (bleDevice != null) {
+                        selectBluetoothDevice = bleDevice
+                        selectWifiInfo = null
+                    }
+                }
+
+                ACTION_SELECT_WIFI_DEVICE -> {
+                    val wifiInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                        intent.getParcelableExtra(
+                            ACTION_SELECT_WIFI_DEVICE_DATA, XDScanWifiInfo::class.java
+                        )
+                    } else {
+                        intent.getParcelableExtra<XDScanWifiInfo>(ACTION_SELECT_WIFI_DEVICE)
+                    }
+
+                    if (wifiInfo != null) {
+                        selectWifiInfo = wifiInfo
+                        if (selectBluetoothDevice != null) {
+                            connectWifi(selectBluetoothDevice!!, wifiInfo.ssid, wifiInfo.password)
+                        }
+                    }
+                }
+            }
+        }
+    }
 
     @Volatile
     private var bleScanning = false
@@ -65,9 +136,9 @@ class XDScanBLEService : Service() {
     private val bleScanCallback = object : ScanCallback() {
         override fun onScanResult(callbackType: Int, result: ScanResult) {
             super.onScanResult(callbackType, result)
-            val oldSize = deviceMap.size
+            val oldSize = bluetoothDevices.size
             addDevice(result)
-            val newSize = deviceMap.size
+            val newSize = bluetoothDevices.size
 
             if (oldSize != newSize) {
                 sendResult()
@@ -76,9 +147,9 @@ class XDScanBLEService : Service() {
 
         override fun onBatchScanResults(results: MutableList<ScanResult>) {
             super.onBatchScanResults(results)
-            val oldSize = deviceMap.size
+            val oldSize = bluetoothDevices.size
             results.forEach { addDevice(it) }
-            val newSize = deviceMap.size
+            val newSize = bluetoothDevices.size
 
             if (oldSize != newSize) {
                 sendResult()
@@ -103,8 +174,8 @@ class XDScanBLEService : Service() {
                     addressType = device.type.toString(),
                 )
 
-                if (!deviceMap.contains(device)) {
-                    deviceMap[device] = result.device
+                if (!bluetoothDevices.contains(device)) {
+                    bluetoothDevices[device] = result.device
                 }
             }
 
@@ -129,8 +200,8 @@ class XDScanBLEService : Service() {
             }
 
             val notification = NotificationCompat.Builder(this, bleChannelName)
-                .setContentTitle("XiaoDou")
-                .setContentText("XiaoDou is running")
+                .setContentTitle("小逗AI设备配网服务")
+                .setContentText("正在为小逗AI设备配网中")
                 .setSmallIcon(android.R.drawable.stat_sys_data_bluetooth)
                 .setChannelId(bleChannelName)
                 .build()
@@ -143,28 +214,14 @@ class XDScanBLEService : Service() {
         bluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
         bluetoothAdapter = bluetoothManager.adapter
 
-        bluetoothReceiver = object : BroadcastReceiver() {
-            override fun onReceive(context: Context?, intent: Intent) {
-                when (intent.action) {
-                    ACTION_START_SCAN -> {
-                        startScan()
-                    }
-
-                    ACTION_STOP_SCAN -> {
-                        stopScan()
-                    }
-                }
-            }
-        }
-
         val intentFilter = IntentFilter()
-        intentFilter.addAction(ACTION_START_SCAN)
-        intentFilter.addAction(ACTION_STOP_SCAN)
-        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            registerReceiver(bluetoothReceiver, intentFilter, Context.RECEIVER_NOT_EXPORTED)
-        }else{
-            registerReceiver(bluetoothReceiver, intentFilter)
-        }
+        intentFilter.addAction(ACTION_RESTART_SCAN)
+        intentFilter.addAction(ACTION_SELECT_BLE_DEVICE)
+        intentFilter.addAction(ACTION_SELECT_WIFI_DEVICE)
+        intentFilter.addAction(ACTION_CONNECT_WIFI)
+        ContextCompat.registerReceiver(
+            this, bluetoothReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED
+        )
 
         startScan()
     }
@@ -180,15 +237,18 @@ class XDScanBLEService : Service() {
                 bleScanFilters, bleScanSettings, bleScanCallback
             )
         }
-        //        delayClose()
+        delayClose()
     }
 
     private fun delayClose() {
         thread {
+            sendBroadcast(Intent(ACTION_START_SCAN))
             Thread.sleep(5000)
             if (bleScanning) {
                 stopScan()
             }
+            Thread.sleep(3000)
+            sendBroadcast(Intent(ACTION_STOP_SCAN))
         }
     }
 
@@ -202,11 +262,61 @@ class XDScanBLEService : Service() {
     private fun sendResult() {
         val intent = Intent(ACTION_SCAN_RESULT)
         intent.putParcelableArrayListExtra(
-            ACTION_SCAN_RESULT_DATA, ArrayList(deviceMap.keys)
+            ACTION_SCAN_RESULT_DATA, ArrayList(bluetoothDevices.keys)
         )
         sendBroadcast(intent)
     }
 
+    private fun connectWifi(device: XDScanBLEDevice, ssid: String, password: String) {
+        val bleDevice = bluetoothDevices[device] ?: return
+
+        val gattCallback = object : BluetoothGattCallback() {
+            override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
+                super.onConnectionStateChange(gatt, status, newState)
+                Log.d("XDScanBLEGattCallback", "onConnectionStateChange: $status,$newState")
+                when (newState) {
+                    BluetoothProfile.STATE_CONNECTED -> {
+                        gatt.discoverServices()
+                    }
+
+                    BluetoothProfile.STATE_DISCONNECTED -> {
+                        gatt.close()
+                    }
+                }
+            }
+
+            override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) {
+                super.onServicesDiscovered(gatt, status)
+                Log.d("XDScanBLEGattCallback", "onServicesDiscovered: $status")
+
+                when (status) {
+                    BluetoothGatt.GATT_SUCCESS -> {
+                        val service = gatt.getService(wifiConnectServiceUUID)!!
+
+                        val notifyCharacteristic = service.getCharacteristic(wifiConnectNotifyUUID)!!
+                        val writeCharacteristic = service.getCharacteristic(wifiConnectWriteUUID)!!
+
+                        gatt.setCharacteristicNotification(notifyCharacteristic, true)
+
+
+                    }
+                }
+            }
+
+            override fun onCharacteristicChanged(
+                gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, value: ByteArray
+            ) {
+                super.onCharacteristicChanged(gatt, characteristic, value)
+                val result = XDBLEUtils.parseConnectResponse(value)
+                Log.d("XDScanBLEService", "onCharacteristicChanged: $result")
+            }
+        }
+
+        val connectGatt = bleDevice.connectGatt(
+            this, false, gattCallback, BluetoothDevice.TRANSPORT_LE
+        )
+    }
+
     override fun onDestroy() {
         unregisterReceiver(bluetoothReceiver)
         stopScan()

+ 2 - 2
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanWifiActivity.kt

@@ -46,7 +46,6 @@ class XDScanWifiActivity : AppCompatActivity(), XDScanWifiStatus.Host {
 
     override fun getWifiManager(): WifiManager = wifiManager
 
-
     private fun setFragment(fragment: Fragment) {
         val fragmentManager = supportFragmentManager;
         val beginTransaction = fragmentManager.beginTransaction()
@@ -58,7 +57,8 @@ class XDScanWifiActivity : AppCompatActivity(), XDScanWifiStatus.Host {
         beginTransaction.commit()
     }
 
-    override fun onStatusChanged(status: XDScanWifiStatus) = checkWifiPermissionAndEnable()
+    override fun onStatusChanged(status: XDScanWifiStatus) =
+        checkWifiPermissionAndEnable()
 
     private fun setupReceiver() {
         val intentFilter = IntentFilter()

+ 13 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEGattCallback.kt

@@ -0,0 +1,13 @@
+package com.luojigou.xiaodou.ble
+
+import android.annotation.SuppressLint
+import android.bluetooth.BluetoothGatt
+import android.bluetooth.BluetoothGattCallback
+import android.bluetooth.BluetoothProfile
+import android.util.Log
+import com.luojigou.xiaodou.XDScanBLEService
+
+@SuppressLint("MissingPermission")
+class XDScanBLEGattCallback : BluetoothGattCallback() {
+
+}

+ 35 - 29
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLENormalFragment.kt

@@ -5,7 +5,6 @@ import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
 import android.content.IntentFilter
-import android.os.Build
 import android.os.Bundle
 import android.view.LayoutInflater
 import android.view.View
@@ -13,6 +12,7 @@ import android.view.ViewGroup
 import android.widget.Button
 import androidx.activity.result.ActivityResultLauncher
 import androidx.activity.result.contract.ActivityResultContracts
+import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import androidx.recyclerview.widget.GridLayoutManager
 import androidx.recyclerview.widget.RecyclerView
@@ -20,6 +20,9 @@ import com.luojigou.xiaodou.R
 import com.luojigou.xiaodou.XDScanBLEService
 import com.luojigou.xiaodou.XDScanBLEService.Companion.ACTION_SCAN_RESULT
 import com.luojigou.xiaodou.XDScanBLEService.Companion.ACTION_SCAN_RESULT_DATA
+import com.luojigou.xiaodou.XDScanBLEService.Companion.ACTION_START_SCAN
+import com.luojigou.xiaodou.XDScanBLEService.Companion.ACTION_STOP_SCAN
+import com.luojigou.xiaodou.XDScanWifiActivity
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.MainScope
 
@@ -27,14 +30,18 @@ import kotlinx.coroutines.MainScope
 class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment(),
     CoroutineScope by MainScope() {
     private val adapter = XDScanBLEAdapter {
-        //        launch {
-        //            host.getManager().connectWifi(it.device, "zdzh", "zdzh00000")
-        //        }
+        val intent = Intent(XDScanBLEService.ACTION_SELECT_BLE_DEVICE)
+        intent.putExtra(XDScanBLEService.ACTION_SELECT_BLE_DEVICE_DATA, it)
+        requireActivity().sendBroadcast(intent)
+        XDScanWifiActivity.start(requireContext())
     }
 
     private lateinit var selectWifi: ActivityResultLauncher<Intent>
 
     private lateinit var bluetoothReceiver: BroadcastReceiver
+
+    private lateinit var restartScanButton: Button
+
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
     ): View? {
@@ -45,11 +52,11 @@ class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment
         super.onViewCreated(view, savedInstanceState)
 
         selectWifi = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
-
+            it.data
         }
 
-        val button = view.findViewById<Button>(R.id.scan_again)
-        button.setOnClickListener { restartScan() }
+        restartScanButton = view.findViewById<Button>(R.id.scan_again)
+        restartScanButton.setOnClickListener { restartScan() }
 
         val recyclerView = view.findViewById<RecyclerView>(R.id.scan_list)
         val layoutManager = GridLayoutManager(requireContext(), 2, RecyclerView.VERTICAL, false)
@@ -67,6 +74,14 @@ class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment
         bluetoothReceiver = object : BroadcastReceiver() {
             override fun onReceive(context: Context?, intent: Intent) {
                 when (intent.action) {
+                    ACTION_START_SCAN -> {
+                        restartScanButton.visibility = View.INVISIBLE
+                    }
+
+                    ACTION_STOP_SCAN -> {
+                        restartScanButton.visibility = View.VISIBLE
+                    }
+
                     ACTION_SCAN_RESULT -> {
                         val list = intent.getParcelableArrayListExtra(
                             ACTION_SCAN_RESULT_DATA, XDScanBLEDevice::class.java
@@ -81,25 +96,19 @@ class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment
         }
 
         val intentFilter = IntentFilter()
+        intentFilter.addAction(ACTION_START_SCAN)
+        intentFilter.addAction(ACTION_STOP_SCAN)
         intentFilter.addAction(ACTION_SCAN_RESULT)
-        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
-            requireContext().registerReceiver(
-                bluetoothReceiver,
-                intentFilter,
-                Context.RECEIVER_NOT_EXPORTED
-            )
-        } else {
-            requireContext().registerReceiver(
-                bluetoothReceiver,
-                intentFilter,
-            )
-        }
-
+        ContextCompat.registerReceiver(
+            requireContext(),
+            bluetoothReceiver,
+            intentFilter,
+            ContextCompat.RECEIVER_EXPORTED,
+        )
 
-        requireContext().startForegroundService(
-            Intent(
-                requireContext(), XDScanBLEService::class.java
-            )
+        ContextCompat.startForegroundService(
+            requireContext(),
+            Intent(requireContext(), XDScanBLEService::class.java),
         )
     }
 
@@ -113,11 +122,8 @@ class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment
 
     private fun restartScan() {
         setAdapterValue(listOf())
-        requireActivity().sendBroadcast(
-            Intent(
-                XDScanBLEService.ACTION_START_SCAN
-            )
-        )
+        val intent = Intent(XDScanBLEService.ACTION_RESTART_SCAN)
+        requireActivity().sendBroadcast(intent)
     }
 
     private fun setAdapterValue(list: List<XDScanBLEDevice>) {

+ 24 - 18
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiAdapter.kt

@@ -1,6 +1,7 @@
 package com.luojigou.xiaodou.wifi
 
 import android.net.wifi.ScanResult
+import android.os.Build
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
@@ -9,36 +10,41 @@ import android.widget.TextView
 import androidx.recyclerview.widget.RecyclerView
 import com.luojigou.xiaodou.R
 
-class XDScanWifiAdapter : RecyclerView.Adapter<XDScanWifiAdapter.ViewHolder>() {
+class XDScanWifiAdapter(
+    private val itemClickListener: (ScanResult) -> Unit,
+) : RecyclerView.Adapter<XDScanWifiAdapter.ViewHolder>() {
     private val list: MutableList<ScanResult> = ArrayList()
 
     override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
-        val itemView: View =
-            LayoutInflater.from(parent.context).inflate(R.layout.item_wifi, parent, false)
+        val itemView: View = LayoutInflater.from(parent.context)
+            .inflate(R.layout.item_wifi, parent, false)
         return ViewHolder(itemView)
     }
 
-    override fun getItemCount(): Int = list.size
+    override fun getItemCount(): Int =
+        list.size
 
     override fun onBindViewHolder(holder: ViewHolder, position: Int) {
         val item = list[position]
 
-        //        holder.alias.text = item.wifiSsid
-        //        holder.name.text = item.device.address
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            holder.name.text = item.wifiSsid?.toString()
+        } else {
+            holder.name.text = item.BSSID
+        }
     }
 
-    fun setValues(values: List<ScanResult>) {
-        list.clear()
-        list.addAll(values)
-        notifyDataSetChanged()
-    }
-
-    fun addValue(value: ScanResult) { //        if (value.device.name != null) {
-        //            if (list.firstOrNull { it.device.address == value.device.address } == null) {
-        //                list.add(value)
-        //                notifyItemChanged(list.size - 1)
-        //            }
-        //        }
+    fun addValue(result: ScanResult) {
+        val ssid = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+            result.wifiSsid.toString()
+        } else {
+            result.BSSID
+        }
+
+        if (ssid != null && result.frequency in 2400..2500) {
+            list.add(result)
+            notifyItemChanged(list.size - 1)
+        }
     }
 
     class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {

+ 9 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiEntity.kt

@@ -0,0 +1,9 @@
+package com.luojigou.xiaodou.wifi
+
+data class XDScanWifiEntity(
+    val ssid:String,
+    val bssid:String,
+    val rssi:Int,
+    val level:Int,
+    val frequency:Int,
+)

+ 40 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiInfo.kt

@@ -0,0 +1,40 @@
+package com.luojigou.xiaodou.wifi
+
+import android.os.Parcel
+import android.os.Parcelable
+
+data class XDScanWifiInfo(
+    val ssid: String,
+    val password: String,
+) : Parcelable {
+
+    companion object {
+        @JvmField
+        val CREATOR: Parcelable.Creator<XDScanWifiInfo> = object :
+            Parcelable.Creator<XDScanWifiInfo> {
+            override fun createFromParcel(source: Parcel): XDScanWifiInfo {
+                return XDScanWifiInfo(
+                    source.readString()!!,
+                    source.readString()!!,
+                )
+            }
+
+            override fun newArray(size: Int): Array<XDScanWifiInfo?> {
+                return arrayOfNulls(size)
+            }
+        }
+    }
+
+    override fun writeToParcel(dest: Parcel, flags: Int) {
+        dest.writeString(ssid)
+        dest.writeString(password)
+    }
+
+    override fun describeContents(): Int {
+        return 0
+    }
+
+    override fun toString(): String {
+        return "XDScanWifiInfo(ssid='$ssid', password='$password')"
+    }
+}

+ 42 - 11
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiNormalFragment.kt

@@ -4,26 +4,26 @@ import android.annotation.SuppressLint
 import android.content.BroadcastReceiver
 import android.content.Context
 import android.content.Intent
-import android.net.wifi.ScanResult
+import android.content.IntentFilter
+import android.net.wifi.WifiManager
 import android.os.Bundle
-import android.util.Log
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
+import android.widget.Button
+import androidx.core.content.ContextCompat
 import androidx.fragment.app.Fragment
 import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
 import com.luojigou.xiaodou.R
 
 @SuppressLint("MissingPermission")
 class XDScanWifiNormalFragment(private val host: XDScanWifiStatus.Host) : Fragment() {
-    private val wifiScanReceiver = object : BroadcastReceiver() {
-        override fun onReceive(context: Context?, intent: Intent?) {
-            val scanResults: List<ScanResult> = host.getWifiManager().scanResults
-        }
-    }
+    private lateinit var wifiScanReceiver: BroadcastReceiver
+
+    private val adapter = XDScanWifiAdapter {
 
-    private val adapter by lazy { XDScanWifiAdapter() }
-    private val layoutManager by lazy { LinearLayoutManager(requireContext()) }
+    }
 
     override fun onCreateView(
         inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
@@ -34,16 +34,47 @@ class XDScanWifiNormalFragment(private val host: XDScanWifiStatus.Host) : Fragme
     override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
         super.onViewCreated(view, savedInstanceState)
 
+
+        val restartScanButton = view.findViewById<Button>(R.id.scan_again) //        restartScanButton.setOnClickListener { restartScan() }
+
+        val recyclerView = view.findViewById<RecyclerView>(R.id.scan_list)
+        val layoutManager = LinearLayoutManager(requireContext(), RecyclerView.VERTICAL, false)
+        recyclerView.layoutManager = layoutManager
+        recyclerView.adapter = adapter
     }
 
     override fun onAttach(context: Context) {
         super.onAttach(context)
 
-        val configuredNetworks = host.getWifiManager().configuredNetworks
-        Log.d("XDScanWifiNormalFragment", "onAttach: ")
+        wifiScanReceiver = object : BroadcastReceiver() {
+            override fun onReceive(context: Context?, intent: Intent) {
+                when (intent.action) {
+                    WifiManager.SCAN_RESULTS_AVAILABLE_ACTION -> {
+                        if (intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)) {
+                            val scanResults = host.getWifiManager().scanResults
+
+                            scanResults.forEach {
+                                adapter.addValue(it)
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        val intentFilter = IntentFilter().apply {
+            addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
+        }
+
+        ContextCompat.registerReceiver(
+            requireContext(), wifiScanReceiver, intentFilter, ContextCompat.RECEIVER_EXPORTED
+        )
+
+        host.getWifiManager().startScan()
     }
 
     override fun onDetach() {
+        requireContext().unregisterReceiver(wifiScanReceiver)
         super.onDetach()
     }
 }

+ 10 - 2
xiaodou/src/main/res/layout/fragment_scanwifi_normal.xml

@@ -4,9 +4,17 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
+
     <androidx.recyclerview.widget.RecyclerView
         android:id="@+id/scan_list"
         android:layout_width="match_parent"
-        android:layout_height="match_parent"
-        android:orientation="vertical" />
+        android:layout_height="match_parent" />
+
+    <Button
+        android:id="@+id/scan_again"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:text="重新扫描"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintRight_toRightOf="parent" />
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 0
xiaodou/src/main/res/layout/item_wifi.xml

@@ -17,6 +17,7 @@
         android:id="@+id/tv_wifi_name"
         android:layout_width="0dp"
         android:layout_height="0dp"
+        android:gravity="center_vertical"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintLeft_toRightOf="@id/iv_wifi_rssi"
         app:layout_constraintRight_toRightOf="parent"