Jelajahi Sumber

first commit

zhaoyadi 8 bulan lalu
induk
melakukan
3018fae8c9
34 mengubah file dengan 868 tambahan dan 81 penghapusan
  1. 17 3
      xiaodou/src/main/AndroidManifest.xml
  2. 15 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDBindFailureActivity.kt
  3. 11 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDBindSuccessActivity.kt
  4. 13 37
      xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEActivity.kt
  5. 55 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEAdapter.kt
  6. 32 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEService.kt
  7. 115 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDScanWifiActivity.kt
  8. 48 0
      xiaodou/src/main/java/com/luojigou/xiaodou/XDScanWifiAdapter.kt
  9. 39 0
      xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEDisableFragment.kt
  10. 36 0
      xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLENormalFragment.kt
  11. 7 0
      xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLENotSupportFragment.kt
  12. 57 0
      xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEPermissionFragment.kt
  13. 16 0
      xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEStatus.kt
  14. 46 0
      xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiDisableFragment.kt
  15. 50 0
      xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiNormalFragment.kt
  16. 54 0
      xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiPermissionFragment.kt
  17. 16 0
      xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiStatus.kt
  18. 17 0
      xiaodou/src/main/res/drawable/wifi_disable.xml
  19. 17 0
      xiaodou/src/main/res/drawable/wifi_permission.xml
  20. 6 0
      xiaodou/src/main/res/layout/activity_bind_failure.xml
  21. 6 0
      xiaodou/src/main/res/layout/activity_bind_success.xml
  22. 2 40
      xiaodou/src/main/res/layout/activity_scanble.xml
  23. 12 0
      xiaodou/src/main/res/layout/activity_scanwifi.xml
  24. 30 0
      xiaodou/src/main/res/layout/fragment_scanble_disable.xml
  25. 6 0
      xiaodou/src/main/res/layout/fragment_scanble_normal.xml
  26. 6 0
      xiaodou/src/main/res/layout/fragment_scanble_not_support.xml
  27. 30 0
      xiaodou/src/main/res/layout/fragment_scanble_permission.xml
  28. 30 0
      xiaodou/src/main/res/layout/fragment_scanwifi_disable.xml
  29. 11 0
      xiaodou/src/main/res/layout/fragment_scanwifi_normal.xml
  30. 30 0
      xiaodou/src/main/res/layout/fragment_scanwifi_permission.xml
  31. 25 0
      xiaodou/src/main/res/layout/item_ble.xml
  32. 6 0
      xiaodou/src/main/res/layout/item_wifi.xml
  33. 6 0
      xiaodou/src/main/res/layout/item_wifi_add.xml
  34. 1 1
      xiaodou/src/main/res/values/themes.xml

+ 17 - 3
xiaodou/src/main/AndroidManifest.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools">
 
     <uses-permission
         android:name="android.permission.BLUETOOTH"
@@ -7,11 +8,20 @@
     <uses-permission
         android:name="android.permission.BLUETOOTH_ADMIN"
         android:maxSdkVersion="30" />
-    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
-    <uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
+    <uses-permission
+        android:name="android.permission.BLUETOOTH_SCAN"
+        android:usesPermissionFlags="neverForLocation"
+        tools:targetApi="s" />
+
     <uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
     <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
 
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+
+    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
+
     <uses-feature
         android:name="android.hardware.bluetooth"
         android:required="true" />
@@ -23,6 +33,10 @@
         <activity
             android:name=".XDScanBLEActivity"
             android:theme="@style/XDTheme" />
+
+        <activity
+            android:name=".XDScanWifiActivity"
+            android:theme="@style/XDTheme" />
     </application>
 
 </manifest>

+ 15 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/XDBindFailureActivity.kt

@@ -0,0 +1,15 @@
+package com.luojigou.xiaodou
+
+import android.content.Context
+import android.net.wifi.WifiManager
+import android.os.Bundle
+import android.util.Log
+import androidx.appcompat.app.AppCompatActivity
+
+class XDBindFailureActivity : AppCompatActivity() {
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_bind_failure)
+  }
+}

