我正在上载大量数据的应用程序。我想确定上传的传输速率,以显示在通知中。
我对这些帖子中的答案不满意,所以我再次询问。
我看过显示上传传输速率的应用程序以及一些自定义ROM,例如Resurrection Remix。
如何确定这些上传的传输速率?
答案 0 :(得分:5)
使用android.net.TrafficStats
获取转移的流量是可行的。这是该思想的一种实现,它测量上游和下游传输速率。您可以通过将TrafficSpeedMeasurer.TrafficType.MOBILE
传递给TrafficSpeedMeasurer
构造函数来测量移动网络的速率,否则使用TrafficSpeedMeasurer.TrafficType.ALL
将导致测量一般流量(WiFi / Mobile)。同样,通过在SHOW_SPEED_IN_BITS = true
中设置MainActivity
,您可以将速度测量单位更改为每秒bit
s。
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);
}
}
}
。
答案 1 :(得分:3)
您要确定的是通过HTTP客户端上传的字节的传输速率。显然,这取决于您使用的HTTP客户端。
没有适用于Android上所有HTTP客户端的即用型解决方案。 Android SDK不提供任何方法来确定特定上载的传输速率。
幸运的是,您使用的是OKHttp,并且 是一种相对简单的方法。您将必须实现自定义RequestBody
,并观察请求进行过程中写入缓冲区的字节。
在OkHttp Github上执行此操作有一个“配方”: https://github.com/square/okhttp/blob/master/samples/guide/src/main/java/okhttp3/recipes/Progress.java
您还可以参考此StackOverflow问题,该问题完全相同: Tracking progress of multipart file upload using OKHTTP
答案 2 :(得分:0)
我是在您的应用程序上下文中进行交谈,因为这样可以更轻松地捕获上传数据的实时速度。您不需要任何额外的库或sdk api。
您大概正在将数据分块上传到服务器。所以
a)您知道每个数据包的数据大小
b)您知道发送数据包之前/发送多个数据包之前的开始时间
c)您可以通过服务器响应知道xy数据包的结束时间,例如状态200
有了这些参数,您就可以计算上传速度
double uploadSpeed = packet.size / (endTime - startTime)
//时间* 1000,以秒为单位
编辑:
由于您使用的是MultiPart
中的OkHttp
,因此可以监视上载的字节数。 Tracking progress of multipart file upload using OKHTTP。您可以将packet.size
替换为当前上传的数量,而endTime
的间隔为xy秒。