我有此功能可以在Wifi网络中进行连接,在Android 10以下可以正常工作,但是当我在Android 10上进行尝试时,我已经成功建立了连接,但是没有互联网,我知道它是{{3 }},但我发现这个a bug in Android 10可以毫无问题地从Android 10连接到wifi。 我被封锁了好几天。
我的功能:
private void connectToWifi(String ssid, String password)
{
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
try {
Log.e(TAG,"connection wifi pre Q");
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + ssid + "\"";
wifiConfig.preSharedKey = "\"" + password + "\"";
int netId = wifiManager.addNetwork(wifiConfig);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
} catch ( Exception e) {
e.printStackTrace();
}
} else {
Log.e(TAG,"connection wifi Q");
WifiNetworkSpecifier wifiNetworkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid( ssid )
.setWpa2Passphrase(password)
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build();
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
super.onAvailable(network);
connectivityManager.bindProcessToNetwork(network);
Log.e(TAG,"onAvailable");
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
Log.e(TAG,"onLosing");
}
@Override
public void onLost(Network network) {
super.onLost(network);
Log.e(TAG, "losing active connection");
}
@Override
public void onUnavailable() {
super.onUnavailable();
Log.e(TAG,"onUnavailable");
}
};
connectivityManager.requestNetwork(networkRequest,networkCallback);
}
}
答案 0 :(得分:2)
如果要使用INTERNET连接到WiFi,则应使用这种 NetworkRequest :
NetworkRequest request = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(wifiNetworkSpecifier)
.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.build();
此外,您需要为过程指定默认路由,以永久性地向连接的WiFi AP发送请求。只需在 onAvaliable 下的 NetworkCallback 中添加下一个方法的调用即可,如下所示:
networkCallback = new ConnectivityManager.NetworkCallback() {
@Override
public void onAvailable(Network network) {
createNetworkRoute(network, connectivityManager);
}
};
if (connectivityManager!= null) connectivityManager.requestNetwork(request, networkCallback);
。
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
private static void createNetworkRoute(Network network, ConnectivityManager connectivityManager) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
connectivityManager.bindProcessToNetwork(network);
} else {
ConnectivityManager.setProcessDefaultNetwork(network);
}
}
不要忘记断开与绑定网络的连接:
connectivityManager.unregisterNetworkCallback(networkCallback);
最后,您可以在WifiUtils之类的不同库中找到最佳实践。
答案 1 :(得分:1)
我也面临同样的问题,即使在 3 个月后我也无法解决这个问题。但我找到了一个很棒很酷的解决方案。
startActivity(new Intent("android.settings.panel.action.INTERNET_CONNECTIVITY"))
只需添加这些线路,而不是从应用程序连接到 wifi,这将提示用户选择一个 wifi 并连接,一旦用户这样做,它就会连接到 wifi 并且它也会有互联网。< /p>
仅从应用程序连接到 wifi 将无法访问互联网。这样做,这是最好的解决方案。
答案 2 :(得分:0)
如果您具有root访问权限(adb root):
手动连接到您选择的Wifi网络。
拉出这些ADB文件:
adb pull /data/misc/wifi/WifiConfigStore.xml
adb pull /data/misc/wifi/WifiConfigStore.xml.encrypted-checksum
Ex: GarageWifi
Ex: BusinessWifi
复制到您选择的位置。 请勿更改您提取的文件的名称。
adb push <location>\WifiConfigStore.xml /data/misc/wifi/
adb push <location>\WifiConfigStore.xml.encrypted-checksum /data/misc/wifi/
adb reboot
答案 3 :(得分:0)
您可以尝试使用wifisuggestion api,我可以使用它们进行连接。
final WifiNetworkSuggestion suggestion1 =
new WifiNetworkSuggestion.Builder()
.setSsid("YOUR_SSID")
.setWpa2Passphrase("YOUR_PRE_SHARED_KEY")
.build();
final List<WifiNetworkSuggestion> suggestionsList =
new ArrayList<WifiNetworkSuggestion>();
suggestionsList.add(suggestion1);
WifiManager wifiManager =
(WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
int status = wifiManager.addNetworkSuggestions(suggestionsList);
if (status == 0 ){
Toast.makeText(this,"PSK network added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network added: "+status);
}else {
Toast.makeText(this,"PSK network not added",Toast.LENGTH_LONG).show();
Log.i(TAG, "PSK network not added: "+status);
}
答案 4 :(得分:0)
因此,对我来说,解决方案是使用 targetSdkVersion 28 编译您的应用。 要连接wifi,请使用此功能
connectToWifi(String ssid, String key)
这只是暂时的解决方法,正在等待Google发布此错误的修复程序,以了解向Google报告的问题的更多信息:issuetracker.google.com/issues/138335744
public void connectToWifi(String ssid, String key) {
Log.e(TAG, "connection wifi pre Q");
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = "\"" + ssid + "\"";
wifiConfig.preSharedKey = "\"" + key + "\"";
int netId = wifiManager.addNetwork(wifiConfig);
if (netId == -1) netId = getExistingNetworkId(wifiConfig.SSID);
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
}
答案 5 :(得分:0)
到目前为止,在我测试过的大多数设备上,什么对我有用(例外是Im目前正在研究的OnePlus,一旦我了解更多,它将进行更新,请参阅底部列表)。
下面的代码是用Kotlin编写的,如果需要的话,请用谷歌搜索如何隐藏到Java。
创建一个API> = 29所需的NetworkCallback(之前不是必需的,但可以使用)
val networkCallback = object : ConnectivityManager.NetworkCallback() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// To make sure that requests don't go over mobile data
// This is preventing a OnePlus model from communicating correctly (still investigating)
connectivityManager.bindProcessToNetwork(network)
} else {
connectivityManager.setProcessDefaultNetwork(network)
}
}
}
按如下所示连接到网络
val wifiNetworkSpecifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(pass)
.build()
networkRequest = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
// Add the below 2 lines if the network should have internet capabilities.
// Adding/removing other capabilities has made no known difference so far
// .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
// .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_RESTRICTED)
.setNetworkSpecifier(wifiNetworkSpecifier)
.build()
connectivityManager.requestNetwork(networkRequest, networkCallback)
在这里需要注意的是'networkRequest'变量是全局变量。据我了解,here要求它是可用的并且不能在函数中调用,这样它就不会被GC收集,并且在不再需要网络时将其设置为null,如下所示
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
//This is required for Xiaomi models for disconnecting
connectivityManager.bindProcessToNetwork(null)
} else {
connectivityManager.setProcessDefaultNetwork(null)
}
connectivityManager.unregisterNetworkCallback(it)
networkRequest = null
一些小技巧:
现在将打开一个系统对话框,该应用分别调用onPause和onResume。这影响了我关于自动连接到IoT设备的逻辑。
关于测试,我还不能仅通过使用espresso来解决该对话框,它可能会阻止某些在API 29之前运行的测试。可以使用其他框架(例如uiautomator)来实现。就我而言,我将测试调整为可以工作,直到出现对话框,然后再运行进一步的测试。 使用Intents.init()不起作用。
onUnavailable,但用户会取消。当找不到网络或用户在找到网络之前取消对话框时,不会调用该方法。这是我通过调试发现的结果
已测试的设备列表:
答案 6 :(得分:0)
从 Android 10 开始,我必须使用以下代码连接到特定的 wifi 网络。
private ConnectivityManager mConnectivityManager;
@Override
public void onCreate(@Nullable Bundle savedInstanceState){
// instantiate the connectivity manager
mConnectivityManager = (ConnectivityManager) this.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
}
public void connect(String ssid, String password) {
NetworkSpecifier networkSpecifier = new WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(password)
.setIsHiddenSsid(true) //specify if the network does not broadcast itself and OS must perform a forced scan in order to connect
.build();
NetworkRequest networkRequest = new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.setNetworkSpecifier(networkSpecifier)
.build();
mConnectivityManager.requestNetwork(networkRequest, mNetworkCallback);
}
public void disconnectFromNetwork(){
//Unregistering network callback instance supplied to requestNetwork call disconnects phone from the connected network
mConnectivityManager.unregisterNetworkCallback(mNetworkCallback);
}
private ConnectivityManager.NetworkCallback mNetworkCallback = new ConnectivityManager.NetworkCallback(){
@Override
public void onAvailable(@NonNull Network network) {
super.onAvailable(network);
//phone is connected to wifi network
}
@Override
public void onLosing(@NonNull Network network, int maxMsToLive) {
super.onLosing(network, maxMsToLive);
//phone is about to lose connection to network
}
@Override
public void onLost(@NonNull Network network) {
super.onLost(network);
//phone lost connection to network
}
@Override
public void onUnavailable() {
super.onUnavailable();
//user cancelled wifi connection
}
};
参考资料: https://anutoshdatta.medium.com/new-wifi-apis-on-android-10-481c525108b7 https://developer.android.com/guide/topics/connectivity/wifi-suggest