+ 11 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/XDBindSuccessActivity.kt

@@ -0,0 +1,11 @@
+package com.luojigou.xiaodou
+
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+
+class XDBindSuccessActivity : AppCompatActivity() {
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_bind_success)
+    }
+}

+ 13 - 37
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEActivity.kt

@@ -18,19 +18,15 @@ import android.os.Bundle
 import android.util.Log
 import android.view.View
 import android.widget.Button
-import android.widget.ListView
 import android.widget.ProgressBar
 import android.widget.TextView
 import androidx.activity.result.contract.ActivityResultContracts
 import androidx.appcompat.app.AppCompatActivity
 import androidx.core.app.ActivityCompat
+import androidx.recyclerview.widget.RecyclerView
 
 
 class XDScanBLEActivity : AppCompatActivity() {
-    companion object {
-        const val REQUEST_ENABLE_BT = 10086
-    }
-
     private val permissions: Array<String> by lazy {
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
             arrayOf(
@@ -47,7 +43,7 @@ class XDScanBLEActivity : AppCompatActivity() {
 
     private lateinit var txtMsg: TextView
     private lateinit var btnScan: Button
-    private lateinit var listview: ListView
+    private lateinit var listview: RecyclerView
     private lateinit var progress: ProgressBar
 
     private val broadcastReceiver by lazy {
@@ -89,21 +85,14 @@ class XDScanBLEActivity : AppCompatActivity() {
 
     private var bluetoothAdapter: BluetoothAdapter? = null
 
-
-    private val requestMultiplePermissionLauncher = registerForActivityResult(
-        ActivityResultContracts.RequestMultiplePermissions()
-    ) { permissions: Map<String, Boolean> ->
-        val noGrantedPermissions = ArrayList<String>()
-        permissions.entries.forEach {
-            if (!it.value) {
-                noGrantedPermissions.add(it.key)
+    private val requestMultiplePermissionLauncher by lazy {
+        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
+            if (it.all { permission -> permission.value }) {
+                maybeSetupBluetooth()
+            } else {
+                setStatus(XDScanBLEStatus.Permission)
             }
         }
-        if (noGrantedPermissions.isEmpty()) {
-            maybeSetupBluetooth()
-        } else {
-            setStatus(XDScanBLEStatus.Permission)
-        }
     }
 
 
@@ -126,11 +115,11 @@ class XDScanBLEActivity : AppCompatActivity() {
             val deviceAddress = device.address
             val rssi = result.rssi
 
-            Log.d(
-                "XDScanBLEService",
-                "发现BLE设备: 名称 - $deviceName, 地址 - $deviceAddress, 信号强度 - $rssi"
-            )
-
+            //            Log.d(
+            //                "XDScanBLEService",
+            //                "发现BLE设备: 名称 - $deviceName, 地址 - $deviceAddress, 信号强度 - $rssi"
+            //            )
+            adapter.addValue(result)
         }
 
         override fun onScanFailed(errorCode: Int) {
@@ -144,18 +133,6 @@ class XDScanBLEActivity : AppCompatActivity() {
         super.onCreate(savedInstanceState)
         setContentView(R.layout.activity_scanble)
 
-        txtMsg = findViewById(R.id.scan_message)
-        btnScan = findViewById(R.id.scan_button)
-        listview = findViewById(R.id.scan_list)
-        progress = findViewById(R.id.scan_progress)
-
-        btnScan.setOnClickListener {
-            setStatus(XDScanBLEStatus.Scanning)
-            startScanBle()
-        }
-
-        setStatus(XDScanBLEStatus.Idle)
-        checkBluetoothPermission()
         registerReceiver(broadcastReceiver, IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED))
     }
 
@@ -197,7 +174,6 @@ class XDScanBLEActivity : AppCompatActivity() {
 
     @SuppressLint("MissingPermission")
     private fun startScanBle() {
-
         val settings =
             ScanSettings.Builder().setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY) // 或选择其他适合的扫描模式
                 .build()

+ 55 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEAdapter.kt

@@ -0,0 +1,55 @@
+package com.luojigou.xiaodou
+
+import android.annotation.SuppressLint
+import android.bluetooth.le.ScanResult
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+
+
+@SuppressLint("MissingPermission")
+class XDScanBLEAdapter : RecyclerView.Adapter<XDScanBLEAdapter.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_ble, parent, false)
+        return ViewHolder(itemView)
+    }
+
+    override fun getItemCount(): Int = list.size
+
+    override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+        val item = list[position]
+
+        holder.alias.text = item.device.name
+        holder.name.text = item.device.address
+        holder.itemView.setOnClickListener {
+            XDScanWifiActivity.start(holder.itemView.context)
+        }
+    }
+
+    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)
+            }
+        }
+    }
+
+    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+        val img = itemView.findViewById<ImageView>(R.id.iv_ble)
+        val alias = itemView.findViewById<TextView>(R.id.tv_ble_alias)
+        val name = itemView.findViewById<TextView>(R.id.tv_ble_name)
+    }
+}

