Measuring Download Speed with Java/Android

There are a few possible problems here:

  1. If you are looking to do this on the fly on an arbitrary device (vs. in a lab setting), you will need to follow Jeffrey's recommendation, because other apps can consume bandwidth that would be reported by getTotalRxBytes().

  2. This tests download speed from this host. If that is the host you will be communicating with for "real stuff", that's cool. Or, if you just generically need an idea of download speed, it's OK. But testing download speed from Site A and assuming that it will be accurate for Site B will be unreliable, as Site A and Site B might not even be on the same continent.

  3. If you expect to do this a lot, the owner of the host you are testing against may be mildly irritated at the bandwidth expense, excessive log entries, etc. Ideally, you would only do this against something you own.

  4. For metered data plans, 200KB might irritate the device owner.

  5. All the standard caveats regarding Internet access (e.g., server may be down) and mobile devices (e.g., user might start on WiFi and move out of range, drastically changing your download ability) apply.

All that being said, doing a download is the only real way to gauge download speeds.


Use the code below. I used it for measuring download speed. You don't need to save the file for the purpose of measuring download speed. You also probably don't need to use OkHttp. I used it because it was used in our project.

    String downloadURL = "http://test.talia.net/dl/1mb.pak";

    MediaType FILE = MediaType.parse("multipart/form-data;");

    OkHttpClient downloadClient = new OkHttpClient().newBuilder()
            .build();

    Request download = new Request.Builder()
            .url(downloadURL)
            .build();

    downloadClient.newCall(download).enqueue(new Callback() {
        @Override
        public void onFailure(Call call, IOException e) {

        }

        @Override
        public void onResponse(Call call, Response response) throws IOException {
            if(response!=null) {
                long startTime = System.currentTimeMillis();
                InputStream is = response.body().byteStream();
                BufferedInputStream bis = new BufferedInputStream(is);
                long size = 0;
                int red = 0;
                byte[] buf = new byte[1024];
                while ((red = bis.read(buf)) != -1) {
                    size += red;
                }
                long endTime = System.currentTimeMillis();
                double rate = (((size / 1024) / ((endTime - startTime) / 1000.0)) * 8);
                rate = Math.round( rate * 100.0 ) / 100.0;
                String ratevalue;
                if(rate > 1000)
                    ratevalue = String.valueOf(rate / 1024).concat(" Mbps");
                else
                    ratevalue = String.valueOf(rate).concat(" Kbps");
                if(is!=null) {
                    is.close();
                }
                if(bis!=null) {
                    bis.close();
                }
                Log.d("download", "download speed = " + ratevalue);
            }
        }
    });