История использования мобильных устройств Android NetworkStatsManager
Я делаю приложение для Android 6.0 и хочу использовать новый класс NetworkStatsManager для получения мобильных данных.
Я добавил все необходимые разрешения в манифест и требует разрешения времени выполнения.
Когда я вызываю метод:
bucket = networkStatsManager.querySummaryForDevice(ConnectivityManager.TYPE_WIFI, "", fromDate.getTime(), toDate.getTime());
верните правильное значение для использования WIFI.
Но если я заменю TYPE_WIFI на TYPE_MOBILE, результат всегда будет 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();
}
1 ответ
Я нашел решение этой проблемы с помощью скрытых API-интерфейсов ( статистика 3g android для каждого приложения, как?), И при попытке получить информацию об использовании мобильных данных с помощью 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, вам необходимо использовать действительный идентификатор подписчика.
В качестве продолжения принятого ответа я также хотел бы отметить, что в следующем коде
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 и в вашем случае использования, где вы используете NetworkStatsManager
для получения статистики использования данных информация с SIM 1 будет бесполезной, поскольку она не используется для использования данных. Итак, вам как-то нужно получить TelephonyManager
для SIM 2, чтобы вы могли использовать правильный идентификатор абонента SIM 2 в networkStatsManager.querySummaryForDevice()
чтобы получить статистику использования мобильных данных. Итак, как ты это делаешь?
Один из способов, который я понял, таков:
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 включительно) и хотите поддерживать телефоны ниже нуга, то старый добрый getMobileRxBytes()
а также getMobileTxBytes()
методы в TrafficStats
класс - это то, что вам, возможно, придется использовать.
Еще одно дополнение к принятому ответу и @Nandan, можно получить идентификаторы подписчиков обеих SIM-карт, используя приведенный ниже код
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){}
}
Кредит, чтобы ответить на ссылку /questions/20210995/subscriptionmanager-dlya-chteniya-imsi-dlya-ustrojstv-s-dvumya-sim-kartami-rabotayuschimi-na-android-51/20211000#20211000