+ 32 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanBLEService.kt

@@ -0,0 +1,32 @@
+package com.luojigou.xiaodou
+
+import android.annotation.SuppressLint
+import android.app.Service
+import android.content.Intent
+import android.os.Binder
+import android.os.IBinder
+import androidx.bluetooth.BluetoothLe
+import androidx.bluetooth.ScanFilter
+import androidx.bluetooth.ScanResult
+import kotlinx.coroutines.flow.Flow
+
+@SuppressLint("MissingPermission")
+class XDScanBLEService : Service() {
+    private val bluetoothLe: BluetoothLe by lazy { BluetoothLe(this) }
+
+    override fun onBind(intent: Intent?): IBinder {
+        return XDScanBLEBinder(this)
+    }
+
+    class XDScanBLEBinder(private val service: XDScanBLEService) : Binder() {
+        companion object {
+            private val filter: List<ScanFilter> = listOf(
+                ScanFilter()
+            )
+        }
+
+        suspend fun scanBle(): Flow<ScanResult> {
+            return service.bluetoothLe.scan(filter)
+        }
+    }
+}

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

@@ -0,0 +1,115 @@
+package com.luojigou.xiaodou
+
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.content.IntentFilter
+import android.content.pm.PackageManager
+import android.net.ConnectivityManager
+import android.net.wifi.WifiManager
+import android.os.Build
+import android.os.Bundle
+import androidx.appcompat.app.AppCompatActivity
+import androidx.fragment.app.Fragment
+import com.luojigou.xiaodou.wifi.XDScanWifiDisableFragment
+import com.luojigou.xiaodou.wifi.XDScanWifiNormalFragment
+import com.luojigou.xiaodou.wifi.XDScanWifiPermissionFragment
+import com.luojigou.xiaodou.wifi.XDScanWifiStatus
+
+class XDScanWifiActivity : AppCompatActivity(), XDScanWifiStatus.Host {
+    companion object {
+        fun start(context: Context) {
+            context.startActivity(Intent(context, XDScanWifiActivity::class.java))
+        }
+    }
+
+    private lateinit var wifiManager: WifiManager
+
+    private val disableFragment by lazy { XDScanWifiDisableFragment(this) }
+    private val normalFragment by lazy { XDScanWifiNormalFragment(this) }
+    private val permissionFragment by lazy { XDScanWifiPermissionFragment(this) }
+
+    private val wifiStatusReceiver = object : BroadcastReceiver() {
+        override fun onReceive(context: Context?, intent: Intent?) {
+            checkWifiPermissionAndEnable()
+        }
+    }
+
+    override fun onCreate(savedInstanceState: Bundle?) {
+        super.onCreate(savedInstanceState)
+        setContentView(R.layout.activity_scanwifi)
+
+        wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager
+        setupReceiver()
+        checkWifiPermissionAndEnable()
+    }
+
+    override fun getWifiManager(): WifiManager = wifiManager
+
+
+    private fun setFragment(fragment: Fragment) {
+        val fragmentManager = supportFragmentManager;
+        val beginTransaction = fragmentManager.beginTransaction()
+        if (fragmentManager.findFragmentById(R.id.fragment_container) == null) {
+            beginTransaction.add(R.id.fragment_container, fragment)
+        } else {
+            beginTransaction.replace(R.id.fragment_container, fragment)
+        }
+        beginTransaction.commit()
+    }
+
+    override fun onStatusChanged(status: XDScanWifiStatus) = checkWifiPermissionAndEnable()
+
+    private fun setupReceiver() {
+        val intentFilter = IntentFilter()
+        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        intentFilter.addAction("android.net.wifi.CONFIGURED_NETWORKS_CHANGE");
+        intentFilter.addAction("android.net.wifi.LINK_CONFIGURATION_CHANGED");
+        intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+        intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
+
+        registerReceiver(wifiStatusReceiver, intentFilter)
+    }
+
+    private fun teardownReceiver() {
+        unregisterReceiver(wifiStatusReceiver)
+    }
+
+    private fun checkWifiPermissionAndEnable() {
+        if (!checkPermissions()) {
+            setFragment(permissionFragment)
+            return
+        }
+
+        if (!checkAndOpenWifi()) {
+            setFragment(disableFragment)
+            return
+        }
+
+        setFragment(normalFragment)
+    }
+
+    private fun checkPermissions(): Boolean {
+        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            hasPermission(android.Manifest.permission.ACCESS_FINE_LOCATION) && hasPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            hasPermission(android.Manifest.permission.CHANGE_WIFI_STATE)
+        } else {
+            true
+        }
+    }
+
+    private fun hasPermission(permission: String): Boolean {
+        return checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED
+    }
+
+    private fun checkAndOpenWifi(): Boolean {
+        return wifiManager.wifiState != WifiManager.WIFI_STATE_DISABLED
+    }
+
+    override fun onDestroy() {
+        teardownReceiver()
+        super.onDestroy()
+    }
+}

