how to measure upload/download speed and latency in android wifi connection

Solution 1:

Are you using 2.2 (Froyo) or higher?

If so, in your application, import Traffic Stats and when your application is using the internet add in the following.

Download/Upload:

long BeforeTime = System.currentTimeMillis();
long TotalTxBeforeTest = TrafficStats.getTotalTxBytes();
long TotalRxBeforeTest = TrafficStats.getTotalRxBytes();

/* DO WHATEVER NETWORK STUFF YOU NEED TO DO */

long TotalTxAfterTest = TrafficStats.getTotalTxBytes();
long TotalRxAfterTest = TrafficStats.getTotalRxBytes();
long AfterTime = System.currentTimeMillis();

double TimeDifference = AfterTime - BeforeTime;

double rxDiff = TotalRxAfterTest - TotalRxBeforeTest;
double txDiff = TotalTxAfterTest - TotalTxBeforeTest;

if((rxDiff != 0) && (txDiff != 0)) {
    double rxBPS = (rxDiff / (TimeDifference/1000)); // total rx bytes per second.
    double txBPS = (txDiff / (TimeDifference/1000)); // total tx bytes per second.
    testing[0] = String.valueOf(rxBPS) + "B/s. Total rx = " + rxDiff;
    testing[1] = String.valueOf(txBPS) + "B/s. Total tx = " + txDiff;
}
else {
    testing[0] = "No uploaded or downloaded bytes.";
}

Now you have testing[0] is your download speed (roughly) and testing[1] is your upload speed (roughly)

Just make sure you are only calling this code when you are actually doing network communication or the time will skew your results.

As per latency, there is nothing that great out there. I've written this which is untested, but should work ok, but there are likely better solutions available.

Latency:

String host = YOUR_HOST
HttpGet request = new HttpGet(host);
HttpParams httpParameters = new BasicHttpParams();
HttpConnectionParams.setConnectionTimeout(httpParameters, 3000);
HttpClient httpClient = new DefaultHttpClient(httpParameters);

for(int i=0; i<5; i++) {
    long BeforeTime = System.currentTimeMillis();
    HttpResponse response = httpClient.execute(request);
    long AfterTime = System.currentTimeMillis();
    Long TimeDifference = AfterTime - BeforeTime;
    time[i] = TimeDifference 
}

Note: Keep in mind that this will not say the latency at your time of use, but give you an idea of the latency experienced on the network you are using at a particular period of time. Also, this is the request and response time, instead of the request reaching the network time as say "ping" would normally do.

Solution 2:

There are 2 main ways to calculate download/upload speed.

Passive testing - this is what has been suggested already using TrafficStats API. This method will give you speed which is more closer to the actual user experience. However, it will not provide you with capacity measurement - i.e what is the expected capacity of the connection. For example for fixed networks ISPs usualy sell packages based on speed - e.g. 100 Mbit package, 1 Gbit package. If you want to see if that ISP is delivering the speed, Passive approach is not the way! The speeds will be much lower as users are not using full capacity all the time. Also, keep in mind its not possible to do latency testing using passive approach using TrafficStats.

Active testing - this method requires downloading and uploading data to the remote server to get the download/upload speed and latency. For this type of testing there are many sampling methodologies , there is no one "true" speed. You can check following standards to give you more idea what is the recommended way:

https://itu.int/en/ITU-T/C-I/Pages/IM/Internet-speed.aspx

https://itu.int/itu-t/recommendations/rec.aspx?rec=q.3960

https://itu.int/ITU-T/recommendations/rec.aspx?rec=14125

https://tools.ietf.org/pdf/rfc6349.pdf

You can also use our Android SDK which should do what you need and is compliant with ITU standard:

https://github.com/speedchecker/speedchecker-sdk-android

Secondly, you have not made it clear whether you are after "wifi speed" or "internet speed". Wifi speed is local network speed that is measured differently from "internet speed". While there are many ways to test "internet speed", testing "wifi speed" is much more challenging as typically its problematic to get the remote server in the local network. Again, our Android SDK I referenced above has measurement of wifi speed as well