Как определить скорость загрузки / выгрузки в Android? - PullRequest
0 голосов
/ 20 ноября 2018

Я работаю над приложением, которое загружает большой объем данных.Я хочу определить скорость передачи загрузки, чтобы показать в уведомлении.

  • Один пост предлагает использовать WifiInfo, который не будет работать для мобильных данных.
  • Другой пост предлагает получить тип сети для оценки скорости.

Я не удовлетворен ответами в этих постах, поэтому я спрашиваю снова.

Я видел приложения, которые отображают скорость передачи загрузки, а также некоторые пользовательские ПЗУ, такие как Resurrection Remix .

Как определить скорость передачи этих загрузок?

Ответы [ 3 ]

0 голосов
/ 28 ноября 2018

То, что вы пытаетесь определить, это скорость передачи байтов, загружаемых через ваш HTTP-клиент.Очевидно, это зависит от используемого вами HTTP-клиента.

Не существует готового решения, которое применимо ко всем HTTP-клиентам, используемым на Android.Android SDK не предоставляет никаких методов для определения скорости передачи конкретной загрузки.

К счастью, вы используете OKHttp, и - это относительно простой способ сделать это.этот.Вам нужно будет реализовать пользовательский RequestBody и наблюдать, как байты записываются в буфер, когда запрос находится в полете.

Для этого на OkHttp Github есть «рецепт»: https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Progress.java

Вы также можете обратиться к этому вопросу StackOverflow, касающемуся той же самой темы: Отслеживание хода многоэтапной загрузки файла с использованием OKHTTP

Другой здесь: OKHTTP3 Отслеживание прогресса загрузки нескольких частей

0 голосов
/ 29 ноября 2018

Возможно получить количество передаваемого трафика, используя android.net.TrafficStats.Вот реализация этой идеи, которая измеряет восходящую и нисходящую скорость передачи.Вы можете измерить скорость мобильной сети, передав TrafficSpeedMeasurer.TrafficType.MOBILE конструктору TrafficSpeedMeasurer, в противном случае использование TrafficSpeedMeasurer.TrafficType.ALL приведет к измерению общего трафика (WiFi / Mobile).Также, установив SHOW_SPEED_IN_BITS = true в MainActivity, вы можете изменить единицу измерения скорости на bit с в секунду.

MainActivity.java

import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    private static final boolean SHOW_SPEED_IN_BITS = false;

    private TrafficSpeedMeasurer mTrafficSpeedMeasurer;
    private TextView mTextView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = findViewById(R.id.connection_class);

        mTrafficSpeedMeasurer = new TrafficSpeedMeasurer(TrafficSpeedMeasurer.TrafficType.ALL);
        mTrafficSpeedMeasurer.startMeasuring();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mTrafficSpeedMeasurer.stopMeasuring();
    }

    @Override
    protected void onPause() {
        super.onPause();
        mTrafficSpeedMeasurer.removeListener(mStreamSpeedListener);
    }

    @Override
    protected void onResume() {
        super.onResume();
        mTrafficSpeedMeasurer.registerListener(mStreamSpeedListener);
    }

    private ITrafficSpeedListener mStreamSpeedListener = new ITrafficSpeedListener() {

        @Override
        public void onTrafficSpeedMeasured(final double upStream, final double downStream) {
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    String upStreamSpeed = Utils.parseSpeed(upStream, SHOW_SPEED_IN_BITS);
                    String downStreamSpeed = Utils.parseSpeed(downStream, SHOW_SPEED_IN_BITS);
                    mTextView.setText("Up Stream Speed: " + upStreamSpeed + "\n" + "Down Stream Speed: " + downStreamSpeed);
                }
            });
        }
    };

}

TrafficSpeedMeasurer.java

import android.net.TrafficStats;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;


public class TrafficSpeedMeasurer {

    private ITrafficSpeedListener mTrafficSpeedListener;
    private SamplingHandler mHandler;

    private TrafficType mTrafficType;
    private long mLastTimeReading;
    private long mPreviousUpStream = -1;
    private long mPreviousDownStream = -1;

    public TrafficSpeedMeasurer(TrafficType trafficType) {
        mTrafficType = trafficType;
        HandlerThread thread = new HandlerThread("ParseThread");
        thread.start();
        mHandler = new SamplingHandler(thread.getLooper());
    }

    public void registerListener(ITrafficSpeedListener iTrafficSpeedListener) {
        mTrafficSpeedListener = iTrafficSpeedListener;
    }

    public void removeListener(ITrafficSpeedListener iTrafficSpeedListener) {
        mTrafficSpeedListener = iTrafficSpeedListener;
    }