+ 48 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/XDScanWifiAdapter.kt

@@ -0,0 +1,48 @@
+package com.luojigou.xiaodou
+
+import android.net.wifi.ScanResult
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+
+class XDScanWifiAdapter : 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_ble, parent, false)
+        return ViewHolder(itemView)
+    }
+
+    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
+    }
+
+    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)
+        //            }
+        //        }
+    }
+
+    class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+        val img = itemView.findViewById<ImageView>(R.id.iv_ble)
+        val alias = itemView.findViewById<TextView>(R.id.tv_ble_alias)
+        val name = itemView.findViewById<TextView>(R.id.tv_ble_name)
+    }
+}

+ 39 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEDisableFragment.kt

@@ -0,0 +1,39 @@
+package com.luojigou.xiaodou.ble
+
+import android.annotation.SuppressLint
+import android.bluetooth.BluetoothAdapter
+import android.content.Intent
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.fragment.app.Fragment
+import com.luojigou.xiaodou.R
+
+@SuppressLint("MissingPermission")
+class XDScanBLEDisableFragment(private val host: XDScanBLEStatus.Host) : Fragment() {
+    private val openBle: ActivityResultLauncher<Intent> =
+        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+            host.onStatusChanged(XDScanBLEStatus.Disabled)
+        }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View? {
+        return inflater.inflate(R.layout.fragment_scanwifi_disable, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val button = view.findViewById<Button>(R.id.btn_open)
+        button.setOnClickListener { checkAndOpenBle() }
+    }
+
+    private fun checkAndOpenBle() {
+        openBle.launch(Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE))
+    }
+}

+ 36 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLENormalFragment.kt

