Android 移动使用历史 NetworkStatsManager
Android mobile usage history NetworkStatsManager
我正在为 Android 6.0 制作一个应用程序,我想使用新的 class NetworkStatsManager 来获取移动数据使用情况。
我在清单中添加了我需要的所有权限并需要权限运行时。
当我调用方法时:
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", fromDate.getTime(), toDate.getTime());
return 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();
}
我找到了隐藏 API (android statistic 3g traffic for each APP, how?) 的此问题的解决方案,并且在尝试使用 TYPE_MOBILE 检索移动数据使用信息时,必须通知 SubscriberID,这与我尝试获取时不同信息类型 WIFI。
试试这个代码
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String subscriberID = tm.getSubscriberId();
NetworkStats networkStatsByApp = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, subscriberID, start, end, uid);
因此,当您使用 TYPE_MOBILE 时,您必须使用有效的 subscriberID。
作为已接受答案的后续,我还想指出,在以下代码中,
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String subscriberID = tm.getSubscriberId(); //subscriberID is usually the IMSI number (for GSM phones)
TelephonyManager tm
包含有关用于拨打电话的默认电话服务(SIM 卡)的信息。因此,如果您将 phone 与双 SIM 卡一起使用,并且 SIM 1 用于通话而 SIM 2 用于数据,那么 TelephonyManager tm
将保存有关 SIM 1 和您的用例的信息,在您使用 NetworkStatsManager
获取数据使用统计信息的地方,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 1 和 SIM 2)并且你想支持牛轧糖以下 phones,那么好的旧 getMobileRxBytes()
和 getMobileTxBytes()
方法in TrafficStats
class 是您可能需要使用的。
另一个跟进接受的答案和@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){}
}
感谢回答 link
我正在为 Android 6.0 制作一个应用程序,我想使用新的 class NetworkStatsManager 来获取移动数据使用情况。
我在清单中添加了我需要的所有权限并需要权限运行时。
当我调用方法时:
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", fromDate.getTime(), toDate.getTime());
return 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();
}
我找到了隐藏 API (android statistic 3g traffic for each APP, how?) 的此问题的解决方案,并且在尝试使用 TYPE_MOBILE 检索移动数据使用信息时,必须通知 SubscriberID,这与我尝试获取时不同信息类型 WIFI。
试试这个代码
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String subscriberID = tm.getSubscriberId();
NetworkStats networkStatsByApp = networkStatsManager.queryDetailsForUid(ConnectivityManager.TYPE_MOBILE, subscriberID, start, end, uid);
因此,当您使用 TYPE_MOBILE 时,您必须使用有效的 subscriberID。
作为已接受答案的后续,我还想指出,在以下代码中,
TelephonyManager tm = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
String subscriberID = tm.getSubscriberId(); //subscriberID is usually the IMSI number (for GSM phones)
TelephonyManager tm
包含有关用于拨打电话的默认电话服务(SIM 卡)的信息。因此,如果您将 phone 与双 SIM 卡一起使用,并且 SIM 1 用于通话而 SIM 2 用于数据,那么 TelephonyManager tm
将保存有关 SIM 1 和您的用例的信息,在您使用 NetworkStatsManager
获取数据使用统计信息的地方,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 1 和 SIM 2)并且你想支持牛轧糖以下 phones,那么好的旧 getMobileRxBytes()
和 getMobileTxBytes()
方法in TrafficStats
class 是您可能需要使用的。
另一个跟进接受的答案和@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){}
}
感谢回答 link