1.大家都知道Android在2.2版本中提供了TrafficStats接口对流量的统计,它提供了一系列的native方法相应统计分类 ,对应的方法如下:
static longgetMobileRxBytes()//获取通过Mobile连接收到的字节总数,不包含WiFi
static longgetMobileRxPackets()//获取Mobile连接收到的数据包总数,不包含WiFi
static longgetMobileTxBytes()//Mobile发送的总字节数
static longgetMobileTxPackets()//Mobile发送的总数据包数
static longgetTotalRxBytes()//获取总的接受字节数,包含Mobile和WiFi等
static longgetTotalRxPackets()//总的接受数据包数,包含Mobile和WiFi等
static longgetTotalTxBytes()//总的发送字节数,包含Mobile和WiFi等
static longgetTotalTxPackets()//发送的总数据包数,包含Mobile和WiFi等
static longgetUidRxBytes(int uid)//获取某个网络UID的接受字节数
static longgetUidTxBytes(int uid) //获取某个网络UID的发送字节数
2. 但在1.6,2.1呢。。。可以通过对文件的的读取而取得数据流量的数据,所以我猜想TrafficSta应该也通过读文件的方式来取的流量吧。好了不多说了,代码:
public class TrafficService extends Service {
private Handler handler = new Handler();
private int intCounter = 0;
private int mHour;
private int mMinute;
private int mYear;
private int mMonth;
private int mDay;
private String mdate;
final public String DEV_FILE = "/proc/self/net/dev";// 系统流量文件
String[] ethdata = {
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
String[] gprsdata = {
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
String[] wifidata = {
"0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0" };
String data = "0,0,0,0,0,0,0,0,0,0,0,0";// 对应on.txt里面的格式
final String ETHLINE = " eth0";// eth是以太网信息 tiwlan0 是 Wifi rmnet0 是 GPRS
final String GPRSLINE = "rmnet0";
final String WIFILINE = "tiwlan0";
final String TEXT_ENCODING = "UTF-8";
final public String ONPATH = "/data/data/com.example.hello/on.txt";
final public String LOGPATH = "/data/data/zy.dnh/log.txt";
private Runnable mTasks = new Runnable() {
public void run()// 运行该服务执行此函数
{
refresh();
intCounter++;
// DisplayToast("Counter:"+Integer.toString(intCounter));
handler.postDelayed(mTasks, 10000);// 每3000毫秒执行一次
}
};
@Override
public void onStart(Intent intent, int startId) {
handler.postDelayed(mTasks, 0);
super.onStart(intent, startId);
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public IBinder onBind(Intent intent) {
// TrafficStatsCompat t= new TrafficStatsCompat();
// TrafficStats f ;
return null;
}
@Override
public void onDestroy() {
/* */
handler.removeCallbacks(mTasks);
super.onDestroy();
}
//读设备流量
public void readdev() {
FileReader fstream = null;
try {
fstream = new FileReader(DEV_FILE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedReader in = new BufferedReader(fstream, 500);
String line;
String[] segs;
String[] netdata = null;
int count = 0;
int k;
int j;
try {
while ((line = in.readLine()) != null) {
segs = line.trim().split(":");
if (line.startsWith(ETHLINE)) {
netdata = segs[1].trim().split(" ");
for (k = 0, j = 0; k < netdata.length; k++) {
if (netdata[k].length() > 0) {
ethdata[j] = netdata[k];
j++;
}
}
} else if (line.startsWith(GPRSLINE)) {
netdata = segs[1].trim().split(" ");
for (k = 0, j = 0; k < netdata.length; k++) {
if (netdata[k].length() > 0) {
gprsdata[j] = netdata[k];
j++;
}
}
} else if (line.startsWith(WIFILINE)) {
netdata = segs[1].trim().split(" ");
for (k = 0, j = 0; k < netdata.length; k++) {
if (netdata[k].length() > 0) {
wifidata[j] = netdata[k];
j++;
}
}
}
count++;
}
fstream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public String getinfo(String path) {
File file;
String str = "";
FileInputStream in;
try {
// 打开文件file的InputStream
file = new File(path);
if (!file.exists()) {
return "";
}
in = new FileInputStream(file);
// 将文件内容全部读入到byte数组
int length = (int) file.length();
byte[] temp = new byte[length];
in.read(temp, 0, length);
// 将byte数组用UTF-8编码并存入display字符串中
str = EncodingUtils.getString(temp, TEXT_ENCODING);
// 关闭文件file的InputStream
in.close();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
public void writefile(String str, String path) {
File file;
FileOutputStream out;
try {
// 创建文件
file = new File(path);
file.createNewFile();
// 打开文件file的OutputStream
out = new FileOutputStream(file);
String infoToWrite = str;
// 将字符串转换成byte数组写入文件
out.write(infoToWrite.getBytes());
// 关闭文件file的OutputStream
out.close();
} catch (IOException e) {
// 将出错信息打印到Logcat
}
}
public void refresh() {
readdev();// 读取本次开机之后直到当前系统的总流量
data = ethdata[0] + "," + ethdata[1] + "," + ethdata[8] + "," + ethdata[9] + "," + gprsdata[0] + "," + gprsdata[1] + "," + gprsdata[8] + "," + gprsdata[9] + "," + wifidata[0] + ","
+ wifidata[1] + "," + wifidata[8] + "," + wifidata[9];
String onstr = getinfo(ONPATH);// 读取on.txt记录到onstr里
Log.i("sys", "onstr: " + onstr);
Log.i("sys", "UID = " + android.os.Process.myUid());
String ondata[] = onstr.split(",");// 将onstr各项分离 放到ondata里
int[] delta = new int[12];
if (ondata.length > 1) {
delta[0] = Integer.parseInt(ethdata[0]) - Integer.parseInt(ondata[0]);
delta[1] = Integer.parseInt(ethdata[1]) - Integer.parseInt(ondata[1]);
delta[2] = Integer.parseInt(ethdata[8]) - Integer.parseInt(ondata[2]);
delta[3] = Integer.parseInt(ethdata[9]) - Integer.parseInt(ondata[3]);
delta[4] = Integer.parseInt(gprsdata[0]) - Integer.parseInt(ondata[4]);
delta[5] = Integer.parseInt(gprsdata[1]) - Integer.parseInt(ondata[5]);
delta[6] = Integer.parseInt(gprsdata[8]) - Integer.parseInt(ondata[6]);
delta[7] = Integer.parseInt(gprsdata[9]) - Integer.parseInt(ondata[7]);
delta[8] = Integer.parseInt(wifidata[0]) - Integer.parseInt(ondata[8]);
delta[9] = Integer.parseInt(wifidata[1]) - Integer.parseInt(ondata[9]);
delta[10] = Integer.parseInt(wifidata[8]) - Integer.parseInt(ondata[10]);
delta[11] = Integer.parseInt(wifidata[9]) - Integer.parseInt(ondata[11]);
}
// 计算增量
else {
delta[0] = Integer.parseInt(ethdata[0]);
delta[1] = Integer.parseInt(ethdata[1]);
delta[2] = Integer.parseInt(ethdata[8]);
delta[3] = Integer.parseInt(ethdata[9]);
delta[4] = Integer.parseInt(gprsdata[0]);
delta[5] = Integer.parseInt(gprsdata[1]);
delta[6] = Integer.parseInt(gprsdata[8]);
delta[7] = Integer.parseInt(gprsdata[9]);
delta[8] = Integer.parseInt(wifidata[0]);
delta[9] = Integer.parseInt(wifidata[1]);
delta[10] = Integer.parseInt(wifidata[8]);
delta[11] = Integer.parseInt(wifidata[9]);
}
// 读取log.txt
// 获取当前时间
final Calendar c = Calendar.getInstance();
mYear = c.get(Calendar.YEAR); // 获取当前年份
mMonth = c.get(Calendar.MONTH) + 1;// 获取当前月份
mDay = c.get(Calendar.DAY_OF_MONTH);// 获取当前月份的日期号码
mHour = c.get(Calendar.HOUR_OF_DAY);// 获取当前的小时数
mMinute = c.get(Calendar.MINUTE);// 获取当前的分钟数
mdate = mYear + "-" + mMonth + "-" + mDay;
String logstr = getinfo(LOGPATH);// 将log.txt的内容读到text字符串中
String[] line = logstr.split("/n");
Log.i("sys", "logstr: " + logstr);
String today = line[line.length - 1];// 获得今日已记录流量
String[] beToday = today.split(",");
// 检查文件最后一行是否为今天的流量记录信息
if (!beToday[0].equals(mdate))// 如果文件只有一行,表明目前日志为空,将当前日期加入
// 判断今日流量是否已经记录,如果今日流量没有记录
{
logstr = logstr + mdate + ",0,0,0,0,0,0,0,0,0,0,0,0/n";
writefile(logstr, LOGPATH);
line = logstr.split("/n");
today = line[line.length - 1];// 获得今日已记录流量
beToday = today.split(",");
}
int i;
// 处理今日流量
int[] newTodaydata = new int[12];// 表示今日流量
String newtoday = mdate;
for (i = 0; i <= 11; i++) {
newTodaydata[i] = Integer.parseInt(beToday[i + 1]) + delta[i];
newtoday = newtoday + "," + newTodaydata[i];
}
newtoday = newtoday + "/n";
String[] beTotal = line[0].split(",");
int[] newTotaldata = new int[12];// 表示总流量数值
// 更新第一行
String newtotal = "total";
for (i = 0; i <= 11; i++) {
newTotaldata[i] = Integer.parseInt(beTotal[i + 1]) + delta[i];// 总流量数值+delta[i]更新
newtotal = newtotal + "," + newTotaldata[i];
}
newtotal = newtotal + "/n";
// 处理中间不变的部分
String before = "";// before为之前的从第1行到昨天的流量记录
for (i = 1; i <= line.length - 2; i++)
before = before + line[i] + "/n";// 代表中间不变的部分
String newlog = newtotal + before + newtoday;
Log.i("sys", newlog);
for (int k = 0; k < delta.length; k++) {
Log.i("sys", "流量结果: " + delta[k] + "-------");
}
writefile(data, ONPATH);// 更新流量记录
writefile(newlog, LOGPATH);// 更新log*/
}
}
分享到:
相关推荐
在Android 2.1版本中,系统提供了从SD卡导入.vcf(VCard)文件来快速导入联系人的功能。VCard是一种通用的电子名片格式,它允许用户将联系人信息以文本文件的形式分享和导入到不同的设备上。在这个过程中,我们将...
### Android系统从init进程开始到systemserver启动详细流程 #### 1. 概述 在Android系统的启动过程中,从Linux内核加载完成后,系统将执行第一个用户空间进程——`init`进程,它作为后续所有进程的父进程。`init`...
2.1 开发Android硬件驱动程序 2.1.1 实现内核驱动程序模块 2.1.2 修改内核Kconfig文件 2.1.3 修改内核Makefile文件 2.1.4 编译内核驱动程序模块 2.1.5 验证内核驱动程序模块 2.2 开发C可执行程序验证...
Android 2.1版本中,系统支持多个logger device,包括: - `log_main`:用于记录通用的日志信息。 - `log_events`:专门记录系统或硬件事件。 - `log_radio`:记录与无线通信相关的消息。 - `log_system`:记录系统...
##### 2.1 Zygote 进程 `Servicemanager` 和 `zygote` 是两个非常关键的进程。其中`zygote` 进程是整个Android运行环境的基础。`zygote` 进程的启动是由`init.rc` 文件中的如下行定义的: ``` service zygote /...
2.1 开发Android硬件驱动程序 2.1.1 实现内核驱动程序模块 2.1.2 修改内核Kconfig文件 2.1.3 修改内核Makefile文件 2.1.4 编译内核驱动程序模块 2.1.5 验证内核驱动程序模块 2.2 开发C可执行程序验证Android...
本项目是一款基于Android 2.1版本开发的手机秘书应用,它提供了多种实用功能,包括但不限于查看手机软件信息、硬件信息以及管理运行进程等。通过对源代码的深入分析,我们可以了解到Android应用开发的核心技术与实践...
Android设备上的“可用内存”显示通常是指系统认为可以安全分配给新进程的内存数量,它不仅包括物理空闲内存,还包括通过交换分区或缓存释放出的潜在可用内存。LOWMEMORYKILLER在其中扮演了重要角色,通过智能管理...
在Android中,用户空间驱动通常通过binder进程间通信(IPC)机制与系统服务进行交互,实现跨进程的数据传输和调用。 四、驱动开发过程 4.1 驱动编译 驱动代码通常由C或C++编写,需要与Android系统的构建系统(如...
在Android 2.1系统及之后的版本中,内置了一个非常实用的功能——电源管理Widget。通过这一工具,用户可以方便地控制Wi-Fi、蓝牙、GPS以及同步等功能的开关状态,同时还能调整屏幕亮度。这些操作有助于降低手机的...
在深入探讨Android IPC机制之前,我们首先来了解一下基础且关键的Linux进程间通信(IPC)技术。Linux作为一款强大的操作系统,提供了多种进程间通信的方式,这些机制使得不同进程之间能够有效地交换数据和同步执行。...
2.1 界面编程与视图(View)组件 36 2.1.1 视图组件与容器组件 36 2.1.2 使用XML布局文件控制UI 界面 40 2.1.3 在代码中控制UI界面 41 2.1.4 使用XML布局文件和Java 代码混合控制UI界面 42 2.1.5 ...
2.1 Android NDK提供的组件 35 2.2 Android NDK的结构 36 2.3 以一个示例开始 36 2.3.1 指定Android NDK的位置 37 2.3.2 导入示例项目 37 2.3.3 向项目中添加原生支持 39 2.3.4 运行项目 40 2.3.5 用命令行对...
一个进程创建时系统会为它创建一个Activity(活动),紧接着调用onCreate(),onCreate()中主要是进行一些初始化,例如读取XML资源文件创建布局,设置主界面各种监听函数等等,每个进程都会调用onCreate()。...
3.3 跨进程通信:通过JNI,可以实现Java与C/C++间的跨进程通信,实现复杂的系统级服务。 四、注意事项 4.1 错误处理:由于JNI是在C/C++环境中运行,错误处理尤为重要。开发者需要确保对可能出现的错误进行适当的...
2.1 开发Android硬件驱动程序..................................... 14 2.1.1 实现内核驱动程序模块.................................. 14 2.1.2 修改内核Kconfig文件...................................... ...