@@ -0,0 +1,36 @@
+package com.luojigou.xiaodou.ble
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.GridLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.luojigou.xiaodou.R
+import com.luojigou.xiaodou.XDScanBLEAdapter
+
+class XDScanBLENormalFragment(private val host: XDScanBLEStatus.Host) : Fragment() {
+    private val adapter = XDScanBLEAdapter()
+
+    private val layoutManager by lazy {
+        GridLayoutManager(requireContext(), 2, RecyclerView.VERTICAL, false)
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View? {
+        return super.onCreateView(inflater, container, savedInstanceState)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val recyclerView = view.findViewById<RecyclerView>(R.id.scan_list)
+
+        recyclerView.layoutManager = layoutManager
+        recyclerView.adapter = adapter
+    }
+
+
+}

+ 7 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLENotSupportFragment.kt

@@ -0,0 +1,7 @@
+package com.luojigou.xiaodou.ble
+
+import androidx.fragment.app.Fragment
+
+class XDScanBLENotSupportFragment(private val host: XDScanBLEStatus.Host) : Fragment() {
+
+}

+ 57 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEPermissionFragment.kt

@@ -0,0 +1,57 @@
+package com.luojigou.xiaodou.ble
+
+import android.Manifest
+import android.os.Build
+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.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.fragment.app.Fragment
+import com.luojigou.xiaodou.R
+
+class XDScanBLEPermissionFragment(private val host: XDScanBLEStatus.Host) : Fragment() {
+    private val requestPermission: ActivityResultLauncher<Array<String>> =
+        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
+            if (it.all { permission -> permission.value }) {
+                host.onStatusChanged(XDScanBLEStatus.Normal)
+            } else {
+                Log.e("XDScanWifiActivity", "requestPermission: 权限被拒绝")
+            }
+        }
+
+
+    private val permissions: Array<String> by lazy {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+            arrayOf(
+                Manifest.permission.BLUETOOTH_SCAN,
+                Manifest.permission.BLUETOOTH_ADVERTISE,
+                Manifest.permission.BLUETOOTH_CONNECT
+            )
+        } else {
+            arrayOf(
+                Manifest.permission.ACCESS_FINE_LOCATION
+            )
+        }
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View? {
+        return inflater.inflate(R.layout.fragment_scanwifi_disable, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val button = view.findViewById<Button>(R.id.btn_open)
+        button.setOnClickListener { requestPermission() }
+    }
+
+    private fun requestPermission() {
+        requestPermission.launch(permissions)
+    }
+}

+ 16 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/ble/XDScanBLEStatus.kt

@@ -0,0 +1,16 @@
+package com.luojigou.xiaodou.ble
+
+import android.net.wifi.WifiManager
+
+sealed class XDScanBLEStatus {
+    object Disabled : XDScanBLEStatus()
+    object Permission : XDScanBLEStatus()
+    object NotSupported : XDScanBLEStatus()
+    object Normal : XDScanBLEStatus()
+
+    interface Host {
+        fun onStatusChanged(status: XDScanBLEStatus)
+
+        fun getWifiManager(): WifiManager
+    }
+}

+ 46 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiDisableFragment.kt

@@ -0,0 +1,46 @@
+package com.luojigou.xiaodou.wifi
+
+import android.content.Intent
+import android.net.wifi.WifiManager
+import android.os.Build
+import android.os.Bundle
+import android.provider.Settings
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.Button
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.fragment.app.Fragment
+import com.luojigou.xiaodou.R
+
+class XDScanWifiDisableFragment(private val host: XDScanWifiStatus.Host) : Fragment() {
+    private val openWifi: ActivityResultLauncher<Intent> =
+        registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
+            host.onStatusChanged(XDScanWifiStatus.Disabled)
+        }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View {
+        return inflater.inflate(R.layout.fragment_scanwifi_disable, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val button = view.findViewById<Button>(R.id.btn_open)
+        button.setOnClickListener { checkAndOpenWifi() }
+    }
+
+    private fun checkAndOpenWifi() {
+        if (host.getWifiManager().wifiState == WifiManager.WIFI_STATE_DISABLED) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+                openWifi.launch(Intent(Settings.Panel.ACTION_WIFI))
+            } else {
+                host.getWifiManager().setWifiEnabled(true)
+                host.onStatusChanged(XDScanWifiStatus.Disabled)
+            }
+        }
+    }
+}

