The naïve way is bytes_downloaded / (now - start_time)
, but that becomes inaccurate if the connection speed fluctuates wildly, or if the user starts another download (perhaps in another app) halfway through your download. Both of these may happen if the user runs a torrent in the background.
A better way (though harder to implement) is to keep an array of periodic samples and present the average.
Start out with an array containing 0. The array is of samples, and each sample is the number of bytes downloaded since the previous sample. Then start the download.
Every half-second (you can try different intervals), measure how many bytes you've downloaded, then subtract the previous total from this new total. Add the difference as the new last element in the array. If this grows the array beyond a certain size, lop off the first element (oldest sample). Then, present the average of all the samples.
You should keep somewhere between 2–5 seconds' worth of samples, and the interval should be somewhere between 0.5 and 1 seconds (it's a trade-off between currency and performance).
You may also want to remove the first element from the array after retrieving it if it is zero. This makes your starting reportage more accurate and helps you recover more quickly from stalls, since you're not including old zeroes in the average.