ThanosFisherman / WifiUtils

Easily Connect to WiFi Networks

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Android 10 support. Testers needed

ThanosFisherman opened this issue · comments

Please report any connectivity issues related to Android 10 here.

WiFiUtils now has a basic support for Android 10 thanks to the contribution #46 of @eliaslecomte

Hopefully owners of Android 10 devices will help us fix potential bugs.

Does it have a way to connect to Wifi network as I've written here:
#31 (comment)
?
At least via root?

@AndroidDeveloperLB I haven't tried the root way because that's another story that involves some command line arguments plus I'm not even sure if it's gonna work.

The new contribution aims to make this library connect to WiFi networks on Android 10 devices without requiring root but it's not thoroughly tested yet.

@ThanosFisherman Wait you have an idea of what should be done using root?
As for without root, I only know of a "suggestion" API that Google presented. It has various disadvantages:

  1. Not staying forever. If the app is removed, the networks too.
  2. Has some limit of number of networks, though it's a very high limit.
  3. Last time I checked, the API causes a notification to appear, instead of just adding the networks or even show a confirmation dialog to the user to add them. Not only that, but it didn't appear right away. It might have changed since I checked it though.

That is correct, with the new api (starting Android 10), the wifi internet is only for the app that requested it. I assume the use case is more like connecting to configure IoT devices.

@eliaslecomte Well it's not such a nice alternative to what we had before...

I believe that they're trying to prevent MITM attacks by not allowing an app to connect to a subverted access point. They don't explicitly say that because you never want to give attackers suggestions.

" subverted access point" ?
So it's not about privacy of getting location by knowing the surrounding Wifi networks?

No, that's why an application can't connect without recommending the connection to the user.
The added permissions needed to scan are about getting location by knowing the surrounding WiFi networks. By insisting on both COARSE_LOCATION and FINE_LOCATION, it becomes a moot point that you can look up the location via WiFi. The user has to trust your app with your location because .... you can figure it out on your own.

What I say is that without COARSE_LOCATION and FINE_LOCATION permissions, it's still possible to get a good guess of where you are, so that's why I think they added those into the mix.

Yes, you are quite correct. So rather than leave the user in the dark, they require scanning for WiFi access point to have location permissions. The user gets explicitly asked for that.

I tried implementing the same in a new project. The phone connects and instantly disconnects to the network, as the OnAvailable method of the NetworkCallback seems to be in a loop. Demo video

@singhal2 Can you please share the source code of this?
Maybe it's a bug on the OS

I tried implementing the same in a new project. The phone connects and instantly disconnects to the network, as the OnAvailable method of the NetworkCallback seems to be in a loop. Demo video

What network security is used (wpa2?)?
Is it a network with or without internet?

@singhal2 If you can make it happen even without this library, you should report it to Google:
https://issuetracker.google.com/issues

Here is the source code I implemented. It contains both the library and standard code to connect to wifi.

https://github.com/singhal2/WifiDemo_AndroidQ

@singhal2 Probably wrong link. Doesn't include Android app project...

There is a first problem:
/** * Enable or disable Wi-Fi. * <p> * Applications must have the {@link android.Manifest.permission#CHANGE_WIFI_STATE} * permission to toggle wifi. * * @param enabled {@code true} to enable, {@code false} to disable. * @return {@code false} if the request cannot be satisfied; {@code true} indicates that wifi is * either already in the requested state, or in progress toward the requested state. * @throws {@link java.lang.SecurityException} if the caller is missing required permissions. * * @deprecated Starting with Build.VERSION_CODES#Q, applications are not allowed to * enable/disable Wi-Fi. * <b>Compatibility Note:</b> For applications targeting * {@link android.os.Build.VERSION_CODES#Q} or above, this API will always return {@code false} * and will have no effect. If apps are targeting an older SDK ( * {@link android.os.Build.VERSION_CODES#P} or below), they can continue to use this API. */ @Deprecated public boolean setWifiEnabled(boolean enabled) { try { return mService.setWifiEnabled(mContext.getOpPackageName(), enabled); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); } }

setWifiEnabled always returns false. I didn't have this at first, not sure if this is due to an sdk patch update?

@eliaslecomte You mean this:

https://developer.android.com/reference/android/net/wifi/WifiManager.html#setWifiEnabled(boolean)

This method was deprecated in API level 29.
Starting with Build.VERSION_CODES#Q, applications are not allowed to enable/disable Wi-Fi. Compatibility Note: For applications targeting Build.VERSION_CODES.Q or above, this API will always return false and will have no effect. If apps are targeting an older SDK ( Build.VERSION_CODES.P or below), they can continue to use this API.

