2017-08-12 18 views
13

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()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?

Trả lời

1

câu trả lời từng phần:

Vì vậy, tôi nghĩ rằng tôi đã đi lạc đường bởi this guide, đó là nơi tôi có vị trí của setThreadStatsTag()clearThreadStatsTag(), trong preExecute()postExecute() tương ứng của AsyncTask.

Khi tôi di chuyển cài đặt và bỏ thẻ vào phần doInBackground() của AsyncTask, sau đó tôi bắt đầu thấy các thẻ ... Tôi nhận thấy điều này trước tiên trong Trình theo dõi thiết bị Android, nhưng chúng cũng có khi sử dụng NetworkStats phương pháp lọc theo tag.

Vì vậy, có vẻ như đúng hơn để sử dụng một cái gì đó giống như mô tả in this guide, dọc theo dòng:

@Override 
protected Bitmap doInBackground(String... baseUrls) { 
    TrafficStats.setThreadStatsTag(appWidgetId); 
    try { 
     // fetch data with HttpURLConnection 
    } finally { 
     TrafficStats.clearThreadStatsTag(); 
    } 
} 

Vì vậy, là hướng dẫn đầu tiên chỉ đơn giản vậy?

Tuy chưa được giải quyết:

  • truy vấn điện thoại di động sử dụng thông tin mà không cần bất kỳ giấy phép bổ sung (Tôi lo sợ rằng READ_PHONE_STATE phép được yêu cầu ... có vẻ như quá mức cần thiết, gây phiền nhiễu và xem xét rằng không phải xin phép với TrafficStats cũng có thể sử dụng dữ liệu di động, mặc dù cùng với các giao diện khác)
  • bao gồm việc sử dụng dữ liệu theo thẻ chỉ vì bản chất của các giao thức có liên quan ... thisthis có thể có liên quan)
Các vấn đề liên quan