Application (WiFi connections) doesn't work an

2020-07-17 04:42发布

问题:

My application stopped working once I upgraded to Marshmallow, it was supposed to be able to change the WiFi connection, but now it doesn't do anything at all.

I've spent some time reading about the new permission model of the Android 6.0. Well awesome, but old apps should continue working... Anyway, I started trying to implement the granting of permission, but realized that this is a normal permission and there should be done no permission request for it if it's defined in android manifest:

<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />

The permission has always been in Android Manifest, and if I understand correctly it is supposed to work because it's a "Normal permission". So why doesn't it work, does anybody have a solution?

Adding the code fragment related to my case:

protected void connectWifi() {
    if ((!connectedToAccessPoint(settings.getMainConnectionName()))
            && (accessPointIsAvailable(settings.getMainConnectionName()))) {
        ConnectionUtils.connectToWifi(this,
                settings.getMainConnectionName(),
                settings.getMainConnectionPassword());
        Toast.makeText(this,
                "Connecting to " + settings.getMainConnectionName(),
                Toast.LENGTH_LONG).show();
        handler.postDelayed(sendUpdatesToUI,
                DelayConstants.BASIC_REQUEST_SENT);
        handler.postDelayed(sendUpdatesToUI,
                DelayConstants.CHANGE_CONNECTION);
    }
}

And here the technical part for the connection:

public static void connectToWifi(Context context, String ssid, String password) {
     WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
     // setup a wifi configuration
      WifiConfiguration wc = new WifiConfiguration();
      wc.SSID = "\"" + ssid + "\"";
      wc.preSharedKey = "\""+ password + "\"";
      wc.status = WifiConfiguration.Status.ENABLED;
      wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
      wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
      wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
      wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
      wc.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
      wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
    // connect to and enable the connection
     int netId = wifiManager.addNetwork(wc);
     wifiManager.enableNetwork(netId, true);
     wifiManager.setWifiEnabled(true);
}

In AndroidManifest as mentioned before there's that CHANGE_WIFI_STATE permission, which was there since the app was running on devices not having Android 6.0

回答1:

So I eventually figured it out with some help of the people commenting and reading on the web. So it was a permissions problem after all.

It seems in order to work well with WifiManager when scanning the Connections from Android 6.0 it needs to access your location, so that is either the fine location or the coarse location, I added the following to my Manifest file:

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

I was checking in my code whether the connection was available before connecting it, and that's why it would never work, it always returned 0 results from the network scan because the permission is missing. So in a standard way an implementation needs to be done to request the ACCESS_COARSE_LOCATION permission, afterwards it would not work, UNLESS you turned on your location setting in Android. It actually makes my app pretty useless if I need to turn on location every time...

At the end I did a work around without checking whether the access point is available and just doing a try-catch statement to try to connect to it. It's ugly but it's the only way in new Android.

I do like the new permission model, but apparently Google has done a really bad job implementing it at some points. Why would you need now to turn on the location to be able to get the WiFi scan results???? Doesn't make any sense because it worked before Android 6.0 without that. I do understand that about the location permission, but actually having to turn on location to be able to scan what's available on WiFi is just plain wrong...



回答2:

An excellent tutorial advice:

*App on Marshmallow needs ACCESS_COARSE_LOCATION or ACCESS_FINE_LOCATION permission and Location services should be enabled to get wifi scan results

You can read more about this at: http://www.intentfilter.com/2016/08/programatically-connecting-to-wifi.html

Reading about a restriction that was put starting from Marshmallow was that the app can only modify those WiFi networks that it has created. The system doesn't allow modification of networks that other apps or users have created. So, adding the network might fail if the network already exists in the list (the system might auto connect to network once it's detected).