1

I'm working on an Android application and I need to know abut the network status: offline, roaming, wifi, wifi hospot, wifi direct, mobile data. I've createad this singleton class:

public class NetworkController {

private static final NetworkController networkController = new NetworkController();

private boolean peerConnected;
private ConnectionMode connectionMode;

public enum ConnectionMode {
    OFFLINE,
    MOBILE_DATA,
    ROAMING,
    WIFI,
    WIFI_HOSPOT,
    WIFI_DIRECT
}

private NetworkController() {
    connectionMode = ConnectionMode.OFFLINE;
}

public static NetworkController getNetworkController() {
    return networkController;
}

public void setPeerConnected(boolean peerConnected) {
    this.peerConnected = peerConnected;
}

public boolean isPeerConnected() {
    return peerConnected;
}

public ConnectionMode getConnectionMode() {
    return connectionMode;
}

public void setConnectionMode(ConnectionMode connectionMode) {
    this.connectionMode = connectionMode;
}

public void updateNetworkStatus() {
    connectionMode = ConnectionMode.OFFLINE;
    if (isRoaming()) {
        connectionMode = ConnectionMode.ROAMING;
    } else if (isConnectedToWiFi()) {
        connectionMode = ConnectionMode.WIFI;
        if (isHotspot())
            connectionMode = ConnectionMode.WIFI_HOSPOT;
        if (isWiFiDirect())
            connectionMode = ConnectionMode.WIFI_DIRECT;
    } else if (isMobileData()) {
        connectionMode = ConnectionMode.MOBILE_DATA;
    }
}

public boolean isRoaming() {
    try {
        ConnectivityManager connectivityManager = (ConnectivityManager) KeweltaApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = null;
        if (connectivityManager != null) {
            netInfo = connectivityManager.getActiveNetworkInfo();
        }
        if (netInfo != null) {
            return netInfo.isRoaming();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

public boolean isConnectedToWiFi() {
    try {
        ConnectivityManager connectivityManager = (ConnectivityManager) KeweltaApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = null;
        if (connectivityManager != null) {
            netInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        }
        if (netInfo != null && netInfo.getState() == NetworkInfo.State.CONNECTED) {
            return true;
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
    return false;
}

public boolean isHotspot() {
    boolean isWifiAPenabled = false;
    WifiManager wifi = (WifiManager) KeweltaApplication.getInstance().getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    Method[] wmMethods = new Method[0];
    if (wifi != null) {
        wmMethods = wifi.getClass().getDeclaredMethods();
    }
    for (Method method : wmMethods) {
        if (method.getName().equals("isWifiApEnabled")) {
            try {
                isWifiAPenabled = (Boolean) method.invoke(wifi);
            } catch (IllegalArgumentException | IllegalAccessException | InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
    return isWifiAPenabled;
}

public boolean isWiFiDirect() {
    return peerConnected;
}

public boolean isMobileData() {
    ConnectivityManager cm = (ConnectivityManager) KeweltaApplication.getInstance().getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetwork = null;
    if (cm != null) {
        activeNetwork = cm.getActiveNetworkInfo();
    }
    return activeNetwork != null && activeNetwork.getType() == ConnectivityManager.TYPE_MOBILE;
}
}

I made this Broadcast Receiver:

public class ConnectionReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals("android.net.conn.CONNECTIVITY_CHANGE")) {
        NetworkController.getNetworkController().updateNetworkStatus();
    }
}
}

I added to the manifest

<receiver android:name=".server.broadcast.ConnectionReceiver">
        <intent-filter>
            <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
        </intent-filter>
</receiver>

Update Network Status method only sets "OFFLINE" or "WIFI", and I need to know about the others connection types. Also, Android Studio Lint check says that "Declaring a broadcast receiver for android.net.conn.CONNECTIVITY_CHANGE is deprecated for apps targeting N and higher. In general apps should not rely on this broadcast and instead use JobScheduler or GCMNetworkManager". I'm sure about what this means and I looked up on stackoverflow looking for a more recently solution to my problem but I just found posts from more than three years ago. But that's not my problem right now, my problem is that connection type is not being detected. Methods "isMobileData", "isHotspot" and "isRoaming" aren't working.

Anton
  • 45
  • 7
  • Possible duplicate of [Android N not sending android.net.conn.CONNECTIVITY\_CHANGE broadcast?](https://stackoverflow.com/questions/39076910/android-n-not-sending-android-net-conn-connectivity-change-broadcast) – rds Sep 03 '18 at 16:02

1 Answers1

1

What that means is that you cannot implicitly listen for CONNECTIVITY_CHANGE from a broadcast receiver declared in your manifest. In N and up your broadcast receiver will not be called.

If you need the status you will need to create a foreground service and register a broadcast receiver in that service to listen for the connection changes

tyczj
  • 71,600
  • 54
  • 194
  • 296
  • That's not my problem right now, my problem is that connection type is not being detected correctly. Methods "isMobileData", "isHotspot" and "isRoaming" aren't working as expected. – Anton Jun 22 '18 at 17:25