Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get SSID of disconnected WiFi network in Android using BroadcastReceiver?

I have the following BroadcastRecevier:

public class WiFiConnectionEventsReceiver extends BroadcastReceiver {

    private static final String TAG = WiFiConnectionEventsReceiver.class.getSimpleName();

    @Override
    public void onReceive(Context context, @NonNull Intent intent) {
        Log.v(TAG, "action: " + intent.getAction());
        Log.v(TAG, "component: " + intent.getComponent());
        Bundle extras = intent.getExtras();
        if (extras != null) {
            for (String key : extras.keySet()) {
                Log.v(TAG, "key [" + key + "]: " +
                        extras.get(key));
            }
        } else {
            Log.v(TAG, "no extras");
        }

        ConnectivityManager conMan = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = conMan.getActiveNetworkInfo();
        if (netInfo != null && netInfo.getType() == ConnectivityManager.TYPE_WIFI) {
            Log.d("NetworkInfo", "Have Wifi Connection");
            Log.d("NetworkInfo", netInfo.getExtraInfo());
            Log.d("NetworkInfo", netInfo.getTypeName());
        }
        else {
            Log.d("NetworkInfo", "Don't have Wifi Connection");
            Log.d("NetworkInfo", netInfo.getExtraInfo());
            Log.d("NetworkInfo", netInfo.getTypeName());
        }

        WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
        Log.d("WifiInfo",  wifiManager.getConnectionInfo().toString());
    }
}

It receives network connection and disconnection events.

When it connects to a WiFi network, I am able to get the SSID of the network easily.

But I want to be able to get the SSID of the WiFi network when the network is disconnected as well (without having to store previously connected networks and then matching them up that way etc). Is this possible?

Logs when WiFi connects:

V/WiFiConnectionEventsReceiver: action: android.net.conn.CONNECTIVITY_CHANGE
V/WiFiConnectionEventsReceiver: component: ComponentInfo{com.example.test/com.example.test.WiFiConnectionEventsReceiver}
V/WiFiConnectionEventsReceiver: key [networkInfo]: [type: WIFI[], state: CONNECTED/CONNECTED, reason: (unspecified), extra: "SKY123”, roaming: false, failover: false, isAvailable: true]
V/WiFiConnectionEventsReceiver: key [networkType]: 1
V/WiFiConnectionEventsReceiver: key [inetCondition]: 100
V/WiFiConnectionEventsReceiver: key [extraInfo]: "SKY123”
D/NetworkInfo: Have Wifi Connection
D/NetworkInfo: "SKY123”
D/NetworkInfo: WIFI
D/WifiInfo: SSID: SKY123, BSSID: 10:40:03:ad:6x:c9, MAC: 02:00:00:00:00:00, Supplicant state: COMPLETED, RSSI: -79, Link speed: 43Mbps, Frequency: 2412MHz, Net ID: 1, Metered hint: false, score: 60

Logs when WiFi disconnects (note unknown SSID):

V/WiFiConnectionEventsReceiver: action: android.net.conn.CONNECTIVITY_CHANGE
V/WiFiConnectionEventsReceiver: component: ComponentInfo{com.example.test/com.example.test.WiFiConnectionEventsReceiver}
V/WiFiConnectionEventsReceiver: key [networkInfo]: [type: WIFI[], state: DISCONNECTED/DISCONNECTED, reason: (unspecified), extra: <unknown ssid>, roaming: false, failover: false, isAvailable: true]
V/WiFiConnectionEventsReceiver: key [networkType]: 1
V/WiFiConnectionEventsReceiver: key [inetCondition]: 0
V/WiFiConnectionEventsReceiver: key [extraInfo]: <unknown ssid>
V/WiFiConnectionEventsReceiver: key [noConnectivity]: true
D/NetworkInfo: Don't have Wifi Connection
D/NetworkInfo: id
D/NetworkInfo: MOBILE
D/WifiInfo: SSID: <unknown ssid>, BSSID: <none>, MAC: 02:00:00:00:00:00, Supplicant state: COMPLETED, RSSI: -127, Link speed: -1Mbps, Frequency: -1MHz, Net ID: -1, Metered hint: false, score: 0

The reason I'd like this info is I want to be able to track a user's WiFi usage on each network - the connection and disconnection times.

Without the SSID of the disconnected network, the only way I can think to do this is something like:

if (WiFi network ABC disconnected)
  if (if previous stored connection for WiFi network ABC has no disconnection time)
      set WiFI network ABC disconnection time to now

However, the above approach feels flaky, for example, what if for some reason a WiFi disconnection event is missed etc

like image 374
Rory Avatar asked Sep 24 '16 16:09

Rory


People also ask

What is a unknown SSID?

What is hiding an SSID? Hiding an SSID is simply disabling a wireless router's SSID broadcast feature. Disabling the SSID broadcast stops the router from sending out the wireless network's name, making it invisible to users. However, this only hides the name from showing up on device lists of nearby networks.


1 Answers

You can definitely do it, by using a different approach than what you've tried.

  1. You need to register a receiver which listens to WifiManager.SCAN_RESULTS_AVAILABLE_ACTION.
  2. Whenever you're doing a wifi scan, this receiver will be called with the scan results, within those results you'll have any router available ssid (regardless of its connected status)
  3. You need to then match the disconnected wifi you found on your code with the scan list.

Add this permissions to your manifest, and don't forget, if you're using marshmallow, request permission for the location.

<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_COARSE_LOCATION" />

This is the MainActivty, results are received on the broadcast receiver.

public class MainActivity extends AppCompatActivity {

    private WifiManager mWifiManager;
    private List<ScanResult> mScanResults;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (mWifiManager.isWifiEnabled() ||
                (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2 && mWifiManager.isScanAlwaysAvailable())) {
            registerReceiver(mReceiver, new IntentFilter(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
        }
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equalsIgnoreCase(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
                mScanResults = mWifiManager.getScanResults();
                for (ScanResult result : mScanResults) {
                    Log.i(getClass().getSimpleName(), "wifi Ssid : " + result.SSID);
                }
            }
        }
    };

    @Override
    protected void onDestroy() {
        try {
            unregisterReceiver(mReceiver);
        } catch (Exception e) {
            e.printStackTrace();
        }
        super.onDestroy();
    }
}
like image 51
Dus Avatar answered Sep 22 '22 12:09

Dus