network connection speed using TrafficStats - android

I am working on an android app that uses internet connectivity to work.I want to monitor the network speed using an indicator which will be red for poor connection, yellow for fair and green for good strength, and show it on the status bar so that the user may know the network speed all the time while using the app.I came across TrafficStats library in which I will get the no. of bytes transmitted using TrafficStats.getMobileTxbytes() and no. of bytes received using TrafficStats.getMobileRxbytes() but now I have a query to deal with.
TrafficStats would give network speed which is based on current data transfer. So if nothing is transferred in say last 10 seconds, it would return 0kbps speed and our indicator would be red, whereas actual network was good and it should have been green.
I am just a newbie in Android, and want some insights here.
Also is there some other good way to solve this problem?

Unfortunately, such data can only be estimated. There is no API in Android, that gives you an average speed in a specified amount of time.
Here is, what I made for specifying the average speed, based on the mobile network connection type (and the unit in external function):
public float mobileNetSpeed(Context context) {
TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
int networkType = tm.getNetworkType();
float netSpeed = getMobileNetworkSpeed(networkType);
return netSpeed;
}
private Network.NetworkSpeedUnits getMobileNetworkSpeedUnit(int networkType) {
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case 16: // TelephonyManager.NETWORK_TYPE_GSM:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
case TelephonyManager.NETWORK_TYPE_UMTS:
return Network.NetworkSpeedUnits.KBps;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
case 17: // TelephonyManager.NETWORK_TYPE_TD_SCDMA:
case TelephonyManager.NETWORK_TYPE_LTE:
case 18: // TelephonyManager.NETWORK_TYPE_IWLAN:
return Network.NetworkSpeedUnits.MBps;
default:
return Network.NetworkSpeedUnits.KBps;
}
}
/**
* Return hypothetical speed of mobile network. This method is an equivalent
* of {#link TelephonyManager#getNetworkClass()}
*
* #param networkType
* #return network speed by one of the XG type
*/
private float getMobileNetworkSpeed(int networkType) {
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
return 114;
case 16: // TelephonyManager.NETWORK_TYPE_GSM:
return 0;
case TelephonyManager.NETWORK_TYPE_EDGE:
return 296;
case TelephonyManager.NETWORK_TYPE_CDMA:
return 115;
case TelephonyManager.NETWORK_TYPE_1xRTT:
return 153;
case TelephonyManager.NETWORK_TYPE_IDEN:
return 60;
case TelephonyManager.NETWORK_TYPE_UMTS:
return 384;
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return 2.46F;
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return 3.1F;
case TelephonyManager.NETWORK_TYPE_HSDPA:
return 21.6F;
case TelephonyManager.NETWORK_TYPE_HSUPA:
return 5.76F;
case TelephonyManager.NETWORK_TYPE_HSPA:
return 14;
case TelephonyManager.NETWORK_TYPE_EVDO_B:
return 4.9F;
case TelephonyManager.NETWORK_TYPE_EHRPD:
return 1.285F;
case TelephonyManager.NETWORK_TYPE_HSPAP:
return 42;
case 17: // TelephonyManager.NETWORK_TYPE_TD_SCDMA:
return 0;
case TelephonyManager.NETWORK_TYPE_LTE:
return 100;
case 18: // TelephonyManager.NETWORK_TYPE_IWLAN:
return 0;
default:
return 0;
}
}
However, the code above will only work for mobile connection. When the WiFi is on, the method would be different:
public float getWiFiSpeed(Context context) {
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
return getWifiNetworkSpeed(wifiInfo);
}
/**
* Return general class of wifi network type. Unfortunately, there is no Android API method
* to do this, link speed in {#link WifiInfo#LINK_SPEED_UNITS "Mbps"} must be used
* and a maximum speed of wifi class must be compared with the value returned from
* {#link WifiInfo#getLinkSpeed()}.
*
* #param wifiInfo
* #return network speed by one of the WIFI_DRAFT_X type
*/
private float getWifiNetworkSpeed(WifiInfo wifiInfo) {
if (wifiInfo == null) {
return 0;
}
int linkSpeed = wifiInfo.getLinkSpeed(); //measured using WifiInfo.LINK_SPEED_UNITS
return linkSpeed;
}

