Android 獲取實時網速實現詳解
正文
最近接到個需求,需要計算WebView
加載網頁時的網速。查詢瞭一下,Android沒有提供直接獲取網速的Api,但是提供瞭獲取流量的類TrafficStats
。本文介紹如何使用Trafficstats
來實現獲取網速功能。
TrafficStats簡介
TrafficStats
提供瞭一些獲取設備從本次開機到目前為止傳輸/接收的流量的接口,如下:
方法 | 參數 | 說明 |
---|---|---|
getTotalTxBytes | – | 獲取設備本次開機到目前為止,WI-FI、流量下傳輸的字節總數。 |
getTotalRxBytes | – | 獲取設備本次開機到目前為止,WI-FI、流量下接收的字節總數。 |
getMobileTxBytes | – | 獲取設備本次開機到目前為止,流量下傳輸的字節總數。 |
getMobileRxBytes | – | 獲取設備本次開機到目前為止,流量下接收的字節總數。 |
getUidTxBytes | uid | 獲取應用從本次開機到目前為止,WI-FI、流量下傳輸的字節總數。 |
getUidRxBytes | uid | 獲取應用從本次開機到目前為止,WI-FI、流量下接收的字節總數。 |
上述接口可以滿足實現計算網速的需求,TrafficStats
類其他接口可以查看官方文檔。
實現獲取網速
可以通過一段時間內傳輸的流量除去時間計算出上行網速,通過一段時間內接收的流量除去時間計算出下行網速。
TrafficStats
類的接口獲取的網速是從開機時就開始計算的,因此,要計算一段時間內的流量需要在開始時獲取一次流量數據,結束時獲取一次流量數據,相減得出一段時間的實際流量。
實時網速
本文用getUidTxBytes
和getUidRxBytes
來演示,其他方法也是類似的,如下:
object NetSpeedUtils { var netSpeedCallback: NetSpeedCallback? = null private var timer: Timer? = null private var timerTask: TimerTask? = null private var lastTotalReceiveBytes: Long = 0 private var lastTotalTransferBytes: Long = 0 /** * 根據應用uid獲取設備啟動以來,該應用接收到的總字節數 * * @param uid 應用的uid */ fun getTotalReceiveBytes(): Long { var receiveBytes: Long = TrafficStats.UNSUPPORTED.toLong() ExampleApplication.exampleContext?.run { receiveBytes = TrafficStats.getUidRxBytes(applicationInfo.uid) } // 當獲取不到時,會返回TrafficStats.UNSUPPORTED return if (receiveBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else receiveBytes / 1024 } /** * 根據應用uid獲取設備啟動以來,該應用傳輸的總字節數 * * @param uid 應用的uid */ fun getTotalTransferBytes(): Long { var transferBytes: Long = TrafficStats.UNSUPPORTED.toLong() ExampleApplication.exampleContext?.run { transferBytes = TrafficStats.getUidTxBytes(applicationInfo.uid) } // 當獲取不到時,會返回TrafficStats.UNSUPPORTED return if (transferBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else transferBytes / 1024 } // 通過Timer每隔1秒計算網速 private fun calculateNetSpeed() { ExampleApplication.exampleContext?.run { val nowTotalReceiveBytes = getTotalReceiveBytes() val nowTotalTransferBytes = getTotalTransferBytes() val downloadSpeed = nowTotalReceiveBytes - lastTotalReceiveBytes val uploadSpeed = nowTotalTransferBytes - lastTotalTransferBytes lastTotalReceiveBytes = nowTotalReceiveBytes lastTotalTransferBytes = nowTotalTransferBytes netSpeedCallback?.onNetSpeedChange("$downloadSpeed kb/s", "$uploadSpeed kb/s") } } fun startMeasuringNetSpeed() { if (timer == null && timerTask == null) { timer = Timer() timerTask = object : TimerTask() { override fun run() { calculateNetSpeed() } } timer?.run { timerTask?.let { schedule(it, 0L, 1000L) } } } } fun stopMeasuringNetSpeed() { timerTask?.cancel() timerTask = null timer?.cancel() timer = null } interface NetSpeedCallback { fun onNetSpeedChange(downloadSpeed: String, uploadSpeed: String) } } // 示例類 class TrafficStatsActivity : BaseGestureDetectorActivity() { private lateinit var binding: LayoutTrafficStatsActivityBinding @SuppressLint("SetTextI18n") override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) binding = DataBindingUtil.setContentView(this, R.layout.layout_traffic_stats_activity) binding.includeTitle.tvTitle.text = "TrafficStatsExample" NetSpeedUtils.netSpeedCallback = object : NetSpeedUtils.NetSpeedCallback { override fun onNetSpeedChange(downloadSpeed: String, uploadSpeed: String) { binding.tvNetSpeed.run { post { text = "downloadSpeed:$downloadSpeed , uploadSpeed:$uploadSpeed" } } } } binding.btnStartMeasureNetSpeed.setOnClickListener { NetSpeedUtils.startMeasuringNetSpeed() } binding.btnStopMeasureNetSpeed.setOnClickListener { NetSpeedUtils.stopMeasuringNetSpeed() } initWebViewSetting(binding.webView) binding.webView.loadUrl("https://go.minigame.vip/") } @SuppressLint("JavascriptInterface", "SetJavaScriptEnabled") private fun initWebViewSetting(webView: WebView?) { webView?.run { settings.cacheMode = WebSettings.LOAD_DEFAULT settings.domStorageEnabled = true settings.allowContentAccess = true settings.allowFileAccess = true settings.useWideViewPort = true settings.loadWithOverviewMode = true settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW settings.javaScriptEnabled = true settings.javaScriptCanOpenWindowsAutomatically = true settings.setSupportMultipleWindows(true) } } override fun onDestroy() { super.onDestroy() binding.webView.clearHistory() binding.webView.loadDataWithBaseURL(null, "", "text/html", "utf-8", null) binding.root.run { if (this is ViewGroup) { this.removeView(binding.webView) } } binding.webView.destroy() } }
效果如圖:
以上就是Android 獲取實時網速實現詳解的詳細內容,更多關於Android 獲取實時網速的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- Java 實現訂單未支付超時自動取消功能(京東商城為例)
- 詳解Android內存泄露及優化方案
- Java中的定時器Timer詳解
- Android webview加載H5方法詳細介紹
- Java任務定時執行器案例的實現