Android?獲取實(shí)時(shí)網(wǎng)速實(shí)現(xiàn)詳解
正文
最近接到個(gè)需求,需要計(jì)算WebView
加載網(wǎng)頁(yè)時(shí)的網(wǎng)速。查詢(xún)了一下,Android沒(méi)有提供直接獲取網(wǎng)速的Api,但是提供了獲取流量的類(lèi)TrafficStats
。本文介紹如何使用Trafficstats
來(lái)實(shí)現(xiàn)獲取網(wǎng)速功能。
TrafficStats簡(jiǎn)介
TrafficStats
提供了一些獲取設(shè)備從本次開(kāi)機(jī)到目前為止傳輸/接收的流量的接口,如下:
方法 | 參數(shù) | 說(shuō)明 |
---|---|---|
getTotalTxBytes | - | 獲取設(shè)備本次開(kāi)機(jī)到目前為止,WI-FI、流量下傳輸?shù)淖止?jié)總數(shù)。 |
getTotalRxBytes | - | 獲取設(shè)備本次開(kāi)機(jī)到目前為止,WI-FI、流量下接收的字節(jié)總數(shù)。 |
getMobileTxBytes | - | 獲取設(shè)備本次開(kāi)機(jī)到目前為止,流量下傳輸?shù)淖止?jié)總數(shù)。 |
getMobileRxBytes | - | 獲取設(shè)備本次開(kāi)機(jī)到目前為止,流量下接收的字節(jié)總數(shù)。 |
getUidTxBytes | uid | 獲取應(yīng)用從本次開(kāi)機(jī)到目前為止,WI-FI、流量下傳輸?shù)淖止?jié)總數(shù)。 |
getUidRxBytes | uid | 獲取應(yīng)用從本次開(kāi)機(jī)到目前為止,WI-FI、流量下接收的字節(jié)總數(shù)。 |
上述接口可以滿(mǎn)足實(shí)現(xiàn)計(jì)算網(wǎng)速的需求,TrafficStats
類(lèi)其他接口可以查看官方文檔。
實(shí)現(xiàn)獲取網(wǎng)速
可以通過(guò)一段時(shí)間內(nèi)傳輸?shù)牧髁砍r(shí)間計(jì)算出上行網(wǎng)速,通過(guò)一段時(shí)間內(nèi)接收的流量除去時(shí)間計(jì)算出下行網(wǎng)速。
TrafficStats
類(lèi)的接口獲取的網(wǎng)速是從開(kāi)機(jī)時(shí)就開(kāi)始計(jì)算的,因此,要計(jì)算一段時(shí)間內(nèi)的流量需要在開(kāi)始時(shí)獲取一次流量數(shù)據(jù),結(jié)束時(shí)獲取一次流量數(shù)據(jù),相減得出一段時(shí)間的實(shí)際流量。
實(shí)時(shí)網(wǎng)速
本文用getUidTxBytes
和getUidRxBytes
來(lái)演示,其他方法也是類(lèi)似的,如下:
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 /** * 根據(jù)應(yīng)用uid獲取設(shè)備啟動(dòng)以來(lái),該應(yīng)用接收到的總字節(jié)數(shù) * * @param uid 應(yīng)用的uid */ fun getTotalReceiveBytes(): Long { var receiveBytes: Long = TrafficStats.UNSUPPORTED.toLong() ExampleApplication.exampleContext?.run { receiveBytes = TrafficStats.getUidRxBytes(applicationInfo.uid) } // 當(dāng)獲取不到時(shí),會(huì)返回TrafficStats.UNSUPPORTED return if (receiveBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else receiveBytes / 1024 } /** * 根據(jù)應(yīng)用uid獲取設(shè)備啟動(dòng)以來(lái),該應(yīng)用傳輸?shù)目傋止?jié)數(shù) * * @param uid 應(yīng)用的uid */ fun getTotalTransferBytes(): Long { var transferBytes: Long = TrafficStats.UNSUPPORTED.toLong() ExampleApplication.exampleContext?.run { transferBytes = TrafficStats.getUidTxBytes(applicationInfo.uid) } // 當(dāng)獲取不到時(shí),會(huì)返回TrafficStats.UNSUPPORTED return if (transferBytes == TrafficStats.UNSUPPORTED.toLong()) 0 else transferBytes / 1024 } // 通過(guò)Timer每隔1秒計(jì)算網(wǎng)速 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) } } // 示例類(lèi) 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 獲取實(shí)時(shí)網(wǎng)速實(shí)現(xiàn)詳解的詳細(xì)內(nèi)容,更多關(guān)于A(yíng)ndroid 獲取實(shí)時(shí)網(wǎng)速的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android開(kāi)發(fā)中遇到端口號(hào)占用問(wèn)題解決方法
這篇文章主要介紹了Android開(kāi)發(fā)中遇到端口號(hào)占用問(wèn)題解決方法,本文給出了一個(gè)簡(jiǎn)潔實(shí)用的方法來(lái)解決這個(gè)煩人的問(wèn)題,需要的朋友可以參考下2015-06-06詳解Android中實(shí)現(xiàn)Redux方法
本篇文章給大家通過(guò)代碼實(shí)例教學(xué)Android中實(shí)現(xiàn)Redux的方法,有需要的朋友跟著參考下吧。2018-01-01解決Android Studio 3.0 butterknife:7.0.1配置的問(wèn)題
下面小編就為大家分享一篇解決Android Studio 3.0 butterknife:7.0.1配置的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)可收縮和擴(kuò)展的TextView,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-03-03Android 中自定義Dialog樣式的Activity點(diǎn)擊空白處隱藏軟鍵盤(pán)功能(dialog不消失)
項(xiàng)目中需要開(kāi)發(fā)帶有EditText的Dialog顯示,要求在編輯完EditText時(shí),點(diǎn)擊Dilog的空白處隱藏軟鍵盤(pán)。但是Dialog不會(huì)消失。下面通過(guò)實(shí)例代碼給大家分享實(shí)現(xiàn)方法,需要的的朋友參考下吧2017-04-04Android Studio Gradle依賴(lài)沖突解決方法
這篇文章主要給大家介紹了關(guān)于A(yíng)ndroid Studio Gradle依賴(lài)沖突解決的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Android Studio具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Android自定義View實(shí)現(xiàn)QQ運(yùn)動(dòng)積分轉(zhuǎn)盤(pán)抽獎(jiǎng)功能
這篇文章主要為大家詳細(xì)介紹了Android自定義View實(shí)現(xiàn)QQ運(yùn)動(dòng)積分轉(zhuǎn)盤(pán)抽獎(jiǎng)功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-10-10Flutter開(kāi)發(fā)之Widget自定義總結(jié)
這篇文章主要給大家介紹了關(guān)于Flutter開(kāi)發(fā)中Widget自定義的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Flutter具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04