4

As a newbie to Android programming, I am trying to get the SSID list using WifiManager's getScanResults() method, but it remains empty, even though I have granted it the ACCESS_COARSE_LOCATION permission as well as the CHANGE_WIFI_STATE (for the startScan() method), both in the manifest and by checking/requesting it at runtime.

In the broadcast receiver for the SCAN_RESULTS_AVAILABLE_ACTION, I even check the extra field of the intent with key EXTRA_RESULTS_UPDATED and the result returns true.

Yet, the list.size() always returns 0.

What am I missing here? I am testing on a Android 7.0 API 24 device.

Edit: The code is as follows:

MainActivity.java:

public class MainActivity extends Activity implements View.OnClickListener {
    private static final String TAG="WiFiDemo";

    WifiManager wifiManager;
    WifiBroadcastReceiver wifiReceiver;

    TextView textView;
    Button btn;

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        Log.d(TAG, "onCreate()");
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //Check for permissions
        if ((ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
                != PackageManager.PERMISSION_GRANTED)
            || (ContextCompat.checkSelfPermission(this, Manifest.permission.CHANGE_WIFI_STATE)
                    != PackageManager.PERMISSION_GRANTED))
        {
            Log.d(TAG, "Requesting permissions");

            //Request permission
            ActivityCompat.requestPermissions(this,
                    new String[]{Manifest.permission.ACCESS_COARSE_LOCATION,
                                 Manifest.permission.ACCESS_FINE_LOCATION,
                                 Manifest.permission.ACCESS_WIFI_STATE,
                                 Manifest.permission.CHANGE_WIFI_STATE,
                                 Manifest.permission.ACCESS_NETWORK_STATE},
                    123);
        }
        else
            Log.d(TAG, "Permissions already granted");

        wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);

        textView = findViewById(R.id.text);
        textView.setTextAlignment(View.TEXT_ALIGNMENT_TEXT_START);

        btn = findViewById(R.id.btn);
        btn.setOnClickListener(this);

        //Instantiate broadcast receiver
        wifiReceiver = new WifiBroadcastReceiver();

        //Register the receiver
        registerReceiver(wifiReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults)
    {
        Log.d(TAG, "onRequestPermissionsResult");

        switch (requestCode)
        {
            case 123:
            {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                {
                    // permission was granted
                    Log.d(TAG, "permission granted: " + permissions[0]);
                }
                else
                {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                    Log.d(TAG, "permission denied: " + permissions[0]);
                }

                return;
            }

            // other 'case' lines to check for other
            // permissions this app might request.
        }
    }

    //Define class to listen to broadcasts
    class WifiBroadcastReceiver extends BroadcastReceiver
    {
        @Override
        public void onReceive(Context context, Intent intent)
        {
            Log.d(TAG, "onReceive()");
            Toast.makeText(getApplicationContext(), "Scan complete!", Toast.LENGTH_SHORT).show();

            boolean ok = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false);

            if (ok)
            {
                Log.d(TAG, "scan OK");

                //StringBuffer buffer = new StringBuffer();
                List<ScanResult> list = wifiManager.getScanResults();

                Toast.makeText(getApplicationContext(), Integer.toString(list.size()), Toast.LENGTH_SHORT).show();

                for (ScanResult scanResult : list)
                {
                    //buffer.append(scanResult);
                    textView.append(scanResult.toString());
                }
            }
            else
                Log.d(TAG, "scan not OK");
        }
    }

    @Override
    protected void onStop()
    {
        // TODO Auto-generated method stub
        unregisterReceiver(wifiReceiver);
        super.onStop();
    }

    @Override
    public void onClick(View view)
    {
        // TODO Auto-generated method stub
        //Toast.makeText(getApplicationContext(), "All Network seached !!",0).show();
        if(view.getId()==R.id.btn)
        {
            Log.d(TAG, "onCreate() wifi.startScan()");

            //if (!wifiManager.isWifiEnabled())
            //    wifiManager.setWifiEnabled(true);

            wifiManager.startScan();
        }
    }
}

In the manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.wifi2ir.umagi.wifitest2">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
</manifest>
ColdFire
  • 6,764
  • 6
  • 35
  • 51
  • where is your code? – AskNilesh Apr 27 '18 at 05:54
  • I edited my post to add the code, as requested. –  Apr 27 '18 at 06:04
  • 2
    Have you enabled location services? From Android 6, granting permissions only is not enough to get the results. – Sagar Apr 27 '18 at 06:22
  • My goodness! The answer by @sagar is the correct one. Although I saw it before, it didn't dawn on me until now (finally!) that this service was completely distinct from the location permission, and that I needed to explicitly enable it in the Android Settings | Connections | Location [Location Service setting][1] I kept looking at the Permissions setting for my application: [Location Permission setting][2] Thanks for clearing up the confusion! [1]: https://i.stack.imgur.com/yFAm7.png [2]: https://i.stack.imgur.com/XsOWF.png –  Apr 27 '18 at 07:39
  • Great! I will update it as answer, help me to approve so that others can benefit too. – Sagar Apr 27 '18 at 07:40
  • Any ideas why Location Services are required? They were disabled on my phone, yet the WiFi scans in the Settings | Wifi app are working? –  Apr 27 '18 at 07:43
  • I have updated my answer with this info. You can have a look – Sagar Apr 27 '18 at 07:55

1 Answers1

5

Starting from Android 6, you have to enable location services in order to get desired results. Granting permissions is just the half work done.

You can also fire an intent to redirect user to this setting:

Intent myIntent = new Intent( Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);

Location services are necessary because when you access the scan results, you can access the information like BSSID (address of the access point). This information can also be used to detect the location of device. By requiring location services, OS ensures that user understands their location information is being accessed when they use your app.

Sagar
  • 23,903
  • 4
  • 62
  • 62
  • 2
    I am using Android 8.0.1. I have added the location permission handling also in my code. But I am getting the empty list after complete the scan. Anything we need to do additionally in Android > 8.0 – Nithinjith Jul 05 '18 at 10:06
  • Is there a way to determine that location services are disabled? **Update:** Found solution at https://stackoverflow.com/questions/10311834/how-to-check-if-location-services-are-enabled. Perhaps worth adding this to the answer. – Sergiy Belozorov May 29 '21 at 21:03