Trong ứng dụng của tôi, nhiều App Widgets có thể được đặt trên màn hình chính, với mỗi tiện ích tìm nạp dữ liệu từ xa theo định kỳ.Theo dõi việc sử dụng dữ liệu của nhiều Widget ứng dụng riêng biệt
Mục tiêu của tôi là:
- theo dõi việc sử dụng dữ liệu liên quan đến mỗi trong số nhiều widget riêng
- WiFi và sử dụng dữ liệu di động
- của ứng dụng của riêng tôi mà thôi (không quan tâm đến việc sử dụng dữ liệu của các ứng dụng khác)
- không có quyền bổ sung
- đồng thời cho phép tiện ích thực hiện hoạt động mạng mà không cần tính hai lần sử dụng dữ liệu
- bao gồm việc sử dụng dữ liệu trong
WebView
hoạt động bắt đầu từ phụ tùng - kết quả báo cáo trong ứng dụng (không chỉ khi tethered để Tool Mạng giao thông)
Thật dễ dàng đủ để đăng nhập sử dụng thông tin cho UID riêng của bạn trước và sau khi một phụ tùng cập nhật với TrafficStats
, bằng cách sử dụng getUidRxBytes()
và getUidTxBytes()
(chuyển UID của ứng dụng của riêng bạn), và sau đó lấy sự khác biệt. Trong khi cách tiếp cận thô lỗ và sẵn sàng này cho các giá trị hợp lý khi các vật dụng chạy trong chuỗi, khi chúng đang chạy đồng thời thì chắc chắn là một mức tăng gấp đôi (gấp ba lần) đang diễn ra.
Tôi không muốn ép buộc các tiện ích cập nhật theo chuỗi, vì tôi muốn để công cụ lập kế hoạch công việc của thiết bị phát hiện ra những gì tốt nhất. Vì vậy, tôi cần một cách để tách riêng việc sử dụng dữ liệu cho từng widget từ mỗi khác.
Dường như việc sử dụng thẻ có thể là cách để ... hoạt động mạng thẻ với appWidgetId
và sau đó lọc số liệu thống kê dựa trên số appWidgetId
này. Tôi không thuyết phục cách tiếp cận này sẽ thực sự cho phép sử dụng dữ liệu của một tiện ích được phân biệt với một tiện ích con khác (có thể nhóm sẽ bị nhầm lẫn), nhưng thực tế là tôi không thể gắn thẻ để hoạt động, vì vậy tôi không thể nhưng hãy nói.
Bạn có thể đặt thẻ với setThreadStatsTag(tag)
trước khi bắt đầu hoạt động mạng, nhưng tôi không thể thấy bất kỳ phương thức nào trong lớp TrafficStats
để truy xuất kết quả được lọc theo thẻ. Có ai biết gì khác không?
Vì vậy, sau đó tôi đã xem NetworkStatsManager và cụ thể là NetworkStatsManager.queryDetailsForUidTag(... , tag)
. Điều này dường như cho phép bạn lọc dựa trên tag
cụ thể và hoạt động mà không có bất kỳ quyền bổ sung nào (cho UID của ứng dụng của riêng bạn), điều này là tốt. Nhưng tôi không thể lấy phương thức đó để trả về bất kỳ nhóm nào có dữ liệu, mặc dù thiết lập TrafficStats.setThreadStatsTag(appWidgetId)
trước khi hoạt động mạng sử dụng HttpURLConnection
và truy vấn bằng cùng một thẻ sau đó bằng cách gọi NetworkStatsManager.queryDetailsForUidTag(... , appWidgetId)
.
Mặt khác, NetworkStatsManager.queryDetailsForUid()
(không tag
tham số) không xô trở lại với dữ liệu hợp lệ, vì vậy nó có vẻ là chỉ gắn thẻ không hoạt động, chứ không phải là bất cứ điều gì cơ bản tôi đang làm sai với NetworkStatsManager
mỗi se.
tôi đặt tag với:
@Override
protected void onPreExecute() {
TrafficStats.setThreadStatsTag(appWidgetId);
}
@Override
protected Bitmap doInBackground(String... baseUrls) {
// fetch data with HttpURLConnection
}
@Override
protected void onPostExecute(Bitmap bmp) {
TrafficStats.clearThreadStatsTag();
}
Và (đối với dữ liệu WiFi) Tôi truy vấn số liệu thống kê với:
void networkStatsStuff() {
NetworkStats networkStats;
NetworkStats networkStatsTagged;
int networkType = ConnectivityManager.TYPE_WIFI;
try {
networkStats = networkStatsManager.queryDetailsForUid(networkType, "", startTime, endTime, myUid);
} catch (RemoteException e) {
return;
}
networkStatsTagged = networkStatsManager.queryDetailsForUidTag(networkType, "", startTime, endTime, myUid, appWidgetId);
long totalData = getTotalData(networkStats);
long totalDataTagged = getTotalData(networkStatsTagged);
Log.d(TAG, "totalData: " + totalData); // this seems to work
Log.d(TAG, "totalDataTagged: " + totalDataTagged); // this is always zero
}
long getTotalData(NetworkStats networkStats) {
long totalData = 0;
do {
NetworkStats.Bucket bucket = new NetworkStats.Bucket();
networkStats.getNextBucket(bucket);
totalData = totalData + bucket.getRxBytes() + bucket.getTxBytes();
} while (networkStats.hasNextBucket());
return totalData;
}
Tôi đang làm gì sai? (EDIT: một phần câu trả lời là dưới đây.) Hoặc có thể có một cách hoàn toàn khác nhau để đạt được mục tiêu của tôi?