Related

How to Check whether the connected network is having data communication or not continuously while the app is running?

My application completely depends on the network so I have to check whether the data communication is there between the application and my server and make a popup on communication lost and if not connected to Wifi or Mobile Data and if the connected service is having slow connection.
I am using the following code where I can get whether the device is connected to the Wifi or mobile data and get the type of connection and also got the code to get the type of mobile network connected which is not working at all.
please refer the following code...
public void CheckInternet()
{
Plugin.Connectivity.CrossConnectivity.Current.ConnectivityChanged += delegate
{
if (!(Plugin.Connectivity.CrossConnectivity.Current.IsConnected))
{
StartActivity(typeof(InternetCheckingView));
}
if (Plugin.Connectivity.CrossConnectivity.Current.IsConnected)
{
ConnectivityManager connectivityManager = (ConnectivityManager)GetSystemService(ConnectivityService);
NetworkInfo networkInf = connectivityManager.ActiveNetworkInfo;
bool isOnline = networkInf.IsConnected;
NetworkInfo networkInfo = connectivityManager.ActiveNetworkInfo;
bool isWifi = networkInfo.Type == ConnectivityType.Wifi;
bool isdata = networkInfo.Type == ConnectivityType.Mobile;
if (!isOnline)
{ StartActivity(typeof(InternetCheckingView)); }
else if(isWifi)
{
Toast.MakeText(_context, "Wifi Connected", ToastLength.Short).Show();
}
else if (isdata)
{
Toast.MakeText(_context, "Mobile Data Connected", ToastLength.Short).Show();
bool datatype = IsConnectionFast(subType);
if(!(datatype))
{StartActivity(typeof(InternetCheckingView));}
}
}
};
}
public bool IsConnectionFast(object networkType)
{
switch (subType)
{
//case TelephonyManager.NETWORK_TYPE_1xRTT:
case NetworkType.OneXrtt:
return false; // ~ 50-100 kbps//case TelephonyManager.NETWORK_TYPE_CDMA:
case NetworkType.Cdma:
return false; // ~ 14-64 kbps//case TelephonyManager.NETWORK_TYPE_EDGE:
case NetworkType.Edge:
return false; // ~ 50-100 kbps//case TelephonyManager.NETWORK_TYPE_EVDO_0:
case NetworkType.Evdo0:
return true; // ~ 400-1000 kbps //case TelephonyManager.NETWORK_TYPE_EVDO_A:
case NetworkType.EvdoA:
return true; // ~ 600-1400 kbps//case TelephonyManager.NETWORK_TYPE_GPRS:
case NetworkType.Gprs:
return false; // ~ 100 kbps//case TelephonyManager.NETWORK_TYPE_HSDPA:
case NetworkType.Hsdpa:
return true; // ~ 2-14 Mbps//case TelephonyManager.NETWORK_TYPE_HSPA:
case NetworkType.Hspa:
return true; // ~ 700-1700 kbps//case TelephonyManager.NETWORK_TYPE_HSUPA:
case NetworkType.Hsupa:
return true; // ~ 1-23 Mbps//case TelephonyManager.NETWORK_TYPE_UMTS:
case NetworkType.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
case NetworkType.Ehrpd:
return true; // ~ 1-2 Mbps//case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
case NetworkType.EvdoB:
return true; // ~ 5 Mbps//case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
case NetworkType.Hspap:
return true; // ~ 10-20 Mbps//case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
case NetworkType.Iden:
return false; // ~25 kbps//case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
case NetworkType.Lte:
return true; // ~ 10+ Mbps// Unknown//case TelephonyManager.NETWORK_TYPE_UNKNOWN:
case NetworkType.Unknown:
return false;
default:
return false;
}
}
Here I would like to detect the slow network or not and if that is a slow network I have to call StartActivity(typeof(InternetCheckingView))
Can any one please help me to do that in I would like to open a popup whenever there is no data communication available like a onclicklisner in so that the even filers when ever there is a data loss even when the network is connected
(Added--)
I am checking for the data communication by pinging a url when the network connected change like disconnected or changes between wifi and mobile data but i would like to know the solution to get a popup to connect network whenever the data communication is lost even if it is connected to the network only when the app is opened.

