在Android(API 30)中编程连接特定的WiFi网络

4

目的 尝试连接或切换到特定的WiFi网络,无需任何人工干预(除了用户名和密码)。

代码片段

MainActivity.kt

主要活动类:AppCompatActivity() {

private var lastSuggestedNetwork:WifiNetworkSuggestion? = null
var wifiManager:WifiManager? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    wifiManager = applicationContext.getSystemService(WIFI_SERVICE) as WifiManager
    val button = findViewById<Button>(R.id.button) // Just a button in the layout file
    button.setOnClickListener(View.OnClickListener {
        wifiManager!!.disconnect()
        connectUsingNetworkSuggestion(ssid = "AndroidWifi", password ="")
        wifiManager!!.reconnect()
    })
}

private fun connectUsingNetworkSuggestion(ssid: String, password: String) {
    val wifiNetworkSuggestion = WifiNetworkSuggestion.Builder()
        .setSsid(ssid)
        .setWpa2Passphrase(password)
        .build()
    val intentFilter =
        IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION);

    val broadcastReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            if (!intent.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                return
            }
            showToast("Connection Suggestion Succeeded")
        }
    }


    registerReceiver(broadcastReceiver, intentFilter)

    lastSuggestedNetwork?.let {
        val status = wifiManager!!.removeNetworkSuggestions(listOf(it))
        Log.i("WifiNetworkSuggestion", "Removing Network suggestions status is $status")
    }
    val suggestionsList = listOf(wifiNetworkSuggestion)

    var status = wifiManager!!.addNetworkSuggestions(suggestionsList)
    Log.i("WifiNetworkSuggestion", "Adding Network suggestions status is $status")
    if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE) {
        showToast("Suggestion Update Needed")
        status = wifiManager!!.removeNetworkSuggestions(suggestionsList)
        Log.i("WifiNetworkSuggestion", "Removing Network suggestions status is $status")
        status = wifiManager!!.addNetworkSuggestions(suggestionsList)
    }
    if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
        lastSuggestedNetwork = wifiNetworkSuggestion
        showToast("Suggestion Added")
    }
}

private fun showToast(s: String) {
    Toast.makeText(applicationContext, s, Toast.LENGTH_LONG).show()
}

}

AndroidManifest.xml 权限

 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

使用此代码,设备可以连接到WiFi网络,但需要手动关闭和打开WiFi。必须有更好的方法来连接或切换到特定的WiFi网络,而无需任何手动操作。
当前过程:
1. 运行应用程序并在主屏幕上单击按钮以连接到WiFi。 2. 转到设置,禁用并启用WiFi 3. 设备连接到所需的WiFi网络。

Output https://istack.dev59.com/zQ7Bo.webp

意图: 摆脱第二步/以编程方式完成
参考:Ref: 在 Android Q 上是否可以添加网络配置? 仅为明确起见,此代码片段中提到的 SSID 和密码是针对默认 AVD 的。只需将其更改为任何其他 WiFi 网络的 SSID 和密码即可,在物理设备上运行。我在 Pixel 3XL 上尝试过,出现了相同的问题。
2个回答

2
您可以使用新的 Settings.Panel(API 29+)或旧的Settings API,轻松地要求用户打开 WiFi。此外,您可以使用 startActivityForResult() 检查用户是否已经从设置中打开了 WiFi。
if(!wifiManager.isWifiEnabled()) {
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
        startActivity(new Intent(Settings.Panel.ACTION_WIFI));
    } else {
        // Use a full page activity - if Wifi is critcal for your app
        startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
        // Or use the deprecated method
        wifiManager.setWifiEnabled(true)
    }
} 

这似乎不是客户的合理要求。如果我看到设置应用程序,它可以在没有任何其他人为干预的情况下切换WiFi网络。如果您有生产软件方面的经验,请提供建议。 - Avijit Das
对于API 29+,Settings.Panel.ACTION_WIFI将为您显示Wi-Fi选择,而不会占用整个屏幕。在我看来,这仍然比让setWifiEnabled(true)的调用对您无效要好!因此,在代码中使用if-else块 :) - Siddharth Kamaria
1
谢谢你的建议,让我试试看。 - Avijit Das
谢谢Siddharth,这可能解决问题 :) 有没有办法防止通知? - Avijit Das
@AvijitDas 你是在指 setWifiEnabled(true) 的警告通知吗?如果是的话,那么我不知道有任何方法可以禁用它。 - Siddharth Kamaria

1

注意:此方法仅适用于不针对Android Q(API 29)及以上版本的情况。

并且没有自动启用该过程的方法。

启用方法

    public void EnableWiFi(){
      wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
      wifiManager.setWifiEnabled(true);
   }

禁用

 public void DisableWiFi(){
      wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
      wifiManager.setWifiEnabled(false);
   }

感谢Ali的快速回应。我正在API 30上尝试它。有没有办法在API 30上实现我正在尝试的内容?我检查了setWifiEnabled自API 29以来已被弃用。 - Avijit Das
1
是的,确切地说,它已经被弃用了。 - Ali
我认为没有任何变通方法,但在API 30以下可以使用以下API进行操作,并且对于API 30,需要手动功能。 - Ali
这段代码在API 28及以下版本上运行正常。但我仍希望能够在29及以上版本上找到解决方案。 - Avijit Das
这个特定的操作取决于Android版本,所以除此之外可能没有其他解决方案。请注意,在29+上无法实现此行为。 - Ali
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接