Android 获取实时网速实现详解

目录
  • 正文
  • TrafficStats简介
  • 实现获取网速
    • 实时网速

正文

最近接到个需求,需要计算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类的接口获取的网速是从开机时就开始计算的,因此,要计算一段时间内的流量需要在开始时获取一次流量数据,结束时获取一次流量数据,相减得出一段时间的实际流量。

实时网速

本文用getUidTxBytesgetUidRxBytes来演示,其他方法也是类似的,如下:

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 获取实时网速的资料请关注我们其它相关文章!

(0)

相关推荐

  • Android 使用Toolbar实现应用栏实例详解

    目录 使用Toolbar实现应用栏 应用栏功能扩展 返回 菜单 使用Toolbar实现应用栏 App中应用栏是十分常见的,通常应用栏会显示当前页面的标题,还有一些操作按钮,例如返回.搜索.扫码等.本文介绍如何通过Toolbar实现应用栏. 使用Toolbar来实现应用栏,需要在AndroidManifest中设置NoActionBar的主题,并且Activity需要继承AppCompatActivity. <?xml version="1.0" encoding="ut

  • Android 搜索框架使用详解

    目录 搜索框架简介 使用搜索框架实现搜索功能 可搜索配置 搜索页面 使用SearchView 使用搜索弹窗 搜索弹窗对Activity生命周期的影响 附加额外的参数 语音搜索 搜索记录 创建SearchRecentSuggestionsProvider 修改可搜索配置 在搜索页面中保存查询 清除搜索历史 示例 搜索框架简介 App中搜索功能是必不可少的,搜索功能可以帮助用户快速获取想要的信息.对此,Android提供了一个搜索框架,本文介绍如何通过搜索框架实现搜索功能. Android 搜索框架

  • Android开发中Signal背后的bug与解决

    目录 背景 出现SIGABRT的原因 SIGSEGV被捕获但是调用jni无法进行 小结 背景 熟悉我的老朋友可能都知道,之前为了应对crash与anr,开源过一个“民间偏方”的库Signal,用于解决在发生crash或者anr时进行应用的重启,从而最大程度减少其坏影响. 在维护的过程中,发生过这样一件趣事,就是有位朋友发现在遇到信号为SIGSEGV时,再调用信号处理函数的时候 void SigFunc(int sig_num, siginfo *info, void *ptr) { // 这里判

  • Google 开发Android MVP架构Demo深入解析

    目录 1.什么是MVP? 2.Google官方的MVP 3.V1.1 My MVP V1 4.V1.2 My MVP V2 1.什么是MVP? Google在2016年推出了官方的Android MVP架构Demo,本文主要分析一下官方的MVP Demo,并且借由自己的一些经验,提出一些学习过程中,遇到的问题和自己的改进.封装措施. MVP架构已经推出很多年了,现在已经非常普及了,我在这里就不过多介绍,简单的说,它分为以下三个层次: Model:数据模型层,主要用来数据处理,获取数据: View

  • Android ApplicationContext接口深入分析

    目录 需求 实现方法 代码 调用 Application getApplicationContext() 参考 需求 Android(Kotlin)获取应用全局上下文 ApplicationContext. 希望可以在应用内任意位置获取上下文,而不是仅在 Activity 或 Service 里才能获取. ApplicationContext 是和应用全局相关的. 实现方法 自定义 MyApplication,保存自身的 Application 实例. MyApplication 配置到 And

  • Android 控件自动贴边实现实例详解

    目录 正文 判断交互 隐藏与显示 示例 正文 最近接到个需求,需要在用户与App交互时,把SDK中之前实现过的悬浮控件贴边隐藏,结束交互后延迟一段时间再自动显示.本篇文章介绍一下实现的思路. 判断交互 用户与App交互.结束交互可以通过监听触摸事件来实现.建议使用的Activity的dispatchTouchEvent,Activity下的所有触摸事件分发时都会回调此方法,代码如下: class AutoEdgeHideActivity : BaseGestureDetectorActivity

  • Android Jetpack导航组件Navigation创建使用详解

    目录 引言 依赖项 创建导航图 导航宿主 导航到目的地 传递参数 NavigationUI 多模块导航 引言 导航是指支持用户导航.进入和退出应用中不同内容片段的交互.Android Jetpack 的导航组件可实现导航,无论是简单的按钮点击,还是应用栏和抽屉式导航栏等更为复杂的模式,该组件均可应对. 依赖项 def nav_version = "2.5.2" implementation "androidx.navigation:navigation-fragment-kt

  • Android O对后台Service限制详解

    目录 Service问题 什么是前台应用 前台Service和后台Service 后台Service限制 解决后台Service限制 Service问题 Service没有界面,运行于后台,它会消耗设备资源,并且可能会导致不好的用户体验,例如资源占用过多,导致设备运行不流畅.为了缓解这个问题,Android O版本(Android 8.0, API 26)对后台Service强加了一些限制.注意,只是对后台Service加了限制,前台Service不受影响. 什么是前台应用 在解释后台Servi

  • Android 获取实时网速实现详解

    目录 正文 TrafficStats简介 实现获取网速 实时网速 正文 最近接到个需求,需要计算WebView加载网页时的网速.查询了一下,Android没有提供直接获取网速的Api,但是提供了获取流量的类TrafficStats.本文介绍如何使用Trafficstats来实现获取网速功能. TrafficStats简介 TrafficStats提供了一些获取设备从本次开机到目前为止传输/接收的流量的接口,如下: 方法 参数 说明 getTotalTxBytes - 获取设备本次开机到目前为止,

  • Android 获取手机联系人实例代码详解

    我的风格,废话不多说了,直接给大家贴代码了. 具体代码如下所示: package com.org.demo.demo; import com.org.wangfeng.R; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Butt

  • Android 实现获取手机里面的所有图片详解及实例

    Android 实现获取手机里面的所有图片详解及实例 实现代码: public class MainActivity extends Activity { //查看图片按钮 private Button look; private Button add; //显示图片名称的list ListView show_list; ArrayList names = null; ArrayList descs= null; ArrayList fileNames = null; @Override pro

  • Java 用Prometheus搭建实时监控系统过程详解

    上帝之火 本系列讲述的是开源实时监控告警解决方案Prometheus,这个单词很牛逼.每次我都能联想到带来上帝之火的希腊之神,普罗米修斯.而这个开源的logo也是火,个人挺喜欢这个logo的设计. 本系列着重介绍Prometheus以及如何用它和其周边的生态来搭建一套属于自己的实时监控告警平台. 本系列受众对象为初次接触Prometheus的用户,大神勿喷,偏重于操作和实战,但是重要的概念也会精炼出提及下.系列主要分为以下几块 Prometheus各个概念介绍和搭建,如何抓取数据(本次分享内容)

  • Android mvvm之LiveData原理案例详解

    1. 生命周期感知 1.1 生命周期感知组件 我们知道,Controller(Activity or Fragment) 都是有生命周期的,但是传统的 Controller 实现方式只负责 Controller 本身的生命周期管理,而与业务层的数据之间并没有实现良好解耦的生命周期事件交换.所以业务层都需要自己主动去感知 Controller 生命周期的变化,并在 Controller 的生存期处理数据的保活,而在消亡时刻解除与 Controller 之间的关系,这种处理方式随着业务规模的扩大往往

  • Android性能优化大图治理示例详解

    目录 引言 1 自定义大图View 1.1 准备工作 1.2 图片宽高适配 1.3 BitmapRegionDecoder 2 大图View的手势事件处理 2.1 GestureDetector 2.2 双击放大效果处理 2.3 手指放大效果处理 引言 在实际的Android项目开发中,图片是必不可少的元素,几乎所有的界面都是由图片构成的:像列表页.查看大图页等,都是需要展示图片,而且这两者是有共同点的,列表展示的Item数量多,如果全部加载进来势必会造成OOM,因此列表页通常采用分页加载,加上

  • android 微信抢红包工具AccessibilityService实现详解

    目录 1.目标 2.实现流程 1.流程分析(这里只分析在桌面的情况) 2.实现步骤 1.收到通知 以及 点击通知栏 2.点击红包 3.点击开红包 4.退出红包详情页 3.遇到问题 4.完整代码 MyNotificationListenerService MyAccessibilityService 5.总结 你有因为手速不够快抢不到红包而沮丧? 你有因为错过红包而懊恼吗? 没错,它来了... 1.目标 使用AccessibilityService的方式,实现微信自动抢红包(吐槽一下,网上找了许多

  • Android USB转串口通信开发实例详解

     Android USB转串口通信开发实例详解 好久没有写文章了,年前公司新开了一个项目,是和usb转串口通信相关的,需求是用安卓平板通过usb转接后与好几个外设进行通信,一直忙到最近,才慢慢闲下来,趁着这个周末不忙,记录下usb转串口通信开发的基本流程. 我们开发使用的是usb主机模式,即:安卓平板作为主机,usb外设作为从机进行数据通信.整个开发流程可以总结为以下几点: 1.发现设备 UsbManager usbManager = (UsbManager) context.getSystem

  • Android 打包三种方式实例详解

     Android 打包三种方式实例详解 前言: 现在市场上很多app应用存在于各个不同的渠道,大大小小几百个,当我们想要在发布应用之后统计各个渠道的用户下载量,我们就要进行多渠道打包. 01.应用的打包签名什么是打包? 打包就是根据签名和其他标识生成安装包. 签名是什么? 1.在android应用文件(apk)中保存的一个特别字符串 2.用来标识不同的应用开发者:开发者A,开发者B 3.一个应用开发者开发的多款应用使用同一个签名 就好比是一个人写文章,签名就相当于作者的署名. 如果两个应用都是一

  • Android AOP之注解处理解释器详解(二)

    Android APO 注解处理解释器 相关文章: Android AOP注解Annotation详解(一) Android AOP之注解处理解释器详解(二) Android AOP 注解详解及简单使用实例(三) 一.提取Annotation信息 当开发者使用了Annotation修饰了类.方法.Field等成员之后,这些Annotation不会自己生效,必须由开发者提供相应的代码来提取并处理Annotation信息.这些处理提取和处理Annotation的代码统称为APT(Annotation

随机推荐