2

I'm newbie in Android.

Can anyone say, how to display in Android UI, during download progressing state, the speed at which a file (say xyz.mp4) is downloading and remaining time to complete download the xyz.mp4 file.

I am using AsyncTask for download task, and I want to display speed and time along with "Progress Percentage". I'm using ProgressDialog in DialogFragment.

Solution

class DownloadVideoFromUrl extends AsyncTask<String, String, String> {
    @Override
    protected void onPreExecute() {
        super.onPreExecute();

        // Do your pre executing codes (UI part)...
        // The ProgressDialog initializations...
    }

    @Override
    protected String doInBackground(String... params) {
        if(params.length < 2)   return "";

        String videoUrlStr = params[0];
        String fileName = params[1];

        try {
            URL url = new URL(videoUrlStr);
            URLConnection conection = url.openConnection();
            conection.connect();

            // This will be useful so that you can show a 0-100% progress bar
            int fileSizeInB = conection.getContentLength();

            // Download the file
            InputStream input = new BufferedInputStream(url.openStream(), 8 * 1024); // 8KB Buffer
            File file = new File(Environment.getExternalStoragePublicDirectory(
                    Environment.DIRECTORY_DOWNLOADS), fileName);
            OutputStream output = new FileOutputStream(file);
            int bufferSizeInB = 1024;
            byte byteBuffer[] = new byte[bufferSizeInB];
            int bytesRead;

            long bytesInInterval = 0;
            int timeLimit = 500;    // ms.
            long timeElapsed = 0;   // ms.
            long nlwSpeed = 0;      String nlwSpeedStr = null;

            long availableB = 0;
            long remainingBytes = fileSizeInB;
            long remainingTime = 0; String remainingTimeStr = null;

            long startingTime = System.currentTimeMillis();
            while ((bytesRead = input.read(byteBuffer)) != -1) {    // wait to download bytes...
                // bytesRead => bytes already Red
                output.write(byteBuffer, 0, bytesRead);
                availableB += bytesRead;
                bytesInInterval += bytesRead;
                remainingBytes -= bytesRead;

                timeElapsed = System.currentTimeMillis() - startingTime;
                if(timeElapsed >= timeLimit) {
                    nlwSpeed = bytesInInterval*1000 / timeElapsed;  // In Bytes per sec
                    nlwSpeedStr = nlwSpeed + " Bytes/sec";

                    remainingTime = (long)Math.ceil( ((double)remainingBytes / nlwSpeed) ); // In sec
                    remainingTimeStr = remainingTime + " seconds remaining";

                    // Resetting for calculating nlwSpeed of next time interval
                    timeElapsed = 0;
                    bytesInInterval = 0;
                    startingTime = System.currentTimeMillis();  
                }
                publishProgress(
                        "" + availableB,    // == String.valueOf(availableB) 
                        "" + fileSizeInB,
                        "" + bytesRead,     // Not currently using. Just for debugging...
                        remainingTimeStr,
                        nlwSpeedStr);
            }

            output.flush();
            output.close();
            input.close();
        } catch (Exception e) {
            return "\n Download - Error: " + e;
        }

        return "";
    }

    protected void onProgressUpdate(String... progress) {
        int availableB = Integer.parseInt(progress[0]);
        int totalB = Integer.parseInt(progress[1]);
        int percent = (availableB *100)/totalB;   // here we get percentage of download...

        String remainingTime = progress[3];
        String nlwSpeed = progress[4];

        if(remainingTime == null || nlwSpeed == null) return;

        // Now show the details in UI:
        // percent, remainingTime, nlwSpeed...
    }

    @Override
    protected void onPostExecute(String result) {
        // Code after download completes (UI part)
    }
}
Chris J
  • 949
  • 9
  • 15

1 Answers1

1

Have you checked the TrafficStats class? There is a wealth of information in there.

Here is a Example of TrafficStats

If you are looking for the maximum download/upload speed for an network interface, well wget has been ported to Android, so you can use any of these answers

Here is a source code of a small app that measures download speed on edge or 3g Detecting Network Speed and Type on Android (Edge,3G)

You can also try following code

private SpeedInfo calculate(final long downloadTime, final long bytesIn) {
    SpeedInfo info=new SpeedInfo();
    //from mil to sec
    long bytespersecond   = (bytesIn / downloadTime) * 1000;
    double kilobits = bytespersecond * BYTE_TO_KILOBIT;
    double megabits = kilobits  * KILOBIT_TO_MEGABIT;
    info.downspeed = bytespersecond;
    info.kilobits = kilobits;
    info.megabits = megabits;

    return info;
}

private static class SpeedInfo { 
    public double kilobits = 0;
    public double megabits = 0;
    public double downspeed = 0;        
}


private static final int EXPECTED_SIZE_IN_BYTES = 1048576; //1MB 1024*1024

private static final double EDGE_THRESHOLD = 176.0;
private static final double BYTE_TO_KILOBIT = 0.0078125;
private static final double KILOBIT_TO_MEGABIT = 0.0009765625;
Sanket Shah
  • 4,352
  • 3
  • 21
  • 41
  • But I've a doubt. Suppose I am downloading a file from a **browser app** and downloading a `xyz.mp4` from my own **another app `abc`** concurrently, then my app need only download speed information of `abc` app only. So will the above given code work here??? Tnx 4 Rply – Chris J Sep 04 '13 at 08:12
  • How to pass parameters `downloadTime` and `bytesIn` ?? What does it mean ?? – Chris J Sep 04 '13 at 08:18
  • 2
    In that case it is not working because this class is in your app not in browser. and downloadtime and bytesIn, you have to calculate from your file. – Sanket Shah Sep 04 '13 at 08:38
  • So, you mean the speed information is only about downloading task in `abc` only and NOT about downloading in **browser app** ? (Yes/No) This doubt occurred because we are collecting network information from the **Android System** which records information of both app `abc` and **browser** – Chris J Sep 04 '13 at 08:50
  • 1
    no it is not about your abc only. but calculation of of speed depends on native apps. – Sanket Shah Sep 04 '13 at 09:05
  • OK Got it... But How to get `downloadTime` function parameter of the native app before downloading ??? I want to show it as progress in `ProgressDialog` – Chris J Sep 04 '13 at 09:12
  • 2
    just visit Detecting Network Speed and Type on Android (Edge,3G) as i mention in my link you got what you want. – Sanket Shah Sep 04 '13 at 09:21
  • Tricky method. OK Got it. No need of `TrafficStats`. Thank you very much – Chris J Sep 04 '13 at 11:39
  • Once you got the solution then please let me know i want to learn other methods for same. – Sanket Shah Sep 04 '13 at 11:42
  • Sorry for delay. The solution code given above. Here I'm not using `TrafficStats` – Chris J Sep 06 '13 at 13:31
  • then what kind of other method you are using? @ChrisJ – Sanket Shah Sep 07 '13 at 03:59
  • Actual code is complicated. So I simplify the code. If you want, to know, how it works, then go to -> [ProgressDialog with AsyncTask](http://stackoverflow.com/a/15758953/2376893) – Chris J Sep 07 '13 at 07:34
  • If you are following that answer then your question is worthless. you are asking about to know downloading speed and i cant get any method for same in your above link. – Sanket Shah Sep 07 '13 at 09:03
  • Code in the above link do not show `download speed` & `remaining time`. So I modified that code using the **SOLUTION** code given above. There is no method(or function). Only using some formula to calculate `download speed` & `remaining time`. – Chris J Sep 07 '13 at 13:12