Android - Need help to get frequency band

I'm trying to find the current frequency band.
I read a lot on this issue in the past few days but I didn't found anything.
I need solution for it (code not an app).
If I can access to this data by getting root access it is also OK.
For network type You can use this method (from here):
public static String getNetworkClass(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
if(info==null || !info.isConnected())
return "-"; //not connected
if(info.getType() == ConnectivityManager.TYPE_WIFI)
return "WIFI";
if(info.getType() == ConnectivityManager.TYPE_MOBILE){
int networkType = info.getSubtype();
switch (networkType) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA:
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN: //api<8 : replace by 11
return "2G";
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_0:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B: //api<9 : replace by 14
case TelephonyManager.NETWORK_TYPE_EHRPD: //api<11 : replace by 12
case TelephonyManager.NETWORK_TYPE_HSPAP: //api<13 : replace by 15
return "3G";
case TelephonyManager.NETWORK_TYPE_LTE: //api<11 : replace by 13
return "4G";
default:
return "?";
}
}
return "?";
}
But to get frequency You should work directly with GSM module of phone via AT Commands like AT!BAND? for Sierra modules or AT+CBAND? for other. It's also possible, but with hard way like this. Or may be something like that but it hardly ever.

Any way to identify the data type being used (2G/3G) in Android?

I need to stop the Android app from syncing data to the server when it is using 2G network connection and allow it when it is using 3G/4G or WiFi connection, the data/WiFi identification is easy but how can I know if the phone is currently using 2G mode or 3G/4G mode?
Using TelephonyManager can identify the SIM mode but not the actual data carrier being used in real-time, since Android assigns E icon for 2G and H,H+for 3G then there must be a way to identify this. Any ideas?
Yes, there is.
On TelephonyManager you have some constants like TelephonyManager.NETWORK_TYPE_EDGE to check that. Use those constants along with the methods getType() and getSubtype() from NetworkInfo.
EDIT: I was being stupid. You can simply call NetworkInfo.getSubtypeName and you're good to go.
NetworkInfo info = Connectivity.getNetworkInfo(context);
Log.d("tag","Network type: " + info.getSubtypeName());
Or you could also try the other solution.
OLD SOLUTION
Try something like:
NetworkInfo info = Connectivity.getNetworkInfo(context);
getConnectionType(info.getType(),info.getSubtype());
And call this function:
private String getConnectionType(int type, int subType) {
if(type==ConnectivityManager.TYPE_WIFI){
return "WiFi";
}
else if(type==ConnectivityManager.TYPE_MOBILE){
switch(subType){
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_CDMA:
return "1G"; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_GPRS:
return "2G"; // ~ 50-100 kbps
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_UMTS:
return "3G"; // ~ 2-14 Mbps
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return "4G"; // ~ 10+ Mbps
// Unknown
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
default:
return "Not defined";
}
}
else{
return "Not defined";
}
}
Of course, the method above is just a suggestion to show how it works, you can change it for your own purposes, and make it more complete, change the return type, etc.

Android - Check if device supports 4G/LTE

