imifirewall(艾米防火墙)是一款Android下的防火墙软件,它主要用来帮助手机用户解决日常使用中遇到的问题:电话骚扰,钓鱼短信,手机垃圾,系统变慢等众多问题,艾米防火墙暂时只支持短信过滤,来电拦截,程序联网行为拦截和流量查看等功能,以后会陆续添加更多实用的功能。
不错的国产防火墙项目,项目如图:
效果如图:
主要源码分析:
public class Function { // jni加载以及本地调用
public static FileDescriptor createSubprocess(String cmd, String arg0,
String arg1) {
return createSubprocess(cmd, arg0, arg1, null);
}
public static native FileDescriptor createSubprocess(String cmd,
String arg0, String arg1, int[] processId); // 创建子进程
public static native void setPtyWindowSize(FileDescriptor fd, int row,
int col, int xpixel, int ypixel); // 设置窗口大小
public static native int waitFor(int processId); // 等待某进程
public static native String version(); // 版本信息
static {
System.loadLibrary("imiFunction");
}
}
Jni项目就两个文件,如图:
关键Api
public final class imiApi { // 封装好的API 关键操作类
主要方法如下:
private static boolean applyIptablesRulesImpl(Context ctx,
List<Integer> uidsWifi, List<Integer> uids3g, boolean showErrors) { // 清除并重新添加所有规则(内部实现)
public static boolean applySavedIptablesRules(Context ctx,
boolean showErrors) {// 清除并重新添加所有已保存的规则(而不是在内存中的)
public static boolean applyIptablesRules(Context ctx, boolean showErrors) {// 清除并重新添加的所有规则
public static void saveRules(Context ctx) {// 保存当前使用规则
public static boolean purgeIptables(Context ctx, boolean showErrors) {// 清除所有ip
public static void showIptablesRules(Context ctx) { // 显示ip
public static DroidApp[] getApps(Context ctx) { // 获得app信息
public static boolean hasRootAccess(Context ctx, boolean showErrors) { // 确认系统权限
public static int runScriptAsRoot(Context ctx, String script,
StringBuilder res, final long timeout) { // 系统权限运行一个脚本
public static int runScriptAsRoot(Context ctx, String script,
StringBuilder res) throws IOException { // 运行一个脚本根 设置一个默认的超时时间为20秒。
public static String RunCustomCmd(String[] cmd, String workdirectory) //执行自定义命令
public static boolean isEnabled(Context ctx) { // 确认防火墙是否开启
public static void setEnabled(Context ctx, boolean enabled) { // 设置防火墙开启与禁止
public class imiCallEngine extends PhoneStateListener { // 电话引擎 监听手机状态
主要方法如下:
// 监听电话线路
public void StartListen(TelephonyManager telMgr) {
telMgr.listen(this, LISTEN_CALL_STATE);
}
public void Hangup() { //挂断电话
// endCallExtend.endcall();
ITelephony iTelephony = null;
TelephonyManager tManager = (TelephonyManager) mContext
.getSystemService(Context.TELEPHONY_SERVICE);
// 初始化iTelephony
Class<TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
getITelephonyMethod = c.getDeclaredMethod("getITelephony",
(Class[]) null);
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony = (ITelephony) getITelephonyMethod.invoke(tManager,
(Object[]) null);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
try {
iTelephony.endCall();
} catch (Exception e) {
}
}
其它关键方法:
public void InstallShortCut() { //初始化快接方法
Intent shortcutIntent = new Intent(ACTION_INSTALL_SHORTCUT);
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
getString(R.string.app_name)); // 快捷方式ICON
shortcutIntent.putExtra(EXTRA_SHORTCUT_DUPLICATE, false); // 覆盖以前的ICON
Intent intent = new Intent();
intent.setComponent(new ComponentName(this.getPackageName(),
".ActivityMain")); // 设置快捷方式的启动程序
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this, R.drawable.icon));
sendBroadcast(shortcutIntent);
}
public void onClick(View v) { //执行shell命令
// TODO Auto-generated method stub
String et_input_value = actinput.getText().toString();
String cmdoutput = "";
ArrayList my_cmd_list = new ArrayList();
if (et_input_value != null) {
String mycmd = "'" + et_input_value.trim() + "'";
my_cmd_list.add(0, "/system/bin/sh"); // shell path
my_cmd_list.add(1, "-c");
my_cmd_list.add(2, mycmd);
int size = my_cmd_list.size();
String[] my_cmd = new String[size];
for (int i = 0; i < size; i++)
my_cmd[i] = (String) my_cmd_list.get(i);
try {
cmdoutput = imiApi.RunCustomCmd(my_cmd, "/");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
tv_output = (TextView) findViewById(R.id.output);
tv_output.setText(cmdoutput);
actinput.setText("");
} else {
tv_output = (TextView) findViewById(R.id.output);
tv_output.setText("The Content Input is not proper!");
}
}
private void setCallProfile() { //设置电话的防骚扰策略
// TODO Auto-generated method stub
int callProfile = db.getOptionsIntData(Commons.CALLSpamType);
ListPreference callProfilelist = (ListPreference) findPreference("call_setting");
callProfilelist.setValueIndex(callProfile);
switch (callProfile) {
case Commons.CALL_PROFILE_NORMAL: {
callProfilelist.setSummary(R.string.call_profile_normal);
break;
}
case Commons.CALL_PROFILE_REJECT_UNKNOW: {
callProfilelist.setSummary(R.string.call_profile_reject_unknow);
break;
}
case Commons.CALL_PROFILE_REJECT_BL: {
callProfilelist.setSummary(R.string.call_profile_reject_blacklist);
break;
}
case Commons.CALL_PROFILE_ONLY_WL_: {
callProfilelist.setSummary(R.string.call_profile_only_whitelist);
break;
}
case Commons.CALL_PROFILE_REJECT_ALL: {
callProfilelist.setSummary(R.string.call_profile_reject_all);
break;
}
default:
break;
}
}
private void saveCallProfile() { //保存电话的防骚扰策略
ListPreference callProfilelist = (ListPreference) findPreference("call_setting");
db.updateOptionsData(Commons.CALLSpamType,
Integer.parseInt(callProfilelist.getValue()));
}
private void setCallBack() { //设置电话被拒的返回铃音
int backTone = db.getOptionsIntData(Commons.CallBackTone);
ListPreference callProfilelist = (ListPreference) findPreference("call_back");
callProfilelist.setValueIndex(backTone);
switch (backTone) {
case Commons.CALL_BUSY: {
callProfilelist.setSummary(R.string.back_tone_busy);
break;
}
case Commons.CALL_POWER_OFF: {
callProfilelist.setSummary(R.string.back_tone_poweroff);
break;
}
case Commons.CALL_OUT_OF_SERVICE: {
callProfilelist.setSummary(R.string.back_tone_outservice);
break;
}
default:
break;
}
}
void saveBackTone() { //保存电话的返回铃音的设置
ListPreference callProfilelist = (ListPreference) findPreference("back_tone");
db.updateOptionsData(Commons.CallBackTone,
Integer.parseInt(callProfilelist.getValue()));
}
void setMessageProfile() {//设置短信的防骚扰策略
int message_type = db.getOptionsIntData(Commons.MessageSpamType);
// mDb.getOptionsData(mOptionsData);
ListPreference callProfilelist = (ListPreference) findPreference("message_profile");
callProfilelist.setValueIndex(message_type);
switch (message_type) {
case Commons.MESSAGE_PROFILE_REJECT_UNKNOW: {
callProfilelist.setSummary(R.string.message_profile_reject_unknow);
break;
}
case Commons.MESSAGE_PROFILE_RECEIVING_ALL: {
callProfilelist.setSummary(R.string.message_profile_receving_all);
break;
}
default:
break;
}
}
void saveMessageProfile() {//保存短信的防骚扰策略
ListPreference callProfilelist = (ListPreference) findPreference("message_profile");
db.updateOptionsData(Commons.MessageSpamType,
Integer.parseInt(callProfilelist.getValue()));
}
void setFilterMessage() { //设置是否进行垃圾短信过滤
int filterValue = db.getOptionsIntData(Commons.MessageSpamFilter);
CheckBoxPreference preference = (CheckBoxPreference) findPreference("spam_filter");
preference.setChecked(filterValue > 0 ? true : false);
}
void saveFilterMessage() { //保存垃圾短信过滤策略
CheckBoxPreference callProfilelist = (CheckBoxPreference) findPreference("spam_filter");
db.updateOptionsData(Commons.MessageSpamFilter,
callProfilelist.isChecked() ? 1 : 0);
}
private void callForwarding(String forwardNum, boolean isSetCallForward) { // 设置呼叫转移选项
String encoded = Uri.encode("#");
TelephonyManager telMagr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
if (telMagr.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) {
Intent intent = null;
if (isSetCallForward) {
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:**67*"
+ Uri.encode(forwardNum) + encoded));
} else {
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
+ encoded + Uri.encode("67") + encoded));
}
startActivity(intent);
} else {
Intent intent = null;
if (isSetCallForward) {
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:*900"));
} else {
intent = new Intent(Intent.ACTION_CALL, Uri.parse("tel:*90"
+ forwardNum + encoded));
}
startActivity(intent);
}
}
private void launchProcess(int pos) // 打开进程
{
String app = ((PROEntity) mList.getItemAtPosition(pos))
.getProcessName();
Intent launch_intent = getPackageManager().getLaunchIntentForPackage(
app);
if (launch_intent != null) {
startActivity(launch_intent);
}
}
private void closeProcess(int pos) // 结束进程
{
String app = ((PROEntity) mList.getItemAtPosition(pos))
.getProcessName();
ActivityManager am = this.mActivityMgr;
imiProcess.killByLevel7(am, app);
((ProcessAdapter) mList.getAdapter()).removeContent(pos);
}
private void showProcessDetail(int pos) // 显示进程详细信息
{
String app = ((PROEntity) mList.getItemAtPosition(pos))
.getProcessName();
Intent detail = Commons.getPackageDetailIntent(app);
startActivity(detail);
}
public class BootBroadcast extends BroadcastReceiver { // 启动广播
private imiSql myPhoneDbHelper;
private ITelephony iTelephony;
static final String BOOT_ACTION = "android.intent.action.BOOT_COMPLETED";
static final String SMS_ACTION = "android.provider.Telephony.SMS_RECEIVED";
static final String CALL_ACTION = "android.intent.action.PHONE_STATE";
static final String OUT_ACTION = "android.intent.action.NEW_OUTGOING_CALL";
final private String TAG = "imiFirewall_Receiver";
@Override
public void onReceive(Context context, Intent intent) {
final SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(context);
if (intent.getAction().equals(BOOT_ACTION)) { // 开机自启动程序
Log.d(TAG, "system boot completed");
if (prefs.getBoolean("Network", true) == true) // 防火墙开关
{
if (!imiApi.applySavedIptablesRules(context, false)) {
// Error enabling firewall on boot
Toast.makeText(context, R.string.toast_error_enabling,
Toast.LENGTH_SHORT).show();
imiApi.setEnabled(context, false);
}
}
// 清空流量统计的数据
// Intent intentclean =new Intent(context,BootService.class);
// context.startService(intentclean);
// Intent intentnet =new Intent(context,NetService.class);
// context.startService(intentnet);
}
}// OnReceiver_END
}
拦截事件在服务中,项目提供了三个服务,如下:
public class BootService extends Service { // 启动服务
public class FireService extends Service implements CallEventListener { // 防火墙服务
public class NetService extends Service { // 网络监管服务
主要方法如下:
public void processIncomingSMS(String smsPhone, String smsMessage, long date) { //处理来信消息
Log.i("imi_get_message", smsMessage);
if (!processSMSData(0, smsPhone, smsMessage, date, 1)) {
// 如果短信未被处理,则将其插入至系统收件箱
// insertSMSToSys(smsPhone,smsMessage,date);
}
}
/*
* 监听呼出电话的处理操作
*/
public void processOutgoingCall(String outGoingNumber) {
}
/*
* 监听呼入电话的处理操作
*/
public void processCall(String incomingNumber) {
if (db.isNumberInUserList(incomingNumber, Commons.VIP_LIST)) {
Log.i("imi", "VIP number");
mVIPIncomingNumber = incomingNumber;
mVIPNeedDeleteLog = true;
} else {
boolean bNeedHangup = false;
// 判断其它情景模式
switch (db.getOptionsIntData(Commons.CALLSpamType)) {
case Commons.CALL_PROFILE_REJECT_UNKNOW: {
if (getNameFromContacts(incomingNumber).length() <= 0) {
bNeedHangup = true;
}
break;
}
case Commons.CALL_PROFILE_REJECT_BL: {
if (db.isNumberInUserList(incomingNumber, Commons.BLACK_LIST)) {
bNeedHangup = true;
}
break;
}
case Commons.CALL_PROFILE_ONLY_WL_: {
if (!db.isNumberInUserList(incomingNumber, Commons.WHITE_LIST)) {
bNeedHangup = true;
}
break;
}
case Commons.CALL_PROFILE_REJECT_ALL: {
bNeedHangup = true;
break;
}
default:
break;
}
if (bNeedHangup) {
mCallEngine.Hangup();
clearSystemNotification();
insertRecordToDb(incomingNumber, Commons.LOG_SPAM_CALL,
Commons.LOG_SPAM_REJECT_CALL);
setNotifyType(Commons.NEW_REJECT_CALL_NOTIFY);
//
}
}
}
public void clearSystemNotification() { //清除系统通知
ITelephony iTelephony = null;
TelephonyManager tManager = (TelephonyManager) this
.getSystemService(Context.TELEPHONY_SERVICE);
// 初始化iTelephony
Class<TelephonyManager> c = TelephonyManager.class;
Method getITelephonyMethod = null;
try {
getITelephonyMethod = c.getDeclaredMethod("getITelephony",
(Class[]) null);
getITelephonyMethod.setAccessible(true);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony = (ITelephony) getITelephonyMethod.invoke(tManager,
(Object[]) null);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
iTelephony.cancelMissedCallsNotification();// 删除未接来电通知
StringBuilder where = new StringBuilder("type=");
where.append(Calls.MISSED_TYPE);
where.append(" AND new=1");
ContentValues values = new ContentValues(1);
values.put(Calls.NEW, "0");
this.getContentResolver().update(Calls.CONTENT_URI, values,
where.toString(), null);
} catch (Exception e) {
}
}
boolean processSMSData(int contactsIndex, String phone, String body,
long date, int type) { //处理短信
if (phone.length() > 0) {
// 确认其为发出的短信
if (db.isNumberInUserList(
phone.length() > 9 ? phone.substring(phone.length() - 9,
phone.length()) : phone, Commons.VIP_LIST)) {
Commons.PDATA tempData = new Commons.PDATA();
tempData.mStringValue_1 = contactsIndex > 0 ? getNameFromContacts(contactsIndex)
: "";
tempData.mStringValue_2 = phone;
tempData.mStringValue_3 = body;
tempData.mIntValue_1 = Commons.LOG_VIP_MESSAGE;
tempData.mIntValue_2 = (type == 1) ? Commons.LOG_VIP_INCOMING_MESSAGE
: Commons.LOG_VIP_OUTGOING_MESSAGE;
tempData.mIntValue_3 = 0;
tempData.mIntValue_4 = db.getMessageThreadId(phone);
tempData.mDate = date;
db.AddData(imiSql.DATABASE_TABLE_USERLOG, tempData);
if (type == 1) {
setNotifyType(Commons.NEW_VIP_MESSAGE_NOTIFY);
}
return true;
} else if (type == 1) {
// 判断其是否为骚扰短信
if ((db.getOptionsIntData(Commons.MessageSpamType) == Commons.MESSAGE_PROFILE_REJECT_UNKNOW && (type == 1 && contactsIndex == 0))
|| (db.getOptionsIntData(Commons.MessageSpamFilter) > 0 && mSpamCharacter
.isSpamMessage(body))) {
Commons.PDATA tempData = new Commons.PDATA();
tempData.mStringValue_1 = contactsIndex > 0 ? getNameFromContacts(contactsIndex)
: "";
tempData.mStringValue_2 = phone;
tempData.mStringValue_3 = body;
tempData.mIntValue_1 = Commons.LOG_SPAM_MESSAGE;
tempData.mIntValue_2 = Commons.LOG_SPAM_MESSAGE;
tempData.mIntValue_3 = 0;
tempData.mDate = date;
db.AddData(imiSql.DATABASE_TABLE_USERLOG, tempData);
if (type == 1) {
setNotifyType(Commons.NEW_SPAM_MESSAGE_NOTIFY);
}
return true;
}
}
}
return false;
}
整个项目58个文件,源码简单易懂,它可直接移植我们的应用程序中,我们也可以开发一款类似360安全卫士的app了!~