解决Android 10 连接设备热点后无法创建Socket 问题
在实际工作中,通常的配网方式为设备热点配网,这就需要手机连接上设备热点,App创建socket和设备建立通信。在工作中发现,将target 设置成29 时,无法创建socket。这里小编就提供一种解决方案
NetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
.setSsidPattern(new PatternMatcher(wifiName, PatternMatcher.PATTERN_PREFIX))
.setWpa2Passphrase(wifiPwd)
.setIsHiddenSsid(false)
.build();
NetworkRequest request =
new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build();
connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (networkCallback == null) {
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
// do success processing here..
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
boolean isCapWifi = capabilities != null && capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
if (isCapWifi) {
ApTcpClient.getInstance().newSocket();
try {
network.bindSocket(ApTcpClient.getInstance().socket);
} catch (IOException e) {
e.printStackTrace();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
}
@Override
public void onUnavailable() {
// do failure processing here..
}
};
}
connectivityManager.requestNetwork(request, networkCallback);
这里着重是这一行
network.bindSocket(ApTcpClient.getInstance().socket);
查看bindSocket源码可以得知,想要和设备热点建立通信必须先绑定
/**
* Binds the specified {@link Socket} to this {@code Network}. All data traffic on the socket
* will be sent on this {@code Network}, irrespective of any process-wide network binding set by
* {@link ConnectivityManager#bindProcessToNetwork}. The socket must not be connected.
*/
public void bindSocket(Socket socket) throws IOException {
// Query a property of the underlying socket to ensure that the socket's file descriptor
// exists, is available to bind to a network and is not closed.
socket.getReuseAddress();
bindSocket(socket.getFileDescriptor$());
}
只有绑定了socket后,才能创建。