+ 50 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiNormalFragment.kt

@@ -0,0 +1,50 @@
+package com.luojigou.xiaodou.wifi
+
+import android.annotation.SuppressLint
+import android.content.BroadcastReceiver
+import android.content.Context
+import android.content.Intent
+import android.net.wifi.ScanResult
+import android.os.Bundle
+import android.util.Log
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.fragment.app.Fragment
+import androidx.recyclerview.widget.LinearLayoutManager
+import com.luojigou.xiaodou.R
+import com.luojigou.xiaodou.XDScanWifiAdapter
+
+@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 val adapter by lazy { XDScanWifiAdapter() }
+    private val layoutManager by lazy { LinearLayoutManager(requireContext()) }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View {
+        return inflater.inflate(R.layout.fragment_scanwifi_normal, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+    }
+
+    override fun onAttach(context: Context) {
+        super.onAttach(context)
+
+        val configuredNetworks = host.getWifiManager().configuredNetworks
+        Log.d("XDScanWifiNormalFragment", "onAttach: ")
+    }
+
+    override fun onDetach() {
+        super.onDetach()
+    }
+}

+ 54 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiPermissionFragment.kt

@@ -0,0 +1,54 @@
+package com.luojigou.xiaodou.wifi
+
+import android.os.Build
+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.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
+import androidx.fragment.app.Fragment
+import com.luojigou.xiaodou.R
+
+class XDScanWifiPermissionFragment(private val host: XDScanWifiStatus.Host) : Fragment() {
+    private val requestPermission: ActivityResultLauncher<Array<String>> =
+        registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
+            if (it.all { permission -> permission.value }) {
+                host.onStatusChanged(XDScanWifiStatus.Normal)
+            } else {
+                Log.e("XDScanWifiActivity", "requestPermission: 权限被拒绝")
+            }
+        }
+
+    private val permissions by lazy {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
+            arrayOf(
+                android.Manifest.permission.ACCESS_FINE_LOCATION,
+                android.Manifest.permission.CHANGE_WIFI_STATE
+            )
+        } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+            arrayOf(android.Manifest.permission.CHANGE_WIFI_STATE)
+        } else {
+            arrayOf()
+        }
+    }
+
+    override fun onCreateView(
+        inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?
+    ): View {
+        return inflater.inflate(R.layout.fragment_scanwifi_permission, container, false)
+    }
+
+    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
+        super.onViewCreated(view, savedInstanceState)
+
+        val button = view.findViewById<Button>(R.id.btn_open)
+        button.setOnClickListener { requestPermission() }
+    }
+
+    private fun requestPermission() {
+        requestPermission.launch(permissions)
+    }
+}

+ 16 - 0
xiaodou/src/main/java/com/luojigou/xiaodou/wifi/XDScanWifiStatus.kt

@@ -0,0 +1,16 @@
+package com.luojigou.xiaodou.wifi
+
+import android.net.wifi.WifiManager
+
+sealed class XDScanWifiStatus {
+    object Disabled : XDScanWifiStatus()
+    object Permission : XDScanWifiStatus()
+    object NotSupported : XDScanWifiStatus()
+    object Normal : XDScanWifiStatus()
+
+    interface Host {
+        fun onStatusChanged(status: XDScanWifiStatus)
+
+        fun getWifiManager(): WifiManager
+    }
+}

File diff ditekan karena terlalu besar
+ 17 - 0
xiaodou/src/main/res/drawable/wifi_disable.xml


File diff ditekan karena terlalu besar
+ 17 - 0
xiaodou/src/main/res/drawable/wifi_permission.xml