You can't normally toggle Wifi using this permission anymore. Maybe via other workarounds (root, being system app, etc...).

Yes, but also, startScan returns false starting Android 10 if you request ACCESS_COARSE_LOCATION. Will have to add a description for that.

As documented here: https://developer.android.com/guide/topics/connectivity/wifi-scan

@eliaslecomte I hope you figure it out. Such a mess has become of Android API. Too many restrictions, that sometimes even the docs don't help.

Based on Wifitutils 1.5.1, I have tested on XiaoMi Mix2 (android 10). It can connect to a WIFI of IoT(can not access the internet). but the IP looks wired. after I add connctionManager.bindProcessToNetwork, it works.

But to support disconnect from that WIFI, I need to pass out the networkCallback used in connectivityManager.requestNetwork(request, networkCallback) when connecting to wifi.

I did not see there is any interface can do that. so I create a Pull Request on react-native-wifi-reborn
Is anyone familiar with WifiUtils could give a review to see how to do those changes on WifiUtils? @ThanosFisherman

@ljbatwh The latest version (1.6.0) of WifiUtils includes support for disconnecting of wifi networks. Please take a look at MainActivity to see how disconnection works and do some testing on your Xiaomi because I do not own an android 10 device yet.

@ThanosFisherman thanks. the 1.6.0 can connect and disconnect wifi on my android 10 (XiaoMi Mix2)
but there two issues.

  1. I need to add connectivityManager.bindProcessToNetwork(network) after the connected.
    Else, it can not access another device on the network.
    networkCallback = new ConnectivityManager.NetworkCallback() {
          @Override
          public void onAvailable(@NonNull Network network) {
              super.onAvailable(network);
              **connectivityManager.bindProcessToNetwork(network);**
              wifiLog("AndroidQ+ connected to wifi ");
          }

          @Override
          public void onUnavailable() {
              super.onUnavailable();

              wifiLog("AndroidQ+ could not connect to wifi");
          }
      };
  1. the multicast package can not be received. But if I connect the Wifi by manual, the multicast worked.

@ljbatwh I've added the bindProcessToNetwork() again(it was also in 1.5.0 but I wrongly assumed it wasn't needed because my IoT device does not have internet) in this pr: #66.

I would assume multicast works. I am also using https://github.com/tradle/react-native-udp and this works after connecting with bindProcessToNetwork().

@eliaslecomte thanks for the help. but it does not work on my phone (Xiaomi Mix2). It does not throw errors, just no receive multicast packets when I use requestnetwork() and bindProcessToNetwork(). But if I manually connect to my IoT WIFI, it works.

I am using 1.6.1 version. I have same problem on OnePlus 7 Pro. but whenever we try it on this phone on Android 10 the connection to the new WiFi network drops and gets stuck in a loop.
The logcat log is below. Please help me.

