Asked  7 Months ago    Answers:  5   Viewed   164 times

How do you detect the network connection type on Android?

Is it through ConnectivityManager.getActiveNetworkInfo().getType(), and is the answer limited to Wifi and mobile?

 Answers

84

If the problem is to find whether the phone's network is connected and fast enough to meet your demands you have to handle all the network types returned by getSubType().

It took me an hour or two to research and write this class to do just exactly that, and I thought I would share it with others that might find it useful.

Here is a Gist of the class, so you can fork it and edited it.

package com.emil.android.util;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.telephony.TelephonyManager;

/**
 * Check device's network connectivity and speed 
 * @author emil http://stackoverflow.com/users/220710/emil
 *
 */
public class Connectivity {

    /**
     * Get the network info
     * @param context
     * @return
     */
    public static NetworkInfo getNetworkInfo(Context context){
        ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        return cm.getActiveNetworkInfo();
    }

    /**
     * Check if there is any connectivity
     * @param context
     * @return
     */
    public static boolean isConnected(Context context){
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected());
    }

    /**
     * Check if there is any connectivity to a Wifi network
     * @param context
     * @return
     */
    public static boolean isConnectedWifi(Context context){
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_WIFI);
    }

    /**
     * Check if there is any connectivity to a mobile network
     * @param context
     * @return
     */
    public static boolean isConnectedMobile(Context context){
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && info.getType() == ConnectivityManager.TYPE_MOBILE);
    }

    /**
     * Check if there is fast connectivity
     * @param context
     * @return
     */
    public static boolean isConnectedFast(Context context){
        NetworkInfo info = Connectivity.getNetworkInfo(context);
        return (info != null && info.isConnected() && Connectivity.isConnectionFast(info.getType(),info.getSubtype()));
    }

    /**
     * Check if the connection is fast
     * @param type
     * @param subType
     * @return
     */
    public static boolean isConnectionFast(int type, int subType){
        if(type==ConnectivityManager.TYPE_WIFI){
            return true;
        }else if(type==ConnectivityManager.TYPE_MOBILE){
            switch(subType){
            case TelephonyManager.NETWORK_TYPE_1xRTT:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_CDMA:
                return false; // ~ 14-64 kbps
            case TelephonyManager.NETWORK_TYPE_EDGE:
                return false; // ~ 50-100 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_0:
                return true; // ~ 400-1000 kbps
            case TelephonyManager.NETWORK_TYPE_EVDO_A:
                return true; // ~ 600-1400 kbps
            case TelephonyManager.NETWORK_TYPE_GPRS:
                return false; // ~ 100 kbps
            case TelephonyManager.NETWORK_TYPE_HSDPA:
                return true; // ~ 2-14 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPA:
                return true; // ~ 700-1700 kbps
            case TelephonyManager.NETWORK_TYPE_HSUPA:
                return true; // ~ 1-23 Mbps
            case TelephonyManager.NETWORK_TYPE_UMTS:
                return true; // ~ 400-7000 kbps
            /*
             * Above API level 7, make sure to set android:targetSdkVersion 
             * to appropriate level to use these
             */
            case TelephonyManager.NETWORK_TYPE_EHRPD: // API level 11 
                return true; // ~ 1-2 Mbps
            case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
                return true; // ~ 5 Mbps
            case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
                return true; // ~ 10-20 Mbps
            case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
                return false; // ~25 kbps 
            case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
                return true; // ~ 10+ Mbps
            // Unknown
            case TelephonyManager.NETWORK_TYPE_UNKNOWN:
            default:
                return false;
            }
        }else{
            return false;
        }
    }

}

Also make sure to add this permission to you AndroidManifest.xml

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

Sources for network speeds include wikipedia & http://3gstore.com/page/78_what_is_evdo_mobile_broadband.html

Tuesday, June 1, 2021
 
tpow
answered 7 Months ago
73

The getActiveNetworkInfo() method of ConnectivityManager returns a NetworkInfo instance representing the first connected network interface it can find or null if none of the interfaces are connected. Checking if this method returns null should be enough to tell if an internet connection is available or not.

private boolean isNetworkAvailable() {
    ConnectivityManager connectivityManager 
          = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
    NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
    return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}

You will also need:

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

in your android manifest.

Edit:

Note that having an active network interface doesn't guarantee that a particular networked service is available. Network issues, server downtime, low signal, captive portals, content filters and the like can all prevent your app from reaching a server. For instance you can't tell for sure if your app can reach Twitter until you receive a valid response from the Twitter service.

Tuesday, June 1, 2021
 
Packy
answered 7 Months ago
68

From iOS 7 on you can use:

CTTelephonyNetworkInfo *telephonyInfo = [CTTelephonyNetworkInfo new];
NSLog(@"Current Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
[NSNotificationCenter.defaultCenter addObserverForName:CTRadioAccessTechnologyDidChangeNotification 
                                                object:nil 
                                                 queue:nil 
                                            usingBlock:^(NSNotification *note) 
{
    NSLog(@"New Radio Access Technology: %@", telephonyInfo.currentRadioAccessTechnology);
}];

I have also found this to detect a slow or fast connection:

- (BOOL)isFast:(NSString*)radioAccessTechnology {
    if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyGPRS]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyEdge]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyWCDMA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSDPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyHSUPA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMA1x]) {
        return NO;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORev0]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevA]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyCDMAEVDORevB]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyeHRPD]) {
        return YES;
    } else if ([radioAccessTechnology isEqualToString:CTRadioAccessTechnologyLTE]) {
        return YES;
    }

    return YES;
}
Thursday, June 3, 2021
 
HexaGridBrain
answered 7 Months ago
10

I think you got 2 options.

First option

First you should register your receiver not with code but within the manifest file. By this way it is registered automatically for your application. Within you receiver you have to store the current state of the network somewhere centrally perhaps in a custom Application class or a singleton class.

Implement some kind of observer pattern so that your activities could register themselves to your custom Application class which holds the network state. The Application class then informs every registered activity about the change of the network state.

You activity class register and unregister to/from the Application class in onCreate() and onDestroy() (better would be onResume() and onPause()) so they get only informed about network changes when they're visible.

Second option

Another option would be to stick to you current code and hold the reference of the Broadcast receiver somewhere centrally, again a custom Application class would do the job.

So your activities know where to find the receiver for registering and unregistering. But be aware that you have to find a place where you initiate the receiver. Also keep in mind that you have to handle the case where you application might be closed by Android because of low memory and restarted later, you'll then have to recreate your receiver.

Wednesday, June 30, 2021
 
Zach
answered 6 Months ago
37

Is there a good way to determine that the user has a fully functioning network connection?

Try downloading something from somewhere. Ideally, the "somewhere" is your own server, to test connectivity between the device and your server.

Alas, there are no doesTehConnexionSuck() or iCanHazBandwidth() methods on ConnectivityManager. :-)

Is this overkill?

In the spirit of "Goldilocks and the Three Bears", I'd describe that as justrightkill.

We have to do the same sorts of shenanigans in Web apps too.

Tuesday, August 3, 2021
 
avon_verma
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share