如何在Xamarin.Forms中从Android设置获取移动数据用量?
嘿,我来帮你搞定Android移动数据用量的获取问题!针对你用Xamarin开发的场景,这里有几个实用的方案,分情况给你拆解清楚:
方案1:用TrafficStats API做基础流量统计
这个是Android原生自带的轻量API,上手快,适合获取设备启动以来的累计流量,或者当前APP的流量使用情况。
第一步:添加权限
先在AndroidManifest.xml里加上必要的权限:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- 如果要获取其他APP的流量,Android 10+需要这个特殊权限 --> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" />
第二步:编写代码调用
直接在你的Xamarin代码里调用即可:
using Android.Net; using Android.OS; using Android.App; // 获取设备总移动数据接收量(字节) long totalReceivedBytes = TrafficStats.TotalRxBytes; // 获取设备总移动数据发送量(字节) long totalSentBytes = TrafficStats.TotalTxBytes; // 获取当前APP的移动数据用量(接收+发送) long appReceivedBytes = TrafficStats.GetUidRxBytes(Application.Context.ApplicationInfo.Uid); long appSentBytes = TrafficStats.GetUidTxBytes(Application.Context.ApplicationInfo.Uid); long appTotalBytes = appReceivedBytes + appSentBytes; // 转成更友好的MB单位 double totalMB = (totalReceivedBytes + totalSentBytes) / (1024.0 * 1024.0); double appMB = appTotalBytes / (1024.0 * 1024.0);
注意事项
- 这个API统计的是设备启动后的流量,不是运营商账单周期的累计数据;
- Android 10及以上,获取其他APP的流量会有严格限制,一般只推荐用来统计自己APP的流量。
方案2:用NetworkStatsManager API获取账单周期流量
如果你需要的是和运营商账单一致的周期流量数据,就得用这个API,它能拿到系统层面的流量统计,包括运营商定义的账单周期数据。
第一步:添加权限
需要的权限更多,同样在AndroidManifest.xml里配置:
<uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.PACKAGE_USAGE_STATS" tools:ignore="ProtectedPermissions" /> <uses-permission android:name="android.permission.READ_NETWORK_USAGE_HISTORY" />
第二步:编写核心代码
这个API从Android 6.0(API 23)开始支持,所以要做版本判断:
using Android.App; using Android.Content; using Android.Net; using Android.OS; using Android.Telephony; using System; public long GetCycleMobileDataUsage() { // 低于API23的设备,只能 fallback 到TrafficStats if (Build.VERSION.SdkInt < BuildVersionCodes.M) { return TrafficStats.TotalRxBytes + TrafficStats.TotalTxBytes; } // 获取系统服务实例 var networkStatsManager = (NetworkStatsManager)Application.Context.GetSystemService(Context.NetworkStatsService); var telephonyManager = (TelephonyManager)Application.Context.GetSystemService(Context.TelephonyService); string subscriberId = telephonyManager.SubscriberId; try { // 查询移动网络的流量汇总(从0时刻到现在,即累计所有流量) var statsBucket = networkStatsManager.QuerySummary( ConnectivityManager.TYPE_MOBILE, subscriberId, 0, DateTimeOffset.UtcNow.ToUnixTimeMilliseconds() ); long totalBytes = 0; while (statsBucket.MoveToNext()) { totalBytes += statsBucket.RxBytes + statsBucket.TxBytes; } return totalBytes; } catch (SecurityException ex) { // 权限不足,引导用户去设置开启权限 Console.WriteLine("权限缺失:" + ex.Message); RequestUsageAccess(); return 0; } } // 引导用户开启PACKAGE_USAGE_STATS权限 private void RequestUsageAccess() { Intent intent = new Intent(Android.Provider.Settings.ActionUsageAccessSettings); intent.AddFlags(ActivityFlags.NewTask); Application.Context.StartActivity(intent); }
注意事项
PACKAGE_USAGE_STATS是特殊权限,不能通过普通动态申请,必须引导用户到系统设置页面开启;- Android 11+对
READ_PHONE_STATE权限有额外限制,需要在代码中处理动态申请逻辑; - 不同运营商的账单周期不同,如果需要精准获取账单周期的起始时间,还需要额外处理(比如通过TelephonyManager获取运营商的账单信息)。
最后小提醒
- 如果只是统计自己APP的流量,方案1足够简单好用;
- 如果需要系统级或账单周期的流量数据,方案2是更合适的选择;
- 测试时尽量用真实设备,模拟器的流量统计可能不准确。
内容的提问来源于stack exchange,提问作者Karthick
相关产品推荐
相关产品推荐