06-01 16:27:44.243 1549 1549 D OpSlaManager: lp:{InterfaceName: wlan0 LinkAddresses: [ 192.168.10.2/24 ] DnsAddresses: [ /192.168.10.1,/8.8.8.8 ] Domains: null MTU: 1500 TcpBufferSizes: 524288,1048576,4194304,524288,1048576,4194304 Routes: [ fe80::/64 -> :: wlan0,192.168.10.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.10.1 wlan0 ]} nc:[ Transports: WIFI Capabilities: NOT_METERED&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, mOriginalRequestorUid=10622, mOriginalRequestorPackageName=com.xxxx.xxxx]> SignalStrength: -28 SSID: "BLE-WIFI_52_AF"]
06-01 16:27:44.282 1549 1549 D OpSlaManager: lp:{InterfaceName: wlan0 LinkAddresses: [ 192.168.10.2/24 ] DnsAddresses: [ /192.168.10.1,/8.8.8.8 ] Domains: null MTU: 1500 TcpBufferSizes: 524288,1048576,4194304,524288,1048576,4194304 Routes: [ fe80::/64 -> :: wlan0,192.168.10.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.10.1 wlan0 ]} nc:[ Transports: WIFI Capabilities: NOT_METERED&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, mOriginalRequestorUid=10622, mOriginalRequestorPackageName=com.xxxx.xxxx]> SignalStrength: -28 SSID: "BLE-WIFI_52_AF"]
06-01 16:27:44.289 1549 1549 D OpSlaManager: lp:{InterfaceName: wlan0 LinkAddresses: [ 192.168.10.2/24 ] DnsAddresses: [ /192.168.10.1,/8.8.8.8 ] Domains: null MTU: 1500 TcpBufferSizes: 524288,1048576,4194304,524288,1048576,4194304 Routes: [ fe80::/64 -> :: wlan0,192.168.10.0/24 -> 0.0.0.0 wlan0,0.0.0.0/0 -> 192.168.10.1 wlan0 ]} nc:[ Transports: WIFI Capabilities: NOT_METERED&NOT_RESTRICTED&TRUSTED&NOT_VPN&VALIDATED&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, mOriginalRequestorUid=10622, mOriginalRequestorPackageName=com.xxxx.xxxx]> SignalStrength: -28 SSID: "BLE-WIFI_52_AF"]
06-01 16:27:44.298 1549 2152 D Ethernet: new score 0 for exisiting request NetworkRequest [ REQUEST id=2963, [ Transports: WIFI Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <WifiNetworkSpecifier [, SSID Match pattern=PatternMatcher{LITERAL: BLE-WIFI_52_AF}, BSSID Match pattern=Pair{b2:38:29:44:52:af ff:ff:ff:ff:ff:ff}, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, requestorUid=10622, requestorPackageName=com.xxxx.xxxx]> Uid: 10622] ] with serial 0
06-01 16:27:44.298 2763 2763 D PhoneSwitcherNetworkRequstListener: new score 0 for exisiting request NetworkRequest [ REQUEST id=2963, [ Transports: WIFI Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <WifiNetworkSpecifier [, SSID Match pattern=PatternMatcher{LITERAL: BLE-WIFI_52_AF}, BSSID Match pattern=Pair{b2:38:29:44:52:af ff:ff:ff:ff:ff:ff}, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, requestorUid=10622, requestorPackageName=com.xxxx.xxxx]> Uid: 10622] ] with serial 0
06-01 16:27:44.309 1549 2065 D UntrustedWifiNetworkFactory: new score 0 for exisiting request NetworkRequest [ REQUEST id=2963, [ Transports: WIFI Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <WifiNetworkSpecifier [, SSID Match pattern=PatternMatcher{LITERAL: BLE-WIFI_52_AF}, BSSID Match pattern=Pair{b2:38:29:44:52:af ff:ff:ff:ff:ff:ff}, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, requestorUid=10622, requestorPackageName=com.xxxx.xxxx]> Uid: 10622] ] with serial 0
06-01 16:27:44.309 1549 2065 D WifiNetworkFactory: new score 0 for exisiting request NetworkRequest [ REQUEST id=2963, [ Transports: WIFI Capabilities: NOT_RESTRICTED&TRUSTED&NOT_VPN Specifier: <WifiNetworkSpecifier [, SSID Match pattern=PatternMatcher{LITERAL: BLE-WIFI_52_AF}, BSSID Match pattern=Pair{b2:38:29:44:52:af ff:ff:ff:ff:ff:ff}, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, requestorUid=10622, requestorPackageName=com.xxxx.xxxx]> Uid: 10622] ] with serial 0
06-01 16:27:44.323 1549 1573 D OpRestartProcessManager: Duration is too short, ignore : 111 in com.xxxx.xxxx
06-01 16:27:44.340 1549 1595 I OpMotorManagerService: notifyActivityChanged: mBackgroudPkg =com.xxxx.xxxx mFocusPkg = com.android.settings mIsSplitMode = false mBackActivity = com.xxxx.xxxx mFocusActivity = com.android.settings.wifi.NetworkRequestDialogActivity
06-01 16:27:44.342 1549 1567 D OpSlaNetlinkHelper: frontPackageChanged: com.android.settings uid:1000 pid:3258 | com.xxxx.xxxx uid:10622 pid:20789
06-01 16:27:48.656 1549 2065 D ConnectivityService: registerNetworkAgent NetworkAgentInfo{ ni{[type: WIFI[], state: CONNECTING/CONNECTING, reason: (unspecified), extra: (none), failover: false, available: true, roaming: false]} network{274} nethandle{1180226736141} lp{{InterfaceName: wlan0 LinkAddresses: [ ] DnsAddresses: [ ] Domains: null MTU: 0 Routes: [ ]}} nc{[ Transports: WIFI Capabilities: NOT_METERED&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, mOriginalRequestorUid=10622, mOriginalRequestorPackageName=com.xxxx.xxxx]> SSID: "BLE-WIFI_52_AF"]} Score{20} everValidated{false} lastValidated{false} created{false} lingering{false} explicitlySelected{false} acceptUnvalidated{false} everCaptivePortalDetected{false} lastCaptivePortalDetected{false} captivePortalValidationPending{false} partialConnectivity{false} acceptPartialConnectivity{false} clat{mBaseIface: null, mIface: null, mState: IDLE} }
06-01 16:27:48.733 1549 1549 D OpSlaManager: lp:{InterfaceName: wlan0 LinkAddresses: [ ] DnsAddresses: [ ] Domains: null MTU: 0 TcpBufferSizes: 524288,1048576,4194304,524288,1048576,4194304 Routes: [ fe80::/64 -> :: wlan0 ]} nc:[ Transports: WIFI Capabilities: NOT_METERED&NOT_RESTRICTED&TRUSTED&NOT_VPN&NOT_ROAMING&FOREGROUND&NOT_CONGESTED&NOT_SUSPENDED LinkUpBandwidth>=1048576Kbps LinkDnBandwidth>=1048576Kbps Specifier: <WifiNetworkAgentSpecifier [WifiConfiguration=, SSID="BLE-WIFI_52_AF", BSSID=b2:38:29:44:52:af, mOriginalRequestorUid=10622, mOriginalRequestorPackageName=com.xxxx.xxxx]> SignalStrength: -27 SSID: "BLE-WIFI_52_AF"]

