From 10357761a67a49228013b7eb00f956a1718d194b Mon Sep 17 00:00:00 2001 From: pakls Date: Thu, 23 Jun 2022 02:33:34 +0800 Subject: [PATCH] [android] Add Soft-AP scanning using Android Wi-Fi Manager APIs. (#19787) * After Wi-Fi AP list has been populated in the spinner * The user can select one from the spinner and connect to it. * Support OPEN authentication, no key management, and no encryption. * After connected to the selected Wi-Fi AP * The user can then 'DISCOVER' the services around. * After an IP address and its discriminator has been received * The user can 'COMMISSION' the device. --- .../CHIPTool/app/src/main/AndroidManifest.xml | 2 + .../AddressCommissioningFragment.kt | 92 ++++++++++++++++++- .../layout/address_commissioning_fragment.xml | 20 +++- .../app/src/main/res/values/strings.xml | 2 + 4 files changed, 114 insertions(+), 2 deletions(-) diff --git a/src/android/CHIPTool/app/src/main/AndroidManifest.xml b/src/android/CHIPTool/app/src/main/AndroidManifest.xml index 9e7ee8657d45e9..ede1f0980aee60 100644 --- a/src/android/CHIPTool/app/src/main/AndroidManifest.xml +++ b/src/android/CHIPTool/app/src/main/AndroidManifest.xml @@ -9,6 +9,8 @@ + + () + private val wifiApList = ArrayList() + private var wifiApSsid = String() private val scope = CoroutineScope(Dispatchers.Main + Job()) override fun onCreateView( @@ -69,6 +81,84 @@ class AddressCommissioningFragment : Fragment() { discoverBtn.isEnabled = true } } + + wifiConnectBtn.setOnClickListener { _ -> + wifiConnectBtn.isEnabled = false + val context = getActivity() + val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager + + // TODO : filter SSID with Information Element, OPEN authentication + var config : WifiConfiguration = WifiConfiguration(); + config.SSID = "\"${wifiApSsid}\"" + config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE) + + Log.d(TAG, "Disconnect existing connection") + wifiManager.disconnect() + Log.d(TAG, "Add network ${config.SSID}") + var res = wifiManager.addNetwork(config) + if (res == -1) { + Log.d(TAG,"Add network failed") + } else { + var success = wifiManager.enableNetwork(res, true) + if (success) { + Log.d(TAG, "Enable network ${config.SSID} succeeded") + } else { + Log.d(TAG, "Enable network ${config.SSID} failed") + wifiConnectBtn.isEnabled = true + } + } + } + + wifiScanBtn.setOnClickListener { _ -> + wifiScanBtn.isEnabled = false + val context = getActivity() + val wifiManager = context?.getSystemService(Context.WIFI_SERVICE) as WifiManager + val wifiScanReceiver = object : BroadcastReceiver() { + override fun onReceive(context: Context, intent: Intent) { + Log.d(TAG, "Scan result event received") + val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false) + if (success) { + Log.d(TAG, "Scan succeeded") + val results = wifiManager.scanResults + updateWifiScanListSpinner(results) + } else { + Log.d(TAG, "Scan failed") + } + wifiScanBtn.isEnabled = true + } + } + + val intentFilter = IntentFilter() + intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION) + + context.registerReceiver(wifiScanReceiver, intentFilter) + val success = wifiManager.startScan() + if (!success) { + Log.d(TAG, "Scan not started") + // TODO: scan failure handling + } else { + Log.d(TAG, "Scan started") + } + } + } + + private fun updateWifiScanListSpinner(scanResults : MutableList) { + wifiApList.clear() + for (result in scanResults) { + if (result.SSID.toString().isNotEmpty()) + wifiApList.add("${result.SSID}, ${result.BSSID}, ${result.level}") + } + requireActivity().runOnUiThread { + wifiScanListSpinner.adapter = + ArrayAdapter(requireContext(), android.R.layout.simple_spinner_dropdown_item, wifiApList) + wifiScanListSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener { + override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) { + wifiApSsid = wifiApList[position].split(",")[0].trim() + Log.d(TAG, "ready to connect to $wifiApSsid") + } + override fun onNothingSelected(parent: AdapterView<*>) {} + } + } } private fun updateSpinner() { @@ -98,4 +188,4 @@ class AddressCommissioningFragment : Fragment() { fun newInstance(): AddressCommissioningFragment = AddressCommissioningFragment() } -} \ No newline at end of file +} diff --git a/src/android/CHIPTool/app/src/main/res/layout/address_commissioning_fragment.xml b/src/android/CHIPTool/app/src/main/res/layout/address_commissioning_fragment.xml index 4ff57d1767d7ed..b82df0400a7a45 100644 --- a/src/android/CHIPTool/app/src/main/res/layout/address_commissioning_fragment.xml +++ b/src/android/CHIPTool/app/src/main/res/layout/address_commissioning_fragment.xml @@ -84,6 +84,24 @@ app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/address_commissioning_fragment_flow"> +