以编程方式连接到 wifi 网络不允许外部通信

问题描述

我正在构建一个 Android 应用程序,该应用程序在入职流程中需要连接到 wifi 网络。我能够成功连接到 SSID,但是当我尝试访问浏览器时,我无法加载任何网页,即使 Wifi 设置说它是通过我的应用程序连接的。

有没有办法在 Android 中指定在我的应用程序之外使用该 wifi 网络的能力?原因是这很重要,因为我们使用 Android MDM 远程管理设备。

class WifiActivity : AppCompatActivity() {

    private val callback = object : ConnectivityManager.NetworkCallback() {
        override fun onAvailable(network: Network) {
            super.onAvailable(network)

            Timber.d("NETWORK! Network is available $network. Binding to network")
            connectivityManager.bindProcesstoNetwork(network)

            Timber.d("NETWORK! Connected to SSID ${wifiManager.connectionInfo.ssid}")
        }

        override fun onUnavailable() {
            super.onUnavailable()

            Timber.d("NETWORK! Network is unavailable")
        }

        override fun onLost(network: Network) {
            super.onLost(network)

            Timber.d("NETWORK! Network is lost $network")
        }

        override fun onLosing(network: Network,maxmsToLive: Int) {
            super.onLosing(network,maxmsToLive)

            Timber.d("NETWORK! Network is losing $network")
        }
    }

    private val suggestionCallback = object: broadcastReceiver() {
        override fun onReceive(context: Context?,intent: Intent?) {
            if (!intent?.action.equals(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)) {
                Timber.d("NETWORK! broadcast was not WIFI_NETWORK_SUGGESTION_POST_CONNECTION")
                return
            }

            Timber.d("NETWORK! I think we're on wifi Now?")
        }
    }

    override fun onResume() {
        super.onResume()
        Timber.d("NETWORK! Registering default network callback")
        connectivityManager.registerDefaultNetworkCallback(callback)
    }

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

        connect.setonClickListener {
            Timber.d("NETWORK! Going to attempt connect. ${ssid.text.toString()}")
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
                Timber.d("NETWORK! SDK and OS requirements satisfied")
                val wifiBuilder = WifiNetworkSpecifier.Builder()
                wifiBuilder.setSsid(ssid.text.toString())
                wifiBuilder.setWpa2Passphrase(password.text.toString())
                val networkSpecifier = wifiBuilder.build()
                Timber.d("NETWORK! WifiNetworkSpecifier $networkSpecifier")

                val networkBuilder = NetworkRequest.Builder()
                networkBuilder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                networkBuilder.setNetworkSpecifier(networkSpecifier)
                val networkRequest = networkBuilder.build()
                Timber.d("NETWORK! NetworkRequest $networkRequest")


                Timber.d("NETWORK! Will request network")
                connectivityManager.requestNetwork(networkRequest,callback)

                // Wifi Suggestion
                val suggestion = WifiNetworkSuggestion
                    .Builder()
                    .setSsid(ssid.text.toString())
                    .setWpa2Passphrase(password.text.toString())
                    .build()

                val suggestions = listof(suggestion)
                val status = wifiManager.addNetworkSuggestions(suggestions)

                if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
                    Timber.d("NETWORK! Failed to add suggestion $suggestion")
                } else {
                    Timber.d("NETWORK! Successfully added a suggestion of $suggestion")
                }

                val intentFilter = IntentFilter(WifiManager.ACTION_WIFI_NETWORK_SUGGESTION_POST_CONNECTION)
                applicationContext.registerReceiver(suggestionCallback,intentFilter)
            } else {
                Timber.d("NETWORK! Cant connect to a wifi on this device programatically")
            }
        }
    }
} 

解决方法

调用 connectivityManager.bindProcessToNetwork(network) 只能将您的应用绑定到特定的网络或网络类型。您不能影响其他应用程序的连接。 这仅取决于 android 操作系统和行为,移动连接和 wifi 是否同时工作,在制造商之间是非常不一致的。