tested your app and it seems for android 10 you're using the p2p requestNetwork solution. Is the WifiNetworkSuggestion not stable as i've successfully connected using WifiNetworkSuggestion but there's a delay of 1 min upon accepting the notification suggestion.

https://developer.android.com/guide/topics/connectivity/wifi-suggest
The suggestions from the app must be approved by the user before the platform initiates a connection to them. This approval is provided by the user in response to a notification the first time the platform finds a network matching one of the suggestions from the app in scan results. When the platform connects to one of the network suggestions, the settings show text that attributes the network connection to the corresponding suggester app.

For my use case, (commissioning of IoT devices), this seemed the right API, as with the network suggestions api, you never know when or if, the OS will connect with a network. Your use case might be different?

@ThanosFisherman
I test the lib a couple days ago, I'don't have internet connection on Android 10 the connection is established but no internet.
I use Redmi note 9 PRO (Android 10)
I miss something ?
I had a question on stackoverflow, a lot of developers are blocked too.

https://stackoverflow.com/questions/63124728/connect-to-wifi-in-android-q-programmatically
thanks

@ThanosFisherman I tried multiple time, I debug my a lot of code too, so the scope of internet access is limited inside the app, If you leave the app which you trigger the connection to a hotspot, then, you will not have internet access.
thank's

@ThanosFisherman I tried multiple time, I debug my a lot of code too, so the scope of internet access is limited inside the app, If you leave the app which you trigger the connection to a hotspot, then, you will not have internet access.
thank's

Yes this is actually normal behavior. Since Android 10, Android has blocked the previous api's to manipulate wifi configuration entries. There are 2 new api's. The first (which is currently used by WifiUtils) is used for IoT commissioning. The app that uses it can execute api calls to the wireless access point. Only that app, and the wifi network is not persisted for the smartphone to use. There is also a wifi suggestion api in Android. You might have need to have a look at that.

@eliaslecomte
I test library with android 10
my device is
samsung a50s

and sample
doesnt work at all .

what is solution ??? how use library with android 10 ???

Hi @ThanosFisherman
Thanks for providing great library.
I was trying to use this library to connect with iOT devices.
Below Android 9, it works well, but with android 10 it doesn't work.

