How to scan wifi networks

edited January 2018 in Android Mode

Hi everyone, im trying to scan al available networks, and with the help of some other post i have the following code:

import java.util.List;
import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiConfiguration.KeyMgmt;
import android.app.Activity;

Activity act;
Context context;
WifiManager wm;
List<ScanResult> results;
WifiInfo wifiInfo ;

boolean primeraVez = true;

void setup() {

  fullScreen();
  act = this.getActivity();
  context = act.getApplicationContext();
} 
void draw() {
  textSize(height/18);


  if (primeraVez) {
    primeraVez = false;
    WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
    wifiManager.startScan();
    List<ScanResult> result = wifiManager.getScanResults();
    println(result);
  }
}

the intention was to print all the available networks but i'm only obtaining an empty array "[]" over the console, what am i doing wrong?

the code may have some useless parts

Answers

  • @erwrow===

    • What permissions are you using?

    • startScan does not return immeditaley but asynch.: you have to use a broadcast receiver as i have explained in this forum. add it a filter: SCAN_RESULTS_AVAILABLE_ACTION

    • you have also to release it after using

    • see what android docs are saying:

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

  • edited January 2018

    @akenaton

    1) I'm using the following permissions:

    "android.permission.ACCESS_COARSE_LOCATION"
    "android.permission.ACCESS_NETWORK_STATE"
    "android.permission.ACCESS_WIFI_STATE"
    "android.permission.CHANGE_NETWORK_STATE"
    "android.permission.CHANGE_WIFI_MULTICAST_STATE"
    "android.permission.CHANGE_WIFI_STATE"
    "android.permission.INTERNET"
    

    2) Ok, i'll try to find more information on broadcast receivers (i've no idea what they are).

  • edited January 2018

    Ok, so i know that this code is sloppy, but i came up with this

        import java.util.List;
        import android.content.Context;
        import android.net.wifi.WifiManager;
        import android.net.wifi.WifiConfiguration;
        import android.net.wifi.ScanResult;
        import android.net.wifi.WifiInfo;
        import android.net.wifi.WifiConfiguration.KeyMgmt;
        import android.app.Activity;
        import android.content.BroadcastReceiver;
        import android.content.Intent;
        import android.content.IntentFilter;
    
        Activity act;
        Context context;
        WifiManager wm;
        List<ScanResult> results;
        WifiInfo wifiInfo ;
    
        boolean primeraVez = true, segundo = false;
        List<ScanResult> result;
        WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
        BroadcastReceiver myDiscoverer = new myOwnBroadcastReceiver();
        IntentFilter IF = new IntentFilter(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    
        void setup()
        {
          fullScreen();
          act = this.getActivity();
          context = act.getApplicationContext();
          this.getActivity().registerReceiver(myDiscoverer, IF);
        } 
        void draw()
        {
          textSize(height/18);
          if (primeraVez)
          {
            primeraVez = false;
            wifiManager.startScan();
          }
          if(segundo)
          {
            println(result);
            segundo = false;
          }
        }
    
        public class myOwnBroadcastReceiver extends BroadcastReceiver {
        //<a href="/two/profile/Override">@Override</a>
            public void onReceive(Context context, Intent intent) {
            result = wifiManager.getScanResults();
            segundo = true;
          }
        }
    

    and when i try to run it the console throws the following "fatal exception"

        FATAL EXCEPTION: main
        Process: processing.test.sketch_180118a, PID: 23001
        java.lang.RuntimeException: Unable to start activity ComponentInfo{processing.test.sketch_180118a/processing.test.sketch_180118a.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2659)
            at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
            at android.app.ActivityThread.-wrap12(ActivityThread.java)
            at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:154)
            at android.app.ActivityThread.main(ActivityThread.java:6123)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
        Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
            at processing.test.sketch_180118a.sketch_180118a.<init>(sketch_180118a.java:51)
            at processing.test.sketch_180118a.MainActivity.onCreate(MainActivity.java:24)
            at android.app.Activity.performCreate(Activity.java:6672)
            at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1140)
            at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2612)
            ... 9 more
    

    i have no idea what went wrong

  • edited January 2018

    &erwrow===

    line 21 you initialize your WifiManager with "context" that is only initialized line 29: null object reference.

  • edited January 2018

    you're right, now i have this:

        import java.util.List;
        import android.content.Context;
        import android.net.wifi.WifiManager;
        import android.net.wifi.WifiConfiguration;
        import android.net.wifi.ScanResult;
        import android.net.wifi.WifiInfo;
        import android.net.wifi.WifiConfiguration.KeyMgmt;
        import android.app.Activity;
        import android.content.BroadcastReceiver;
        import android.content.Intent;
        import android.content.IntentFilter;
    
        Activity act;
        Context context;
        WifiManager wm;
        List<ScanResult> results;
        WifiInfo wifiInfo ;
    
        boolean primeraVez = true, segundo = false;
        List<ScanResult> result;
        WifiManager wifiManager;
        BroadcastReceiver myDiscoverer = new myOwnBroadcastReceiver();
        IntentFilter IF = new IntentFilter(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    
        void setup()
        {
          fullScreen();
          act = this.getActivity();
          context = act.getApplicationContext();
          wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
          this.getActivity().registerReceiver(myDiscoverer, IF);
        } 
        void draw()
        {
          textSize(height/18);
          if (primeraVez)
          {
            primeraVez = false;
            wifiManager.startScan();
          }
          if(segundo)
          {
            println(result);
            segundo = false;
          }
        }
    
        public class myOwnBroadcastReceiver extends BroadcastReceiver {
        //<a href="/two/profile/Override">@Override</a>
            public void onReceive(Context context, Intent intent) {
            result = wifiManager.getScanResults();
            segundo = true;
          }
        }
    

    but still prints an empty list "[]" (no errors this time)

  • @erwrow===

    after line 51 try to add a boolean: if(result.length>0)...before segundo: because in your code it returns even when nothing was scanned...

  • ok, I added it, but it shows nothing. It's like there's no wifi network

  • @ erwrow===

    code snippet tested: it works (android 6.X) dont forget - 4 permissions (accessCoarseLocation, wifiState, wifiChange, netWorkstate) (i think now that you have not added these permissions, verify it!)

    • unregister your receiver onPause(), onStop(), on Destroy()

              import java.util.List;
              import android.content.Context;
              import android.net.wifi.WifiManager;
              import android.net.wifi.WifiConfiguration;
              import android.net.wifi.ScanResult;
              import android.net.wifi.WifiInfo;
              import android.net.wifi.WifiConfiguration.KeyMgmt;
              import android.app.Activity;
              import android.content.BroadcastReceiver;
              import android.content.Intent;
              import android.content.IntentFilter;
      
              Activity act;
              Context context;
              WifiManager wm;
              List<ScanResult> results;
              WifiInfo wifiInfo ;
      
              boolean primeraVez = true, segundo = false;
              List<ScanResult> result;
              WifiManager wifiManager;
              BroadcastReceiver myDiscoverer = new myOwnBroadcastReceiver();
              IntentFilter IF = new IntentFilter(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
      
              void setup()
              {
                fullScreen();
                act = this.getActivity();
                context = act.getApplicationContext();
                wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
                this.getActivity().registerReceiver(myDiscoverer, IF);
      
      
              } 
              void draw()
              {
                textSize(height/18);
                if (primeraVez)
                {
                  primeraVez = false;
                  wifiManager.startScan();
                }
                if(segundo)
                {
                  println(result);
                  segundo = false;
                }
              }
      
              public class myOwnBroadcastReceiver extends BroadcastReceiver {
              @Override
                  public void onReceive(Context context, Intent intent) {
                    result = wifiManager.getScanResults();
                    if(result.size()>0){
                  //result = wifiManager.getScanResults();
                  segundo = true;
                    }
                }
              }
      
  • edited February 2018

    Sorry for the delay in answering. This still doesn't work, i might think that the problem is

    <a href="/two/profile/Override">@Override</a>

    in line 51, it trhows an error "unexpected token: href", so i commented it. About the permissions, i added everything that says wifi and more. i'm testing it on android 7.x

  • @Override

    @erwrow That is just a bug when posting in this forum. You should replace the line above with

    @ Override and make sure you remove the space character after the ampersand (@). Check this link for further info: https://docs.oracle.com/javase/tutorial/java/annotations/predefined.html

    Kf

  • @erwrow===

    of course, this is just a typo from the forum....@kfrajer is right

  • Ok, i've changed that, but it still doesn't work. (and i have all the permissions)

  • @erwrow===

    put your manifest file; i have tested the code i put, it works

  • well, after some research i've found the "error", (at least in my case) you have to go to settings->app->(name of the app)->permisions and enable the location permisions, then you have to enable the gps and then voila! it works jaja. it's a very odd bug.

    so, now i need to automatically enable the location permises

  • Or, do you have any idea on how to solve that?

  • Answer ✓

    @erwrow===

    • put answered for others

    • as for permissions that s why i have told you in my previous post to put your manifest; since android 6 you have to deal with " dangerous" permissions listed in the manifest on runtime. They never are automatically granted, because the user can change his mind.

    here for more details: https://developer.android.com/training/permissions/requesting.html

  • edited February 2018

    in resume, to scan the available wifi networks you need the following code:

        import java.util.List;
        import android.content.Context;
        import android.net.wifi.WifiManager;
        import android.net.wifi.WifiConfiguration;
        import android.net.wifi.ScanResult;
        import android.net.wifi.WifiInfo;
        import android.net.wifi.WifiConfiguration.KeyMgmt;
        import android.app.Activity;
        import android.content.BroadcastReceiver;
        import android.content.Intent;
        import android.content.IntentFilter;
    
    
        boolean FirstTime = true, SecondTime = false;
        Activity act;
        Context context;
        List<ScanResult> result;
        WifiManager wifiManager;
        BroadcastReceiver myDiscoverer = new myOwnBroadcastReceiver();
        IntentFilter IF = new IntentFilter(wifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
    
        void setup()
        {
          fullScreen();
          background(50);
          act = this.getActivity();
          context = act.getApplicationContext();
          wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE); 
          this.getActivity().registerReceiver(myDiscoverer, IF);
          requestPermission("android.permission.ACCESS_FINE_LOCATION", "initLocation");  //this ask for permission, very important.
          //requestPermission("android.permission.ACCESS_COARSE_LOCATION", "initLocation1");  //some times you need to set this two, remember to create the "initLocation1" function, identical to the "initLocation" function.
    
        } 
        void draw()
        {
          textSize(height/18);
          if (FirstTime)
          {
            wifiManager.startScan();
          }
          if(SecondTime)
          {
            println(result);
            for(int i = 0; i < result.size(); i++)
            {
              println(result.get(i).SSID + " - " + result.get(i).level);
            }
            SecondTime = false;
          }
        }
    
        public class myOwnBroadcastReceiver extends BroadcastReceiver {
          @Override
          public void onReceive(Context context, Intent intent) {
            result = wifiManager.getScanResults();
            if(result.size()>0) {
              FirstTime = false;
              SecondTime = true;
            }
          }
        }
    
        void initLocation(boolean granted) {
          if (granted) {   
            println("init location manager");
          }
        }
    

    with the permissions: accessCoarseLocation, wifiState, wifiChange, netWorkstate and accessFineLocation (this last one is sugested by this page), in some devices you need to enable the location to get the available networks.

    Remember that in line 53, where it says:

    <a href="/two/profile/Override">@Override</a>

    it actually says @Override

Sign In or Register to comment.