    public void startMeasuring() {
        mHandler.startSamplingThread();
        mLastTimeReading = SystemClock.elapsedRealtime();
    }

    public void stopMeasuring() {
        mHandler.stopSamplingThread();
        finalReadTrafficStats();
    }

    private void readTrafficStats() {
        long newBytesUpStream = (mTrafficType == TrafficType.MOBILE ? TrafficStats.getMobileTxBytes() : TrafficStats.getTotalTxBytes()) * 1024;
        long newBytesDownStream = (mTrafficType == TrafficType.MOBILE ? TrafficStats.getMobileRxBytes() : TrafficStats.getTotalRxBytes()) * 1024;

        long byteDiffUpStream = newBytesUpStream - mPreviousUpStream;
        long byteDiffDownStream = newBytesDownStream - mPreviousDownStream;

        synchronized (this) {
            long currentTime = SystemClock.elapsedRealtime();
            double bandwidthUpStream = 0;
            double bandwidthDownStream = 0;

            if (mPreviousUpStream >= 0) {
                bandwidthUpStream = (byteDiffUpStream) * 1.0 / (currentTime - mLastTimeReading);
            }
            if (mPreviousDownStream >= 0) {
                bandwidthDownStream = (byteDiffDownStream) * 1.0 / (currentTime - mLastTimeReading);
            }
            if (mTrafficSpeedListener != null) {
                mTrafficSpeedListener.onTrafficSpeedMeasured(bandwidthUpStream, bandwidthDownStream);
            }

            mLastTimeReading = currentTime;
        }

        mPreviousDownStream = newBytesDownStream;
        mPreviousUpStream = newBytesUpStream;
    }

    private void finalReadTrafficStats() {
        readTrafficStats();
        mPreviousUpStream = -1;
        mPreviousDownStream = -1;
    }

    private class SamplingHandler extends Handler {

        private static final long SAMPLE_TIME = 1000;
        private static final int MSG_START = 1;

        private SamplingHandler(Looper looper) {
            super(looper);
        }

        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_START:
                    readTrafficStats();
                    sendEmptyMessageDelayed(MSG_START, SAMPLE_TIME);
                    break;
                default:
                    throw new IllegalArgumentException("Unknown what=" + msg.what);
            }
        }

        void startSamplingThread() {
            sendEmptyMessage(SamplingHandler.MSG_START);
        }

        void stopSamplingThread() {
            removeMessages(SamplingHandler.MSG_START);
        }

    }

    public enum TrafficType {
        MOBILE,
        ALL
    }

}

ITrafficSpeedListener.java

public interface ITrafficSpeedListener {

    void onTrafficSpeedMeasured(double upStream, double downStream);
}

Utils.java

import java.util.Locale;

public class Utils {

    private static final long B = 1;
    private static final long KB = B * 1024;
    private static final long MB = KB * 1024;
    private static final long GB = MB * 1024;

    public static String parseSpeed(double bytes, boolean inBits) {
        double value = inBits ? bytes * 8 : bytes;
        if (value < KB) {
            return String.format(Locale.getDefault(), "%.1f " + (inBits ? "b" : "B") + "/s", value);
        } else if (value < MB) {
            return String.format(Locale.getDefault(), "%.1f K" + (inBits ? "b" : "B") + "/s", value / KB);
        } else if (value < GB) {
            return String.format(Locale.getDefault(), "%.1f M" + (inBits ? "b" : "B") + "/s", value / MB);
        } else {
            return String.format(Locale.getDefault(), "%.2f G" + (inBits ? "b" : "B") + "/s", value / GB);
        }
    }

}

.

Визуальный результат

enter image description here

0 голосов
/ 28 ноября 2018

Я говорю в контексте вашего приложения, поскольку это облегчает отслеживание скорости ваших загруженных данных в режиме реального времени.Вам не нужны дополнительные библиотеки или SDK API.

Предположительно, вы загружаете данные частями на сервер.Итак,

a) Вы знаете размер данных каждого пакета
b) Вы знаете время начала перед отправкой пакета / до отправки нескольких пакетов
c) Вы знаете время окончания пакетов xy поответ сервера, например, статус 200

С этим у вас есть все параметры для расчета скорости загрузки

double uploadSpeed = packet.size / (endTime - startTime) // время * 1000, чтобы иметь ее в секундах

РЕДАКТИРОВАТЬ:

Поскольку вы используете MultiPart из OkHttp, вы можете отслеживать количество загруженных байтов. Отслеживание хода многоэтапной загрузки файла с использованием OKHTTP .Вы бы заменили packet.size текущей загруженной суммой, а endTime будет интервалом xy секунд.

...