BroadcastReceiver模块
用于监听开机信息 并初始化和启动服务
package zy.dnh; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast; public class getpowerinfo extends BroadcastReceiver{ FileOutputStream out; final public String ONPATH = "/data/data/zy.dnh/on.txt"; @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub if(intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)){ Intent bootActivityIntent=new Intent(context,mService1.class);//启动服务 bootActivityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); writefile("0,0,0,0,0,0,0,0,0,0,0,0",ONPATH); context.startService(bootActivityIntent); Toast.makeText(context, "Netcounter service has been lauched", Toast.LENGTH_LONG).show(); Api.applySavedIptablesRules(context, false);//应用防火墙规则 Toast.makeText(context, "Wall rules have been lauched", Toast.LENGTH_LONG).show(); } } public void writefile(String str,String path ) { File file; 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 }
mService1模块
后台服务,用于维护流量日志
public class mService1 extends Service { private Handler objHandler = 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";//以太网信息所在行 final String GPRSLINE="rmnet0"; final String WIFILINE="tiwlan0"; final String TEXT_ENCODING = "UTF-8"; final public String ONPATH = "/data/data/zy.dnh/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)); objHandler.postDelayed(mTasks, 30000);//每3000毫秒执行一次 } }; @Override public void onStart(Intent intent, int startId) { // TODO Auto-generated method stub //writefile("0,0,0,0,0,0,0,0,0,0,0,0",ONPATH);//每次启动服务 初始化onpath objHandler.postDelayed(mTasks, 0); super.onStart(intent, startId); } @Override public void onCreate() { // TODO Auto-generated method stub super.onCreate(); } @Override public IBinder onBind(Intent intent) { // TODO Auto-generated method stub return null; } @Override public void onDestroy() { // TODO Auto-generated method stub /* */ objHandler.removeCallbacks(mTasks); super.onDestroy(); } public void DisplayToast(String str) { Toast.makeText(this,str,Toast.LENGTH_SHORT).show(); } public void readdev() { FileReader fstream = null; try { fstream = new FileReader(DEV_FILE); } catch (FileNotFoundException e) { DisplayToast("Could not read " + DEV_FILE); } BufferedReader in = new BufferedReader(fstream, 500); String line; String[] segs; String[] netdata; 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) { DisplayToast(e.toString()); } } public String getinfo(String path) { File file; String str=""; FileInputStream in; try{ //打开文件file的InputStream file = new File(path); 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) { DisplayToast(e.toString()); } 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 DisplayToast(e.toString()); } } 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里 String ondata[]=onstr.split(",");//将onstr各项分离 放到ondata里 //计算增量 int [] delta=new int [12]; 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]); //读取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 text=getinfo(LOGPATH);//将log.txt的内容读到text字符串中 String [] line=text.split("\n"); String today=line[line.length-1];//获得今日已记录流量 String [] beToday=today.split(","); //检查文件{zh1}一行是否为今天的流量记录信息 if(!beToday[0].equals(mdate))// //判断今日流量是否已经记录,如果今日流量没有记录 { text=text+mdate+",0,0,0,0,0,0,0,0,0,0,0,0\n"; writefile(text,LOGPATH); line=text.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];//表示总流量数值 //更新{dy}行 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; writefile(data,ONPATH);//更新流量记录 writefile(newlog,LOGPATH);//更新log*/ } }
应用iptable规则模块,通过运行iptable脚本来实现iptable规则的应用
private static boolean applyIptablesRulesImpl(Context ctx, List<Integer> uids, boolean showErrors) { if (ctx == null) { return false; } final SharedPreferences prefs = ctx.getSharedPreferences(PREFS_NAME, 0); final boolean whitelist = prefs.getString(PREF_MODE, MODE_WHITELIST).equals(MODE_WHITELIST); boolean wifi = false; // Wi-fi selected ? final String itfs = prefs.getString(PREF_ITFS, ITF_3G); String itfFilter; if (itfs.indexOf("|") != -1) { itfFilter = ""; // Block all interfaces wifi = true; } else if (itfs.indexOf(ITF_3G) != -1) { itfFilter = "-o rmnet+";; // Block all rmnet interfaces } else { itfFilter = "-o tiwlan+";; // Block all tiwlan interfaces wifi = true; } final StringBuilder script = new StringBuilder(); try { int code; script.append("iptables -F || exit\n"); final String targetRule = (whitelist ? "ACCEPT" : "REJECT"); if (whitelist && wifi) { // When "white listing" Wi-fi, we need ensure that the dhcp and wifi users are allowed int uid = android.os.Process.getUidForName("dhcp"); if (uid != -1) script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j ACCEPT || exit\n"); uid = android.os.Process.getUidForName("wifi"); if (uid != -1) script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j ACCEPT || exit\n"); } for (Integer uid : uids) { script.append("iptables -A OUTPUT " + itfFilter + " -m owner --uid-owner " + uid + " -j " + targetRule + " || exit\n"); } if (whitelist) { script.append("iptables -A OUTPUT " + itfFilter + " -j REJECT || exit\n"); } StringBuilder res = new StringBuilder(); code = runScriptAsRoot(script.toString(), res); if (showErrors && code != 0) { String msg = res.toString(); Log.e("DroidWall", msg); // Search for common error messages if (msg.indexOf("Couldn't find match `owner'") != -1 || msg.indexOf("no chain/target match") != -1) { alert(ctx, "Error applying iptables rules.\nExit code: " + code + "\n\n" +"It seems your Linux kernel was not compiled with the netfilter \"owner\" module enabled, which is required for Droid Wall to work properly.\n\n" +"You should check if there is an updated version of your Android ROM compiled with this kernel module."); } else { // Remove unnecessary help message from output if (msg.indexOf("\nTry `iptables -h' or 'iptables --help' for more information.") != -1) { msg = msg.replace("\nTry `iptables -h' or 'iptables --help' for more information.", ""); } // Try `iptables -h' or 'iptables --help' for more information. alert(ctx, "Error applying iptables rules. Exit code: " + code + "\n\n" + msg.trim()); } } else { return true; } } catch (Exception e) { if (showErrors) alert(ctx, "error refreshing iptables: " + e); } return false; }