问题描述
我正在构建一个 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 是否同时工作,在制造商之间是非常不一致的。