On Android 4.0 onwards we have data usage control options in the phone. Please check the attached screen shot for further understanding.
http://developer.android.com/about/versions/android-4.0-highlights.html
Now I have some requirement to check these things (All Application's Data usage in specific time period/specific days) from my application. How can I achieve this? I am also using the below class for Network Usage details.
http://developer.oesf.biz/em/developer/reference/eggplant/android/net/NetworkStatsHistory.html
Please check the below link images. I need to develop the same kind of application.
http://developer.android.com/sdk/images/4.0/usage-all-lg.png
http://developer.android.com/sdk/images/4.0/usage-maps-lg.png
Thanks for sharing your code, but I need to know data used by each application instead of all applications. So far I observed in the links no one is talking about data usage of individual applications. I already know how to show installed applications in the device. Now I would like to know what's the data used by each and every application.
I am using the below code for list of installed applications in the device.
private ArrayList<PInfo> getInstalledApps(boolean getSysPackages) {
ArrayList<PInfo> res = new ArrayList<PInfo>();
List<PackageInfo> packs = getPackageManager().getInstalledPackages(0);
for (int i=0; i<packs.size(); i++) {
PackageInfo p = packs.get(i);
if ((!getSysPackages) && (p.versionName == null)) {
continue ;
}
PInfo newInfo = new PInfo();
newInfo.setAppname(p.applicationInfo.loadLabel(getPackageManager()).toString());
newInfo.setPname(p.packageName);
newInfo.setVersionName(p.versionName);
newInfo.setVersionCode(p.versionCode);
newInfo.setIcon(p.applicationInfo.loadIcon(getPackageManager()));
res.add(newInfo);
}
return res;
}
How do I know what's the data used by each application?
Actually, I need a solution which gives data usage of applications in a given time period, i.e. in between two days.
First, get a list of all running apps' process info:
List<RunningAppProcessInfo>
Then get the UID of every app and get then send and receive traffic of the app:
// Get running processes
ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
List<RunningAppProcessInfo> runningApps = manager.getRunningAppProcesses();
for (RunningAppProcessInfo runningApp : runningApps) {
// Get UID of the selected process
int uid = ((RunningAppProcessInfo)getListAdapter().getItem(position)).uid;
// Get traffic data
long received = TrafficStats.getUidRxBytes(uid);
long send = TrafficStats.getUidTxBytes(uid);
Log.v("" + uid , "Send :" + send + ", Received :" + received);
}
There are some more options to get network usage :
[NetworkStatsManager] provides network traffic statistics. These statistics include bytes transmitted and received and network packets transmitted and received, over all interfaces, over the mobile interface, and on a per-UID basis.
So to use NetworkStatsManager :
Declare required permissions in AndroidManifest file :
<uses-permission android:name="android.permission.READ_PHONE_STATE" / >
<uses-permission android:name="android.permission.PACKAGE_USAGE_STATS"
tools:ignore="ProtectedPermissions" / >
Since “android.permission.PACKAGE_USAGE_STATS” is a system level permission we will need to handle the request in a different manner. In order to check, whether the permission has been granted, check:
AppOpsManager appOps = (AppOpsManager) getSystemService(Context.APP_OPS_SERVICE);
int mode = appOps.checkOpNoThrow(AppOpsManager.OPSTR_GET_USAGE_STATS,
android.os.Process.myUid(), getPackageName());
if (mode == AppOpsManager.MODE_ALLOWED) {
return true;
}
This permission can be granted from the Settings -> Security -> Apps with usage access screen. To ask for this permission, simply start an activity with Settings.ACTION_USAGE_ACCESS_SETTINGS Intent to help the user to get there:
startActivity(new Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS));
Once everything has been set up you can get an instance of NetworkStatsManager which we will need to fetch network usage data:
NetworkStatsManager networkStatsManager = (NetworkStatsManager) context.getSystemService(Context.NETWORK_STATS_SERVICE);
Whatever query you will perform, you will get as a result a NetworkStats.Bucket or a NetworkStats (which is basically a container for multiple buckets with methods hasNextBucket() and getNextBucket() to access the real data (also remember to use close() before the object is out of scope).
In every query you will have to specify the network type (ConnectivityManager.TYPE_WIFI or ConnectivityManager.TYPE_MOBILE).
Subscriber Id required to make query and it remains same unless the user switches SIM card or carrier. To get that
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); String subscriberId = manager.getSubscriberId();
PackageManager packageManager = context.getPackageManager(); ApplicationInfo info = packageManager.getApplicationInfo("com.example.app", 0); int uid = info.uid;
UIDs used for the network usage caused by :
- Unistalled apps : UID_REMOVED
- Tethering : UID_TETHERING
- Android OS : SYSTEM_UID
- To get stats for all apps : UID_ALL
Some example queries:
To get all Rx and Tx bytes of Mobile :
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis());
bucket.getRxBytes();
bucket.getTxBytes();
To get all Rx and Tx bytes of Wifi :
NetworkStats.Bucket bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, ””, 0, System.currentTimeMillis());
bucket.getRxBytes();
bucket.getTxBytes();
To get all Rx and Tx bytes of Mobile for package :
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, getSubscriberId(context, ConnectivityManager.TYPE_MOBILE), 0, System.currentTimeMillis(),packageUid);
long rxBytes = 0L;
long txBytes = 0L;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
rxBytes += bucket.getRxBytes();
txBytes += bucket.getTxBytes();
}
networkStats.close();
To get all Rx and Tx bytes of Wifi for package :
NetworkStats.Bucket bucket = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_WIFI, “”, 0, System.currentTimeMillis(),packageUid);
long rxBytes = 0L;
long txBytes = 0L;
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
while (networkStats.hasNextBucket()) {
networkStats.getNextBucket(bucket);
rxBytes += bucket.getRxBytes();
txBytes += bucket.getTxBytes();
}
networkStats.close();
Note :
- Those queries should never be performed on the main thread or they will cause your app to drop frame.
- NetworkStatsManager.query* throws RemoteException
- Roaming and tag were added in API level 24 (Android 7.0 Nougat) so if you’re targeting Marshmallow (API level 23) you won’t be able to use those.
- Since API level 24 (Android 7.0 Nougat) you can use NetworkStatsManager without the PACKAGE_USAGE_STATS permission if you only want to get your app data. You’d still need it if your goal is to access other apps’ stats.
2. TrafficStats : It also provides required info but there are some drawbacks which makes it unreliable at least :
Some example methods of TrafficStats:
- To get Total Rx bytes - TrafficStats.getTotalRxBytes();
- To get Total Tx bytes - TrafficStats.getTotalTxBytes();
- To get all Mobile Rx bytes - TrafficStats.getMobileRxBytes();
- To get all Mobile Tx bytes - TrafficStats.getMobileTxBytes();
- To get all Wifi Rx bytes - TrafficStats.getTotalRxBytes() - TrafficStats.getMobileRxBytes();
- To get all Wifi Tx bytes - TrafficStats.getTotalTxBytes() - TrafficStats.getMobileTxBytes();
- To get Package Rx Bytes : - TrafficStats.getUidRxBytes(packageUid);
- To get Package Tx Bytes : - TrafficStats.getUidTxBytes(packageUid);