对不起我的英语不好.我正在编写一个代码来连接到另一个Android设备热点.它连接起来了.但是,在我的情况下,热点将没有互联网.现在连接的设备,切换回与互联网的另一个wifi网络.除了我的方式,有没有更好的方法连接到热点?我的代码如下:
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout);
AppCompatButton btnConnect=findViewById(R.id.btnConnect);
btnConnect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
registerReceiver(mWifiBroadcastReceiver , new IntentFilter("android.net.wifi.STATE_CHANGE"));
EditText eSSID=findViewById(R.id.ssid);
EditText ePassword=findViewById(R.id.password);
String ssid = eSSID.getText().toString();
String key = ePassword.getText().toString();
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"" , ssid);
wifiConfig.preSharedKey = String.format("\"%s\"" , key);
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId , true);
wifiManager.reconnect();
}
});
}
Run Code Online (Sandbox Code Playgroud)
接收器是:
private BroadcastReceiver mWifiBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(final Context context , Intent intent) {
switch (intent.getAction()) {
case WifiManager.NETWORK_STATE_CHANGED_ACTION:
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
boolean isConnected = info.isConnected();
boolean isConnecting = info.isConnectedOrConnecting();
//TODO: probably better to use the EXTRA_ info here
String ssid = wifiManager.getConnectionInfo() != null ?
wifiManager.getConnectionInfo().getSSID() : null;
ssid = normalizeAndroidWifiSsid(ssid);
String stateName = "";
switch (info.getState()) {
case CONNECTED:
stateName = "connected";
break;
case CONNECTING:
stateName = "connecting";
break;
case DISCONNECTED:
stateName = "disconnected";
break;
case DISCONNECTING:
stateName = "disconnecting";
break;
case SUSPENDED:
stateName = "suspended";
break;
case UNKNOWN:
stateName = "unknown";
break;
}
if (Build.VERSION.SDK_INT >= 21) {
if (isConnected) {
NetworkRequest.Builder builder = new NetworkRequest.Builder();
builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
builder.addCapability(NetworkCapabilities.NET_CAPABILITY_CAPTIVE_PORTAL);
final String connectedSsid = ssid;
connectivityManager.registerNetworkCallback(builder.build() , new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(network);
//This is always the SSID if it's wifi, even though this is *not* documented
String networkSsid = networkInfo.getExtraInfo();
if (networkSsid.equals(connectedSsid)) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Toast.makeText(context,"Connected Successfully",Toast
.LENGTH_LONG).show();
}
});
/*
* We can now use network.openURLConnection and network.getSocketFactory()
* to communicate using the wifi network that has no Internet
*/
connectivityManager.unregisterNetworkCallback(this);
}
}
});
}
}
break;
}
}
};
Run Code Online (Sandbox Code Playgroud)
由于Android中WiFi处理的异步特性,我将重点关注这4条寻求解决方案的线路
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId , true);
wifiManager.reconnect();
Run Code Online (Sandbox Code Playgroud)
disconnect和reconnect电话在这里是错误的,它们只是使内部wifi状态机混乱。enableNetwork将参数boolean attemptConnect设置为调用true足以以编程方式选择wifi。
因此,只需使用:
int netId = manager.addNetwork(wifiConfig);
manager.enableNetwork(netId, true);
Run Code Online (Sandbox Code Playgroud)
老实说,我尝试扫描内部源,但是内部状态机非常复杂。如果您有兴趣,可以在这里查看状态机,在这里查看wifi配置数据库的处理方式。
另外,为避免有多个配置条目,请在调用addNetwork之前检查已创建的配置,以查找要连接的SSID,仅调用enableNetwork。
List<WifiConfiguration> networks = manager.getConfiguredNetworks();
for(WifiConfiguration c : networks) {
if (isThisWifiAppSpecific(c.SSID)) {
manager.enableNetwork(c.networkId, true);
return;
}
}
Run Code Online (Sandbox Code Playgroud)
我在生产中使用它并且效果很好。从未在低于24的API级别中进行过测试。
| 归档时间: |
|
| 查看次数: |
1022 次 |
| 最近记录: |