How to determine if a android device supports 4G/LTE networks?
Checking the current network type is not an option, because I have to check it even if the current network type is 3G.
UPDATE:
OK, I have managed to detect the prefered_network_mode by:
Settings.Secure.getInt(context.getContentResolver(), "preferred_network_mode", -1);
It work's fine on HTC One but on Samsung devices it always returns a 0 value when it should return more then a 0 value and that is the main problem now ;/
Does Samsung phones store the preferred network mode somewhere else ?
/**
* 获取当前网络类型
*
* #param context
* #return 2G/3G/4G/WIFI/no/unknown
*/
public static String getNetType(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo info = cm.getActiveNetworkInfo();
if (info == null || !info.isAvailable()) {
return "no";
}
if (info.getType() == ConnectivityManager.TYPE_WIFI) {
return "WIFI";
}
if (info.getType() == ConnectivityManager.TYPE_MOBILE) {
int sub = info.getSubtype();
switch (sub) {
case TelephonyManager.NETWORK_TYPE_GPRS:
case TelephonyManager.NETWORK_TYPE_EDGE:
case TelephonyManager.NETWORK_TYPE_CDMA://电信的2G
case TelephonyManager.NETWORK_TYPE_1xRTT:
case TelephonyManager.NETWORK_TYPE_IDEN:
//以上的都是2G网络
return "2G";
case TelephonyManager.NETWORK_TYPE_UMTS:
case TelephonyManager.NETWORK_TYPE_EVDO_A:
case TelephonyManager.NETWORK_TYPE_HSDPA:
case TelephonyManager.NETWORK_TYPE_HSUPA:
case TelephonyManager.NETWORK_TYPE_HSPA:
case TelephonyManager.NETWORK_TYPE_EVDO_B:
case TelephonyManager.NETWORK_TYPE_EHRPD:
case TelephonyManager.NETWORK_TYPE_HSPAP:
//以上的都是3G网络
return "3G";
case TelephonyManager.NETWORK_TYPE_LTE:
return "4G";
case TelephonyManager.NETWORK_TYPE_UNKNOWN:
return "unknown";
default:
return "unknown";
}
}
return "unknown";
}

Android : how to find band width of a WiFi channel programmatically?

In my App, am using ScanResult to get the list of networks. How do I find the bandwidth of the networks (say is it 22MHz or 40MHz etc) ?
You can get the range of bandwidth by using the below functions but not the exact bandwidth.
public static void printBandwidthOfConnection(Context context){
NetworkInfo info = Connectivity.getNetworkInfo(context);
Log.i("Range",rangeOfConnection(info.getType(),info.getSubtype())));
}
/**
* Check if the connection is fast
* #param type
* #param subType
* #return string
*/
public static String rangeOfConnection(int type, int subType){
if(type==ConnectivityManager.TYPE_WIFI){
return "wifi";
}else if(type==ConnectivityManager.TYPE_MOBILE){
switch(subType){
case TelephonyManager.NETWORK_TYPE_1xRTT:
return "50-100 kbps";
case TelephonyManager.NETWORK_TYPE_CDMA:
return " 14-64 kbps";
case TelephonyManager.NETWORK_TYPE_EDGE:
return "50-100 kbps";
case TelephonyManager.NETWORK_TYPE_EVDO_0:
return "400-1000 kbps";
case TelephonyManager.NETWORK_TYPE_EVDO_A:
return "600-1400 kbps";
case TelephonyManager.NETWORK_TYPE_GPRS:
return "100 kbps";
case TelephonyManager.NETWORK_TYPE_HSDPA:
return "2-14 Mbps";
case TelephonyManager.NETWORK_TYPE_HSPA:
return "700-1700 kbps";
case TelephonyManager.NETWORK_TYPE_HSUPA:
return "1-23 Mbps"
case TelephonyManager.NETWORK_TYPE_UMTS:
return "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 " 1-2 Mbps";
case TelephonyManager.NETWORK_TYPE_EVDO_B: // API level 9
return "5 Mbps";
case TelephonyManager.NETWORK_TYPE_HSPAP: // API level 13
return "10-20 Mbps";
case TelephonyManager.NETWORK_TYPE_IDEN: // API level 8
return "25 kbps";
case TelephonyManager.NETWORK_TYPE_LTE: // API level 11
return "10+ Mbps";
default:
return null;
}
}else{
return null;
}
}

Categories

Resources