+ 6 - 0
xiaodou/src/main/res/layout/activity_bind_failure.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 0
xiaodou/src/main/res/layout/activity_bind_success.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 2 - 40
xiaodou/src/main/res/layout/activity_scanble.xml

@@ -4,47 +4,9 @@
     android:layout_width="match_parent"
     android:layout_height="match_parent">
 
-    <TextView
-        android:id="@+id/scan_message"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <Button
-        android:id="@+id/scan_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:text="扫描附近设备"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <ListView
-        android:id="@+id/scan_list"
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/fragment_container"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
-        android:visibility="gone" />
-
-    <ProgressBar
-        android:id="@+id/scan_progress"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:visibility="gone"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintLeft_toLeftOf="parent"
-        app:layout_constraintRight_toRightOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <ListView
-        android:id="@+id/scan_open_bluetooth"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
         app:layout_constraintBottom_toBottomOf="parent" />
-
 </androidx.constraintlayout.widget.ConstraintLayout>

+ 12 - 0
xiaodou/src/main/res/layout/activity_scanwifi.xml

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+    <androidx.fragment.app.FragmentContainerView
+        android:id="@+id/fragment_container"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        app:layout_constraintBottom_toBottomOf="parent" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
xiaodou/src/main/res/layout/fragment_scanble_disable.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/white">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:layout_width="200dp"
+            android:layout_height="300dp"
+            android:src="@drawable/wifi_disable" />
+
+        <Button
+            android:id="@+id/btn_open"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginVertical="16dp"
+            android:text="去打开" />
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 0
xiaodou/src/main/res/layout/fragment_scanble_normal.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 0
xiaodou/src/main/res/layout/fragment_scanble_not_support.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
xiaodou/src/main/res/layout/fragment_scanble_permission.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/white">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:layout_width="200dp"
+            android:layout_height="300dp"
+            android:src="@drawable/wifi_permission" />
+
+        <Button
+            android:id="@+id/btn_open"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginVertical="16dp"
+            android:text="去打开" />
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
xiaodou/src/main/res/layout/fragment_scanwifi_disable.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/white">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:layout_width="200dp"
+            android:layout_height="300dp"
+            android:src="@drawable/wifi_disable" />
+
+        <Button
+            android:id="@+id/btn_open"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginVertical="16dp"
+            android:text="去打开" />
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 11 - 0
xiaodou/src/main/res/layout/fragment_scanwifi_normal.xml

@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    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" />
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 30 - 0
xiaodou/src/main/res/layout/fragment_scanwifi_permission.xml

@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:background="@android:color/white">
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent">
+
+        <ImageView
+            android:layout_width="200dp"
+            android:layout_height="300dp"
+            android:src="@drawable/wifi_permission" />
+
+        <Button
+            android:id="@+id/btn_open"
+            android:layout_width="wrap_content"
+            android:layout_height="wrap_content"
+            android:layout_gravity="center_horizontal"
+            android:layout_marginVertical="16dp"
+            android:text="去打开" />
+    </LinearLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 25 - 0
xiaodou/src/main/res/layout/item_ble.xml

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical">
+
+    <ImageView
+        android:id="@+id/iv_ble"
+        android:layout_width="match_parent"
+        android:layout_height="200dp" />
+
+    <TextView
+        android:id="@+id/tv_ble_alias"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:text="adadafafafaf" />
+
+    <TextView
+        android:id="@+id/tv_ble_name"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:layout_gravity="center_horizontal"
+        android:text="111223" />
+</LinearLayout>

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

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 6 - 0
xiaodou/src/main/res/layout/item_wifi_add.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent">
+
+</androidx.constraintlayout.widget.ConstraintLayout>

+ 1 - 1
xiaodou/src/main/res/values/themes.xml

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
 <resources>
-    <style name="XDTheme" parent="Theme.AppCompat.Light.DarkActionBar">
+    <style name="XDTheme" parent="Theme.Material3.Light.NoActionBar">
     </style>
 </resources>

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini