Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a way to detect which cellular network is used on Android?

Tags:

android

My app will feature live video streams. I would like to know if there is a way to detect if the user has 2G, 3G, or 4G on their devices, and if the which category the current connection belongs to? My question is specifically about Android devices.

like image 418
Android Developer Avatar asked Dec 06 '12 00:12

Android Developer


People also ask

What is cellular network in Android?

These settings configure Android's ability to connect to mobile (cellular) networks and use mobile data. In some regions this menu might be called Mobile networks. On some devices the Cellular networks menu might be hidden under a menu called More settings.

How do I check network state?

You can use the ConnectivityManager to check the network state. Note that the constants ConnectivityManager. TYPE_MOBILE and ConnectivityManager. TYPE_WIFI represent connection types and these two values are not exhaustive.


2 Answers

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
     * @param type
     * @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
     * @param type
     * @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>

For all less than or equal to 100kbps speed, the network is considered to be as 2G.

For all greater than 100kbps & less than 1mbps speed, the network is considered to be as 3G.

And for all greater than 1mbps speed, the network is considered to be as 4G.

Sources for network speeds include wikipedia http://en.wikipedia.org/wiki/Comparison_of_wireless_data_standards

like image 186
Vivek Bansal Avatar answered Oct 13 '22 00:10

Vivek Bansal


I'm not aware of a way to query the hardware capabilities of the device (which radios are present), but if you're asking how to detect the current type of cellular data connection, look to TelephonyManager.getNetworkType(), which "returns a constant indicating the radio technology (network type) currently in use on the device for data transmission".

I would consider the values NETWORK_TYPE_LTE and NETWORK_TYPE_HSPAP to indicates a 4G connection. Since the line between 3G and 4G is blurry, and since the set of older technologies is effectively fixed (we aren't inventing new 2G networks), a better strategy may be identifying network technologies that are not sufficient and displaying a warning if the connection is using a known slow technology (e.g., EDGE).

Also keep in mind that network technology alone doesn't necessarily equate to a certain connection speed. Even a 4G connection can run at speeds that are insufficient for video streaming depending on many factors, some of which are external to the device (weather, signal strength, device battery level, bandwidth available at the cell tower, etc.)

Other caveats:

  • You should first check whether the active network connection is a cellular connection. To do this, get ConnectivityManager.getActiveNetworkInfo() and examine that object's getType(). This will indicate whether the active network is Wi-Fi or cellular. Keep in mind that there may be no active network (null will be returned).

  • You should also check ConnectivityManager.isActiveNetworkMetered() for a hint about whether the current network connection has a data restriction. If so, you should warn the user before performing data-intensive operations regardless of the connection type.

like image 39
quietmint Avatar answered Oct 13 '22 01:10

quietmint