【问题标题】:Android mobile usage history NetworkStatsManagerAndroid 手机使用历史 NetworkStatsManager
【发布时间】:2016-05-19 10:23:21
【问题描述】:

我正在为 Android 6.0 制作应用程序,我想使用新类 NetworkStatsManager 来获取移动数据使用情况。

我在清单中添加了我需要的所有权限并需要权限运行时。

当我调用方法时:

bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", fromDate.getTime(), toDate.getTime());

返回正确的 WIFI 使用值。

但如果我用 TYPE_MOBILE 替换 TYPE_WIFI,结果总是 0。

    NetworkStats.Bucket bucket = null;
    try {
        bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, "", fromDate.getTime(), toDate.getTime());

        if(bucket == null){
            Log.i("Info", "Error");
        }else{
            Log.i("Info", "Total: " + (bucket.getRxBytes() + bucket.getTxBytes()));
        }

    } catch (RemoteException e) {
        e.printStackTrace();
    }

【问题讨论】:

    标签: java android android-trafficstats networkstatsmanager


    【解决方案1】:

    我找到了使用隐藏 API (android statistic 3g traffic for each APP, how?) 解决此问题的方法,并且当尝试使用 TYPE_MOBILE 检索移动数据使用信息时,需要通知 SubscriberID,这与我尝试获取信息 TYPE WIFI 时不同。

    试试这个代码

        TelephonyManager  tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        String subscriberID = tm.getSubscriberId();
    
        NetworkStats networkStatsByApp = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, subscriberID, start, end, uid);
    

    因此,当您使用 TYPE_MOBILE 时,您必须使用有效的订阅者 ID。

    【讨论】:

    • 请不要只发布代码作为答案...至少解释一下您的答案/代码。
    • 对不起,我添加了有关解决方案的更多信息。
    • 很酷的东西@EMIDIOOLIVEIRA :)
    • 有没有机会将移动统计信息拆分到家庭和漫游网络?
    • 使用此代码时我仍然为零 public long getAllRxBytesMobile1(Context context) { NetworkStats.Bucket bucket;尝试 { bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis()); } catch (RemoteException e) { return -1; } 返回 bucket.getRxBytes(); }
    【解决方案2】:

    作为已接受答案的后续,我还想指出,在以下代码中,

    TelephonyManager  tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
    String subscriberID = tm.getSubscriberId(); //subscriberID is usually the IMSI number (for GSM phones)
    

    TelephonyManager tm 包含有关用于拨打电话的默认电话服务(SIM 卡)的信息。因此,如果您使用带有双 SIM 卡的手机,并且 SIM 1 用于通话,而 SIM 2 用于数据,那么TelephonyManager tm 将保存有关 SIM 1 和您的用例中的信息,您在哪里使用 @ 987654324@ 用于获取数据使用统计信息,SIM 1 信息将没有用,因为它不用于消费数据。因此,您需要以某种方式获取 SIM 2 的 TelephonyManager,以便您可以在 networkStatsManager.querySummaryForDevice() 中使用 SIM 2 的正确订户 ID 来获取移动数据使用统计信息。那么,你如何做到这一点?

    我想出的一种方法是这样的:

    public void subscriberIdsOfDualSim(){
        SubscriptionManager subscriptionManager = SubscriptionManager.from(this);
        //we'll now get a List of information of active SIM cards
        //for example, if there are 2 SIM slots and both the slots have 1 SIM card each, then the List size will be 2
        List<SubscriptionInfo> activeSubscriptionInfoList = subscriptionManager.getActiveSubscriptionInfoList();
        TelephonyManager manager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
        for (SubscriptionInfo subscriptionInfo : activeSubscriptionInfoList) {
            //loop through the SIM card info
            //if there are 2 SIM cards, then we'll try to print the subscriberId of each of the SIM cards
            if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) {
                //the following createForSubscriptionId() is available from API 24 :(
                TelephonyManager manager1=manager.createForSubscriptionId(subscriptionInfo.getSubscriptionId());
                String operatorName=manager1.getNetworkOperatorName();
                String subscriberId=manager1.getSubscriberId(); //use this subscriberId to do NetworkStatsManager stuff
                System.out.println("subscriberIdsOfDualSim: Carrier Name: "+operatorName+", subscriber id: "+subscriberId);
            }
        }
    }
    

    请注意,我使用了createForSubscriptionId() 方法。此方法的一个限制是它只能从 API 24 (Android 7.0 Nougat) 使用。

    因此,如果您同时使用 SIM 1 和 SIM 2 进行数据消费,那么您可以通过将每张 SIM 卡的 subscriberId 提供给 networkStatsManager.querySummaryForDevice() 来获取每张 SIM 卡的数据使用信息。但是,如果你想获得正确的移动数据消耗(包括 SIM 1 和 SIM 2)并且你想支持牛轧糖以下的手机,那么 TrafficStats 类中的旧 getMobileRxBytes()getMobileTxBytes() 方法是你可能的必须使用。

    【讨论】:

    • 另一个限制是,从 API 28(应用程序定位它)开始,getSubscriberId() 返回 null,如果定位 API 29,则返回异常!
    【解决方案3】:

    对已接受的答案和@Nandan 的另一个跟进,可以使用以下代码获取两张 SIM 卡的订户 ID

    SubscriptionManager subman = (SubscriptionManager)getSystemService(TELEPHONY_SUBSCRIPTION_SERVICE);
    TelephonyManager telman = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
    
    List<SubscriptionInfo> li = subman.getActiveSubscriptionInfoList();
    
    for(SubscriptionInfo info : li){
        int sid = info.getSubscriptionId(); //not the id we want
    
        try{
            Class c = Class.forName("android.telephony.TelephonyManager");
            Method m = c.getMethod("getSubscriberId", new Class[]{int.class});
            Object o = m.invoke(telman, new Object[]{sid});
    
            String subid = (String)o;  //id we want
            Log.i("SubscriptionId", subid);
        }
        catch(Exception e){}
    
    }
    

    感谢回答链接https://stackoverflow.com/a/38071705/9038181

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-26
      • 2012-09-10
      • 1970-01-01
      • 2021-07-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多