Rajiv Kanchan
Rajiv Kanchan

Reputation: 23

How to fetch data usage report for ALL UID's using the new NetworkStatsManager class

I am building a data manager app, which requires per-app data usage report over mobile and wifi interfaces.

While trying to use the method "NetworkStatsManager.querySummary", I only get usage reports for some of the UID's, but not all. While the API documentation for the method does say

Result filtered to include only uids belonging to calling user

Its not clear to me as to which UID's belong to the calling user and which do not. Please help me understand the difference and how I can obtain data usage reports for all UID's using this new "NetworkStatsManager" class.

Upvotes: 2

Views: 2917

Answers (2)

rajeesh
rajeesh

Reputation: 941

Question is like asking data usages for each app. Not the whole device usage. So with respect to each uid we need corresponding app's data usage. The following are used for getting the data usage for a particular uid. This also not working with all devices. I checked and later understood that in some devices this is not available even after we gave app usage tracking permission. This is a system level permission though.

long dataUsageWithRespectToUid = getPackageRxBytesMobile(this)+ getPackageTxBytesMobile(this) + getPackageRxBytesWifi() +getPackageTxBytesWifi();

public long getPackageRxBytesMobile(Context context) {
    NetworkStats networkStats = null;
    try {
        networkStats = networkStatsManager.queryDetailsForUid(
                ConnectivityManager.TYPE_MOBILE,
                getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
                0,
                System.currentTimeMillis(),
                packageUid);
    } catch (RemoteException e) {
        return -1;
    }
    NetworkStats.Bucket bucket = new NetworkStats.Bucket();
    networkStats.getNextBucket(bucket);
    networkStats.getNextBucket(bucket);
    return bucket.getRxBytes();
}

public long getPackageTxBytesMobile(Context context) {
    NetworkStats networkStats = null;
    try {
        networkStats = networkStatsManager.queryDetailsForUid(
                ConnectivityManager.TYPE_MOBILE,
                getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
                0,
                System.currentTimeMillis(),
                packageUid);
    } catch (RemoteException e) {
        return -1;
    }
    NetworkStats.Bucket bucket = new NetworkStats.Bucket();
    networkStats.getNextBucket(bucket);
    return bucket.getTxBytes();
}

public long getPackageRxBytesWifi() {
    NetworkStats networkStats = null;
    try {
        networkStats = networkStatsManager.queryDetailsForUid(
                ConnectivityManager.TYPE_WIFI,
                "",
                0,
                System.currentTimeMillis(),
                packageUid);
    } catch (RemoteException e) {
        return -1;
    }
    NetworkStats.Bucket bucket = new NetworkStats.Bucket();
    networkStats.getNextBucket(bucket);
    return bucket.getRxBytes();
}

public long getPackageTxBytesWifi() {
    NetworkStats networkStats = null;
    try {
        networkStats = networkStatsManager.queryDetailsForUid(
                ConnectivityManager.TYPE_WIFI,
                "",
                0,
                System.currentTimeMillis(),
                packageUid);
    } catch (RemoteException e) {
        return -1;
    }
    NetworkStats.Bucket bucket = new NetworkStats.Bucket();
    networkStats.getNextBucket(bucket);
    return bucket.getTxBytes();
}

Upvotes: 1

R. Zagórski
R. Zagórski

Reputation: 20268

It is possible to get the summary for the device. Just use another method: android.app.usage.NetworkStatsManager#querySummaryForDevice. Here is the sample usage:

WiFi:

NetworkStats.Bucket bucket;
try {
    bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI,
            "",
            0,
            System.currentTimeMillis());
} catch (RemoteException e) {
    return -1;
}

Mobile:

public long getAllTxBytesMobile(Context context) {
    NetworkStats.Bucket bucket;
    try {
        bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE,
                getSubscriberId(context, ConnectivityManager.TYPE_MOBILE),
                0,
                System.currentTimeMillis());
    } catch (RemoteException e) {
        return -1;
    }
    return bucket.getTxBytes();
}

private String getSubscriberId(Context context, int networkType) {
    if (ConnectivityManager.TYPE_MOBILE == networkType) {
        TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        return tm.getSubscriberId();
    }
    return "";
}

to get Rx or Tx bytes, just call:

bucket.getRxBytes();
bucket.getTxBytes();

Made a sample Github repo demonstrating the usage.

Upvotes: 1

Related Questions