1. 主Activity文件
首先编写文件MainActivity.java,此文件是整个系统的核心,能够实现服务勾选处理和模式设置功能,勾选后会禁止或开启某项网络服务。文件MainActivity.java的具体实现流程如下。
- 定义类MainActivity为项目启动后首先显示的Activity,设置按下Menu后显示的选项,并设置需要的各个实例函数。
public class MainActivity extends Activity implements OnCheckedChangeListener, OnClickListener {
//按下Menu后显示的选项
private static final int MENU_DISABLE = 0;
private static final int MENU_TOGGLELOG = 1;
private static final int MENU_APPLY = 2;
private static finall int MENU_EDIT = 3;
private static final int MENU_HELP = 4;
private static final int MENU_SHOWLOG = 5;
private static final int MENU_SHOWRULES = 6;
private static final int MENU_CLEARLOG =7;
private static final int MENU_SETPWD = 8;
//进展对话实例
private ListView listview;
public void onCreate( Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
checkPreferences();
setContentView(R.layout.main);
this.findViewById(R.id.label_mode).setOnClickListenter(this);
Api.assertBinaries(this, true);
}
protected void onStart() {
super.onStart();
Log.d("DroidWall","onStart() - Forcing APP list reload!");
Api.applications =null;
}
protected void onResume() {
super.onResume();
if(this.listview == null) {
this.listview = (ListView) this.findViewById(R.id.listview);
}
refreshHeader();
final String pwd = getSharedPreferences(Api.PREFS_NAME, 0).getString( Api.PREF_PASSWORD, "");
if (pwd.length() == 0) {
showOrLOadApplication();
} else {
requestPassword(pwd);
}
}
protected void onPause() {
super.onPause();
this.listview.setAdapter(null);
}
• 定义函数checkPreferences()检查被存放的选项正常,具体代码如下所示:
//检查被存放的选项正常
private void checkPreferences() {
final SharedPreferences prefs = getSharedPreferences( APi.PREFS_NAME, 0);
final Editor editor = prefs.edit();
boolean changed = false;
if (prefs.getString(Api.PREF_MODE, "").length() == 0) {
editor.putString( Api.PREF_MODE, Api.MODE_WHITELIST);
changed = true;
}
//删除旧的选项名称
if (prefs.contains("AllowedUids")) {
editor.remove("AllowedUids");
changed = true;
}
if (prefs.contains("Interfaces")) {
editor.remove("Interfaces");
changed = true;
}
if (chabged)
editor.commit();
}
• 定义函数refreshHander()来刷新显示当前运行和网络相关的程序,具体代码如下所示:
private void refreshHeader() {
final SharedPreferences prefs = getSharedPreferences(Api.PREFS_NAME,0);
final String mode = prefs.getString(Api.PREF_MODE, Api.MODE_WHITELIST);
final TextView labelmode = (TextView) this.findViewById(R.id.label_mode);
final Resources res = getResources();
int resid = (mode.equals(Api.MODE_WHITELIST)? R.string.mode_whitelist : R.string.mode_blacklist);
labelmode.setText( res.getString (R.string.mode_header, res.getSTring(resid)));
resid = (Api.isEnabled(this) ? R.string.title_enabled : R.string.title_disabled);
setTitle (res.getSting (resid, Api.VERSION));
}
• 定义函数selectMode()显示对话框选择操作方式,供我们选择黑名单模式还是白名单模式。
private void selectMode() {
final Resources res = getResources();
new ALertDialog.Builder(this)
.setItems(
new String[] { res.getString(R.string.mode_whitelist),
res.getString( Rstring.mode_blacklist.) },
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
final String mode = (which == 0? Api.MODE_WHITELIST : Api.MODE_BLACKLIST);
final Editor editor = getSharedPreferences( Api.PREFS_NAME, 0).edit();
editor.putString(Api.PREF_MODE, mode);
editor.commit();
refreshHeader();
}
}).setTitle("Select mode:").show();
• 定义函数setPassword()来设置一个系统密码,如果设置密码后,在进入主界面前会通过函数requestPassword()来验证密码,只有密码正确才能进入。
//设置一新的密码
private void setPassword (String pwd) {
final Resources res = getResources();
final Editor editor = getSharedPreferences( Api.PREFS_NAME, 0).edit();
editor.putString( Api.PREF_PASSWORD,pwd);
String msg;
if (editor.commit()) {
if(pwd.length() > 0) {
msg = res.getString( R.string.passdefined);
} else {
msg = res.getString(R.string.passremoved);
}
Toast.makeText( MainActivity.this, msg, Toast.LENGTH_SHORT).show.();
}
//如果设置了密码,显示主界面前先验证密码
private void requestPassword( final String pwd) {
new PassDIalog( this, false, new android.os.Handler.callback() {
public boolean handleMessage( Message msg) {
if (msg.obj == null) {
MainActivity.this.finish();
android.os.Process.killProcess( android.os.Process.myPid());
return false;}
if ( !pwd.equals(msg.obj)) {
requestPassword(pwd);
return false;
}
//如果密码正确
showOrLoadApplications();
return false;
}
}).show();
}
• 编写函数toggleLogEnabed()实现防火墙禁用和日志禁用开关处理。
private void toggleLogEnabled() {
final SharedPreferences prefs = getSharedPreferences(Api.PREFS_NAME, 0 );
final boolean enabled = !prefs.getBollean(Api.PREF_LOGENABLED, false);
final Editor editor = prefs.edit();
editor.putBoolean(Api.PREF_LOGENABLED, enabled);
editor.commit();
if(Api.isEnabled(this)) {
Api.applySavedIptablesRules(this, true);
}
Toast.makeText(
MainActivity.this,
(enabled? R.string.log_was_enabled: Rstring.log_was_disable),
Toast.LENGTH_SHORT).show();
}
• 编写函数showOrLoadApplication(),如果在某模式下有应用则显示里面的应用。
private void showOrLoadApplications() {
final Resources res = getResources();
if(Api.applications == null) {
final ProgressDialog progress = ProgressDialog.show(this,
res.getString(R.string.working), res.getString(R.string.reading_apps), true);
final Handler handler = new Handler() {
public void handleMessage (Message msg) {
try {
progress.dismiss();
} catch (Exception ex) {
}
showApplications();
}
};
new Thread() {
public void run() {
Api.getApps(MainActivity.this);
handler.sendEmptyMessage(0);
}
}.start();
} else {
//储藏应用,显示名单
showApplications();
}
}
• 编写showApplications()显示应用名单
private void showApplications() {
final DroidApp[ ] apps = Api.getApps(this);
Arrays.sort( apps, new Comparator<DroidApp>() {
public int compare (DroidApp o1, DroidApp o2) {
if ((o1.selected_wifi | o1.selected_3g) == (o2.selected_wifi | o2.selected_3g)) {
return String.CASE_INSENSITIVE_ORDER.compare (o1.name[0], o2.names[0]);
}
if (o1.selected_wifi || o1.selected_3g)
return -1;
return 1;
}
});
final LayoutInflater inflater = getLayoutInflater();
final LIstAdapter adapter = new ArrayAdapter<DroidApp> (this, R.layout.listitem, R.id.app_text, apps) {
public View getView (int position, View contertView, ViewGroup parent) {
ListEntry entry;
if (convertView == null) {
convertView = inflater.inflate (R.layout.listitem, parent, false);
entry = new ListEntry();
entry.box_wifi = (CheckBox) convertView.findViewById(R.id.itemcheck_wifi);
entry.box_3g = (CheckBox) convertView.findViewById(R.id.itemcheck_3g);
entry.app_text = (TextView) convert.findViewById(R.id.app_text);
entry.upload = (TextView) convertView.findViewById(R.id.upload);
entry.download = (TextView) convertView.findViewById(R.id.download);
convertView.setTag(entry);
entry.box_wifi.setOnCheckedChangeListener( MainActivity.this);
entry.box_3g.setOnCheckedChangeListener( MainActivity.this);
} else {
//转换一个现有视图
final DroidApp app = apps [position];
entry.app_text.setText( app.toString());
convertAndSetColor (TrafficStats.getUidTxBytes( app.uid), entry.upload);
convertAndSetColor (TrafficStats.getUidRxBytes( app.uid), entry.download);
final CheckBox box_wifi = entry.box_wifi;
box_wifi.setTag(app);
box_wifi.setChecked (app.selected_wifi);
final CheckBox box_3g = entry.box_3g;
box_3g.setTag(app);
box_3g.setChecked (app.selected_3g);
return convertView;
}
• 编写函数convertAndSetColor(), 根据对某选项的设置显示内容,并设置显示内容的颜色。假如没有任何设置,则显示“N/A”,如果已经设置了启用 则显示已经用过的流量。
private void convertAndSetColor( long num, TextView text) {
String value = null;
long temp = num;
float floatnum = num;
if( num == -1) {
value = "N/A";
text.setText(value);
text.setTextColor(0xff919191);
return;
} else if ((temp = temp/1024) < 1) {
value = num + "B";
} else {
value = temp + "KB";
} else {
DecimalFormat format = new DecimalFormat ("##0.0");
value = format.format( floatnum) + "MB";
}
text.setText(value);
text.setTextColor(0xffff0300);
}
};
this.listview.setAdapter(adapter);
}
• 进入系统主界面后,如果按下MENU键则会弹出设置界面,在设置界面中可以选择对应的功能。
public boolean onCreateOptionsMenu( Menu menu) {
menu.add( 0, MENU_DISABLE, 0, R.string.fw_enabled).setIcon( android.R.drawable.button_onoff_indicator_on);
menu.add( 0, MENU_TOGGLELOG, 0, R.string.log_enabled).setIcon( android.R.drawable.button_onoff_indicator_on);
menu.add( 0, MENU_APPLY, 0, R.string.applyrules).setIcon(R.drawable.apply);
menu.add( 0, MENU_EXIT, 0, R.string.eixt).setIcon( android.R.drawable.ic_menu_close_clear_cancel);
menu.add( 0, MENU_HELP, 0, R.string.help).setIcon( android.R.drawable.ic_menu_help);
menu.add( 0, MENU_SHOWLOG, 0, R.string.show_log).setIcon(R.drawable.show);
menu.add( 0, MENU_SHOWRULES, 0, R.string.showrules).setIcon(R.drawable.show);
menu.add( 0, MENU_CLEARLOG, 0, R.string.clear_log).setIcon(android.R.drawable.ic_menu_close_clear_cancel);
menu.add( 0, MENU_SETPWD, 0, R.string.setpwd).setIcon(android.R.drawable.ic_lock_lock);
return;
}
public boolean onPrepareOptionMenu( Menu menu) {
final MenuItem item_onoff = menu.getItem( MENU_DISABLE);
final MenuItem item_apply = menu.getItem( MENU_APPLY);
final boolean enabled = Api.isEnabled(this);
if (enabled) {
item_onoff.setIcon( android.R.drawable.button_onoff_indicator_on);
item_onoff.setTitle( R.string.fw_enabled);
item_apply.setTitle( R.string.applyrules);
} else {
item_onoff.setIcon( android.R.drawable.button_onoff_indicator_off);
item_onoff.setTitle( R.string.fw_disabled);
item_apply.setTitle( R.string.saverules);
}
final MenuItem item_log = menu.getItem( MENU_TOGGLELOG);
final boolean logenabled = getSharedPreferences( Api.PREFS_NAME, 0).getBoolean( Api.PREF_LOGENABLED, false);
if (logenabled) {
item_log.setIcon( android.R.drawable.button_onoff_indicator_on);
item_log.setTitle( R.string.log_enabled);
} else {
item_log.setIcon( android.R.drawable.button_onoff_indicator_off);
item_log.setTitle( R.string.log_disabled);
}
return super.onPrepareOptionMenu( menu);
}
public boolean onMenuItemSelected( int featureId, MenuItem item) {
switch (item.getItemId()) {
case MENU_DISABLE:
disableOrEnable();
return true;
case MENU_TOGGLELOG:
toogleLogEnabled();
return true;
case MENU_APPLY:
applyOrSaveRules();
return true;
case MENU_EIXT:
finish();
System.exit( 0);
return true;
case MENU_HELP:
new HelpDIalog(this).show();
return true;
case MENU_SETPWD:
setPassword();
return true;
case MENU_SHOWLOG:
showLog();
return true;
case MENU_SHOWRULES:
showRules();
return true;
case MENU_CLEARLOG:
clearLog();
return true;
}
return false;
}
• 编写函数disableOrEnable()设置开启或关闭防火墙
private void disableOrEnable() {
final boolean enabled = !Api.isEnabled( this);
Log.d ("DriodWall", "Changing enabled status to: " + enabled);
Api.setEnabled( this, enabled);
if (enabled) {
applyOrSaveRules();
} else {
purgeRules();
}
refreshHeader();
}
• 编写函数setPassword来设置密码界面
private void setPassword() {
new PassDialog (this, true, new android.os.Handler.Callback() {
public boolean handleMessage (Message msg) {
if (msg.obj != null) {
setPassword( (String) msg.obj);
}
return false;
)
}).show();
}
• 选择“Save rules(保存规则)”后执行函数showRules()
private void showRules() {
final Resources res = getResources();
final ProgressDialog progress = ProgressDialog.show( this, res.getString (R.string.working), res.getString( R.string.please_wait), true);
final Handler handler = new Handler () {
public void handleMessage( Message msg) {
try {
progress.dismiss();
} catch (Exception ex) {
}
if (! Api.hasRootAccess (MainActivity.this, true))
return;
Api.showIptablesRules (MainActivity.this);
}
};
handler.sendEmptyMessageDelayed( 0, 100);
}
• 编写函数showLog()显示日志信息界面
private void showLog() {
final Resources res = getResources();
final ProgressDialog progress = ProgressDialog.show( this, res.getString( R.string.working), res.getString( R.string.please_wait), true);
final Handler handler = new Handler() {
public void handleMessage (Message msg) {
try {
progress.dismiss();
} catch (Exception ex) {
}
Api.showLog( MainActivity.this);
}
};
handler.sendEmptyMessageDelayed( 0, 100);
}
• 编写函数clearLog()清除系统内的日志记录信息
private void clearLog() {
final Resources res = getResources();
final ProgressDIalog progress = ProgressDIalog.show( this, res.getString( R.string.working), res.getString( R.string.please_wait), true);
final Handler handler = new Handler() {
public void handlerMessage( Message msg) {
try {
progress.dismiss();
} catch (Exception ex) {
}
if (!Api.hasRootAccess (MainActivity.this, true))
return;
if (Api.clearLog( MainActivity.this)) {
Toast.makeText( MainActivity.this, R.string.log_cleared, Toast.LENGTH_SHORT).show();
}
}
};
handler.sendEmptyMessageDelayed(0, 100);
}
• 编写函数applyOrSaveRules(),当申请或保存规则后将规则运用到本系统
private void applyOrSaveRules() {
final Resources res = getResources();
final boolean enabled = Api.isEnabled( this);
final ProgressDialog progress = ProgressDialog.show( this, res.getString( R.string.working), res.getString( enabled ? R.string.applying_rules: R.string.saving_rules), true);
final Handler handler = new Handler() {
public void handleMessage( Message msg) {
try {
progress.dismiss();
} catch( Exception ex) {
}
if (enabled) {
Log.d ("DroidWall", "Applying rules.");
if (Api.hasRootAccess( MainActivity.this, true) && Api.applyIptablesRules (MainActivity.this ,true)) {
Toast.makeText (MainActivity.this, R.string.rules_applied, Toast.LENGTH_SHORT).show();
} else {
Log.d ("DroidWall", "Failed - Disabling firewall.");
Api.setEnabled( MainActivity.this, false);
}
} else {
Log.d ("DroidWall", "Saving rules.");
Api.saveRules( MainActivity.this, R.string.rules_saved, Toast.LENGTH_SHORT).show();
}
}
};
handler.sendEmptyMessageDelayed( 0, 100);
}
• 编写函数purgeRules()来清除一个规则
private void purgeRules() {
final Resources res = getResources();
final ProgressDialog progress = ProgressDialog.show (this, res.getString( R.string,working), res.getString( R.string.deleting_rules), true);
final Handler handler = new Handler() {
public void handleMessage( Message msg) {
try {
progress.dismiss();
} catch (Exception ex) {
}
if (!Api.hasRootAccess (MainActivity.this, true))
return;
if (!Api.purgeIptables( MainActivity.this, true)) {
Toast.makeText (MainActivity.this, R.string.rules_deleted, Toast.LENGTH_SHORT).show();
}
}
};
handler.sendEmptyMessageDelayed( 0, 100);
}
• 编写函数onCheckedChanged()检查WI-FI选项和3G选项是否发送变化
public void onCheckedChanged (CompoundButton buttonView, boolean isChecked) {
final DroidApp app = (DroidApp) buttonView.getTag();
if (app != null) {
switch (buttonView.getId()) {
case R.id.itemcheck_wifi:
app.selected_wifi = isChecked;
break;
case R.id.itemcheck_3g:
app.selected_3g = isChecked;
break;
}
}
}
到目前为止,主界面程序介绍完毕,关于string.xml文件里string内容的定义我这边就不列拉。