If i provide correct password, then it connected and I save this password.
After I change wifi password manually, and retry to connect (at this moment, the saved password is different with current password), it is failed (Didn't connect to wifi authentication_error_occurred)

After that, even the correct password doesn't works, always showing above Log.

what can i do?

remove(SSID, callback) function is forgetting previous configuration in Android 10?, if not how???

Hope any one can give me answer asap.

@eliaslecomte
I test library with android 10
my device is
samsung a50s

and sample
doesnt work at all .

what is solution ??? how use library with android 10 ???

Did you maybe edit the MainActivity? This file is no longer used, you should edit the MainKotlinActivity for testing purposes.

Hi @ThanosFisherman
Thanks for providing great library.
I was trying to use this library to connect with iOT devices.
Below Android 9, it works well, but with android 10 it doesn't work.

If i provide correct password, then it connected and I save this password.
After I change wifi password manually, and retry to connect (at this moment, the saved password is different with current password), it is failed (Didn't connect to wifi authentication_error_occurred)

After that, even the correct password doesn't works, always showing above Log.

what can i do?

remove(SSID, callback) function is forgetting previous configuration in Android 10?, if not how???

Hope any one can give me answer asap.

If changing password / reconnecting doesn't work you will have to debug. I think it will be a phone firmware issue rather than something WifiUtils can fix.

Thanks @eliaslecomte
Let me try to explain again. (lets think any credential is not saved in wifi settings)

  • if i use correct password, then app connect to wifi.
  • if i use wrong password, we get "Didn't connect to wifi authentication_error_occurred", i think it is correct.
  • after this, i can't connect to wifi even with correct password, always show above log message.

it will work again if i go to wifi settings and forgot that wifi.
Please let me know if this is still firmware issue? or when try to connect to wifi in android 10, some credential info is saved in wifi configuration?
as i asked above, remove function will not remove previous configuration in android 10? since am going to call this function before trying connect.

Hope your kind reply, Thanks.

PS; the password is changed correctly in Firmware, if i fresh wifi and try changed password, it works.
if i use wrong password again, then it will stop working even i use correct password.

Is your app targetting Android 10? If that's the case it's not actually saving the wifi configuration. You can only Disconnect in wifi settings but it's never saved in the first place. I would call the remote method first.

min sdk version is 23, targetSDK version is 29

Regarding the sample I did some cleanups, migrated to .kts gradle scripts, renamed the MainKotlinActivity into MainActivity and removed the old Java MainActivity. The sample should work as is. Just make sure you are using the latest Android Studio Version (CC @mas1515 )

@super0610 Seems like another restriction (or probably a bug on Android OS itself). You say that if you manually forget the network then WifiUtils are able to reconnect with the new password. Please Try the following:

  • Make sure the hotspot you are trying to connect to is not previously saved in the device. If it is then manually forget it from the Settings
  • Open the sample and try to connect with the current password (This step should work fine)
  • Now change the HotSpot password via your router firmware
  • Launch the sample again and choose REMOVE - Let me know at this point if the network is actually removed from the Settings
  • Modify the Wifi password in sample code to the new one and rerun the sample
  • Turn off and back on your device's wifi (just in case there is a glitch or something)
  • Try to connect again with the new password - Let me know what happens at this point

Thanks for your reply @ThanosFisherman
Yes, I am using latest Android Studio, and latest WifiUtils library (1.6.3)
I will check this in few hours and share here.
Best Regards.,

hi @ThanosFisherman
I tested with the Sample, but the sample doesn't work.
I tried same credential for the wifi, forget wifl from settings.
Tested several times, but sample didn't work, and our app works with same credential.

in Android 7, sample works.
in Android 10 (mine is Samsung SM-T290 tablet), it doesn't (Timeout)

Thanks for the update @super0610 I'm not sure yet what might be wrong or if this is an intended behavior. I'll try to investigate it and post back.

Thanks @ThanosFisherman
I will wait good news, and i can test in my side if needed.

I'm not having a Samsung SM-T290, so I can't help on this one. If you could do any more debugging @super0610 that would be awesome.

Getting Error COULD_NOT_SCAN in android 10 when connecting to local hotspot created with specific ssid and password

Getting Error COULD_NOT_SCAN in android 10 when connecting to local hotspot created with specific ssid and password

Same here. Galaxy S20 connecting to a device that doesn't have an internet connection with a specific ssid and password.

edit: could be an S20 specific issue. I am able to connect to the same WiFi network using Google Pixel 4a on AN10

edit 2: location was turned off on the S20. Turned it on and was able to connect

commented

I have found an application and it can easily connect to wifi on android 10 device.But I don't know how it work.
my device: realme x2 android 10 & teclast p20hd android 10
google play: https://play.google.com/store/apps/details?id=com.halo.wifikey.wifilocating&hl=en
web site: https://en.wifi.com/

About enabling/disabling Wifi through the library on Android 10 (and up) - I think because of the OS restrictions that have been put in place the best option would be to invoke a Settings panel:

val panelIntent = Intent(Settings.Panel.ACTION_WIFI)
startActivityForResult(panelIntent, WIFI_REQUEST)

What do you think?

About enabling/disabling Wifi through the library on Android 10 (and up) - I think because of the OS restrictions that have been put in place the best option would be to invoke a Settings panel:

val panelIntent = Intent(Settings.Panel.ACTION_WIFI)
startActivityForResult(panelIntent, WIFI_REQUEST)

What do you think?

This is logic you want to add in your app :-). The library indicates wifi is off. You show this 'error state' and the user has to take action. You can add a button that then opens the Settings screen.

I tried it on my Android 10 device and I get zero scanResults.