Android项目实战--手机卫士31--注册广播事件自动杀死进程

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u011485531/article/details/12958275



最新实战教程,让你了解Android自动化刷量、作弊与防作弊的那些事,案例:刷友盟统计、批量注册苹果帐号




昨天,我们就完成了对应用权限列表的读取,而且还修复了一些小bug,那么今天我们要完成的就是我们的进程设置那一块啦,这里我们做得比较简单,就只是完成两个设置而已

一个就是是否显示系统进程,第二个就是是否在锁屏的时候进行清理一些进程,大家完全可以做得更完善一些的,比如说添加一个进程的白名单啦,这样子,我们一些常用的就用的进程就不会被杀死啊,这类的功能,因为这些都比较容易,所以我就不写了,大家有兴趣的可以完善一下,那么我们现在就来看一下我们今天要做的效果


上面的那一张就是我们的进程设置里面的界面啦,就只有简单的两个设置,我们今天就来完成一下它


对于这些设置信息,我把它保存到我们的SharedPreferences里面的,这样子,下次用户进来,就会先读取原来的信息的


首先,我们就先把界面做一下,这个界面非常的简单,我就不把布局文件粘出来啦,

com.xiaobin.security.ui.ProcessSettingActivity

package com.xiaobin.security.ui;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.Window;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

import com.xiaobin.security.R;

public class ProcessSettingActivity extends Activity
{
	private TextView tv_process_setting_tips;
	private CheckBox cb_process_setting_state;
	private TextView tv_process_clean_tips;
	private CheckBox cb_process_clean_state;
	private SharedPreferences sp;

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.process_setting);

		sp = getSharedPreferences("config", Context.MODE_PRIVATE);
		boolean showSystemProcess = sp.getBoolean("showSystemProcess", false);

		tv_process_setting_tips = (TextView) findViewById(R.id.tv_process_setting_tips);
		cb_process_setting_state = (CheckBox) findViewById(R.id.cb_process_setting_state);
		if (showSystemProcess)
		{
			tv_process_setting_tips.setText("显示系统进程");
			cb_process_setting_state.setChecked(true);
		}
		else
		{
			tv_process_setting_tips.setText("不显示系统进程");
			cb_process_setting_state.setChecked(false);
		}
		cb_process_setting_state
				.setOnCheckedChangeListener(new OnCheckedChangeListener()
				{
					@Override
					public void onCheckedChanged(CompoundButton buttonView,
							boolean isChecked)
					{
						if (isChecked)
						{
							tv_process_setting_tips.setText("显示系统进程");
							Editor editor = sp.edit();
							editor.putBoolean("showSystemProcess", true);
							editor.commit();
							// 与前面的ProcessManagerActivity里面的那个resultCode相对应
							setResult(200);
						}
						else
						{
							tv_process_setting_tips.setText("不显示系统进程");
							Editor editor = sp.edit();
							editor.putBoolean("showSystemProcess", false);
							editor.commit();
							// 与前面的ProcessManagerActivity里面的那个resultCode相对应
							setResult(200);
						}
					}
				});
		
		tv_process_clean_tips = (TextView) findViewById(R.id.tv_process_clean_tips);
		cb_process_clean_state = (CheckBox) findViewById(R.id.cb_process_clean_state);
		boolean killProcess = sp.getBoolean("killProcess", false);
		if (killProcess)
		{
			tv_process_clean_tips.setText("锁屏清理内存");
			cb_process_clean_state.setChecked(true);
		}
		else
		{
			tv_process_clean_tips.setText("锁屏不清理内存");
			cb_process_clean_state.setChecked(false);
		}
		cb_process_clean_state.setOnCheckedChangeListener(new OnCheckedChangeListener()
		{
			@Override
			public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
			{
				if(isChecked)
				{
					tv_process_clean_tips.setText("锁屏清理内存");
					Editor editor = sp.edit();
					editor.putBoolean("killProcess", true);
					editor.commit();
				}
				else
				{
					tv_process_clean_tips.setText("锁屏不清理内存");
					Editor editor = sp.edit();
					editor.putBoolean("killProcess", false);
					editor.commit();
				}
			}
		});
	}

}

上面都是一些很简单的逻辑操作啦,我就不多说啦

那么,这个activity写好之后,我们就要启动它啦,因为我们第一个设置就是,显不显示系统的进程嘛,那么,如果我选了显示,那我们就要刷新界面的啦,

所以我们就要有一个标记才行,让我们的应用知道什么时候要刷新界面啦,所以我们使用了startActivityForResult这个方法,来启动这个activity

			case R.id.bt_process_setting:
				Intent intent = new Intent(this, ProcessSettingActivity.class);
				startActivityForResult(intent, 0);
				break;

然后重写onActivityResult方法

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		//刷新数据
		if(resultCode == 200)
		{
			initData();
		}
	}

大家可以看到,当我们的resultCode返回的是200的时候,我们才会刷新数据,那么我们就要在ProcessSettingActivity里面设置一下啦,大家在上面都可以看到的,当我们的CheckBox的状态改变了,我们的resultCode就没设置为200的啦,这样子,我们就可以进行数据的刷新啦。

但是这样还是不行的,我们还要修改一下我们的Adapter才行的

对于显示系统进程,那很简单啦,就是我们原来的样子,但是只显示用户进程,那就要修改一下啦,其实也很简单啦,就是在getCount那里改变一下那个值就可以的啦

		@Override
		public int getCount()
		{
			boolean showSystemProcess = sp.getBoolean("showSystemProcess", false);
			if(showSystemProcess)
			{
				// 加上两个标签,一个是系统标签,一个是用户标签
				return taskInfos.size() + 2;
			}
			else
			{
				return userTaskInfos.size() + 1;
			}
		}

因为我们之前写的时候,就已经对各种情况判断好的啦,所以就修改一下这里就可以的啦,是不是要显示系统进程,是从SharedPreferences里面读取的


就 这样子,我们的第一个设置就完成的啦,那么接下来,我们不完成我们的第二个设置啦,那就是当用户锁屏的时候,是否要进行进程的清理

其实这个也很简单啦,就是注册一个广播接收者,接收锁屏的广播,当收到广播之后,我们就进行一系列的处理啦

com.xiaobin.security.receiver.LockScreenReceive

package com.xiaobin.security.receiver;

import com.xiaobin.security.utils.ProcessUtil;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.util.Log;

public class LockScreenReceiver extends BroadcastReceiver
{
	private static final String TAG = "LockScreenReceiver";

	@Override
	public void onReceive(Context context, Intent intent)
	{
		Log.i(TAG, "已经锁屏了");
		SharedPreferences sp = context.getSharedPreferences("config",
				Context.MODE_PRIVATE);
		boolean killProcess = sp.getBoolean("killProcess", false);
		if (killProcess)
		{
			Log.i(TAG, "开始清理内存");
			ProcessUtil.killAllProcess(context);
		}
	}

}

我们把清理进程写在一个util类里面啦,这样方便我们使用

com.xiaobin.security.utils.ProcessUtil

package com.xiaobin.security.utils;

import java.util.List;

import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;

public class ProcessUtil
{
	public static void killAllProcess(Context context)
	{
		//拿到这个包管理器
		ActivityManager activityManager = (ActivityManager) context
				.getSystemService(Context.ACTIVITY_SERVICE);
		//拿到所有正在运行的进程信息
		List<RunningAppProcessInfo> list = activityManager
				.getRunningAppProcesses();
		//进行遍历,然后杀死它们
		for (RunningAppProcessInfo runningAppProcessInfo : list)
		{
			activityManager
					.killBackgroundProcesses(runningAppProcessInfo.processName);
		}
	}

}

好啦,这样子,我们的广播接收者就写好的啦,现在我们就在AndroidMainfest里面注册它啦

        <receiver 
            android:name="com.xiaobin.security.receiver.LockScreenReceive">
            <intent-filter android:priority="1000">
                <action android:name="android.intent.action.SCREEN_OFF"/>
            </intent-filter>
        </receiver>

就这样子,我们的广播接收者就写好的啦


注意,因为我用的是模拟器来测试的,不知道为什么,在我的模拟器里面,通过AndroidMainfest里面注册不上锁屏这个广播接收者的

所以我就在代码里面自己写了,也当温习一下,怎样用代码注册广播接收者

我在自己昨天自己写的MyApplication类里面,重写它的onCreate方法,然后在里面注册广播接收者

	@Override
	public void onCreate()
	{
		super.onCreate();
		
		IntentFilter intentFilter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
		intentFilter.setPriority(1000);
		LockScreenReceiver receiver = new LockScreenReceiver();
		registerReceiver(receiver, intentFilter);
	}

就这样子,我们就可以把一个锁屏的广播接收者给注册成功的啦


好啦,今天就讲到这里的了,今天的内容比较容易,下面我把完整的activity粘出来

com.xiaobin.security.ui.ProcessManagerActivity

package com.xiaobin.security.ui;

import java.util.ArrayList;
import java.util.List;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.MemoryInfo;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.xiaobin.security.MyApplication;
import com.xiaobin.security.R;
import com.xiaobin.security.domain.TaskInfo;
import com.xiaobin.security.engine.TaskInfoProvider;
import com.xiaobin.security.ui.view.MyToast;
import com.xiaobin.security.utils.TextFormater;

public class ProcessManagerActivity extends Activity implements OnClickListener
{
	private static final int LOAD_FINISH = 1;

	private TextView tv_process_count;
	private TextView tv_process_memory;

	private LinearLayout ll_process_load;
	private ListView lv_process_list;
	private Button bt_process_clear;
	private Button bt_process_setting;
	private CheckBox cb_process_state;

	private ActivityManager activityManager;
	private List<RunningAppProcessInfo> runningAppProcessInfos;
	private TaskInfoProvider taskInfoProvider;
	private List<TaskInfo> taskInfos;
	private TaskInfoAdapter adapter;
	private List<TaskInfo> userTaskInfos;
	private List<TaskInfo> systemTaskInfos;
	private String totalMemory;
	private String availMemory;
	
	private SharedPreferences sp;

	@SuppressLint("HandlerLeak")
	private Handler handler = new Handler()
	{
		public void handleMessage(Message msg)
		{
			switch (msg.what)
			{
				case LOAD_FINISH:
					ll_process_load.setVisibility(View.INVISIBLE);
					adapter = new TaskInfoAdapter();
					lv_process_list.setAdapter(adapter);
					tv_process_memory.setText(availMemory + "/" + totalMemory);
					break;

				default:
					break;
			}
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		
		sp = getSharedPreferences("config", Context.MODE_PRIVATE);

		activityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

		// 请求一个自己定义的title,但有一些Android系统是被修改过的,
		// 所以有可能是无法请求的,如乐Phone或小米的手机,这些系统是被修改过的,
		// 所以就要判断一下是否请求成功
		boolean flags = requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);

		setContentView(R.layout.process_manager);

		if (flags)
		{
			// 设置自定义的title
			getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
					R.layout.process_manager_title);
		}

		tv_process_count = (TextView) findViewById(R.id.tv_process_count);
		tv_process_memory = (TextView) findViewById(R.id.tv_process_memory);

		ll_process_load = (LinearLayout) findViewById(R.id.ll_process_load);
		lv_process_list = (ListView) findViewById(R.id.lv_process_list);
		bt_process_clear = (Button) findViewById(R.id.bt_process_clear);
		bt_process_setting = (Button) findViewById(R.id.bt_process_setting);
		bt_process_clear.setOnClickListener(this);
		bt_process_setting.setOnClickListener(this);

		initData();

		lv_process_list.setOnItemClickListener(new OnItemClickListener()
		{
			@Override
			public void onItemClick(AdapterView<?> parent, View view,
					int position, long id)
			{
				// adapter里面的getItem返回的值
				Object obj = lv_process_list.getItemAtPosition(position);
				if (obj instanceof TaskInfo)
				{
					cb_process_state = (CheckBox) view
							.findViewById(R.id.cb_process_manager_state);
					TaskInfo taskInfo = (TaskInfo) obj;

					// 设置成不能杀死自己的进程,还有一些系统进程
					if ("com.xiaobin.security".equals(taskInfo.getPackageName())
							|| "system".equals(taskInfo.getPackageName())
							|| "android.process.media".equals(taskInfo
									.getPackageName()))
					{
						cb_process_state.setVisibility(View.INVISIBLE);
						return;
					}
					if (taskInfo.isCheck())
					{
						taskInfo.setCheck(false);
						cb_process_state.setChecked(false);
					}
					else
					{
						taskInfo.setCheck(true);
						cb_process_state.setChecked(true);
					}
				}
			}
		});
		
		lv_process_list.setOnItemLongClickListener(new OnItemLongClickListener()
		{
			@Override
			public boolean onItemLongClick(AdapterView<?> parent, View view,
					int position, long id)
			{
				// adapter里面的getItem返回的值
				Object obj = lv_process_list.getItemAtPosition(position);
				if (obj instanceof TaskInfo)
				{
					TaskInfo taskInfo = (TaskInfo) obj;
					
					//拿到我们自己定义的application对象
					MyApplication myApplication = (MyApplication) getApplication();
					//把TaskInfo对象设置进去
					myApplication.setTaskInfo(taskInfo);
					
					Intent intent = new Intent(ProcessManagerActivity.this, AppDetialActivity.class);
					startActivity(intent);
				}
				return false;
			}
		});
	}

	@Override
	public void onClick(View v)
	{
		switch (v.getId())
		{
			case R.id.bt_process_clear:
				killTask();
				break;

			case R.id.bt_process_setting:
				Intent intent = new Intent(this, ProcessSettingActivity.class);
				startActivityForResult(intent, 0);
				break;

			default:
				break;
		}
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data)
	{
		super.onActivityResult(requestCode, resultCode, data);
		//刷新数据
		if(resultCode == 200)
		{
			initData();
		}
	}

	private void initData()
	{
		// 因为这个title是要显示当前进程数目和可用内存的,所以我们每次在这里都调用一下,以更新数据
		initTitle();
		ll_process_load.setVisibility(View.VISIBLE);
		new Thread(new Runnable()
		{
			@Override
			public void run()
			{
				taskInfoProvider = new TaskInfoProvider(
						ProcessManagerActivity.this);
				taskInfos = taskInfoProvider.getAllTask(runningAppProcessInfos);

				// 计算总内存大小,因为不可以直接获取到总内存的,所以只能计算
				// 计算方法就是,全部进程占用的内存,再加上可用的内存,但这样计算是不准确的
				long total = 0;
				for (TaskInfo taskInfo : taskInfos)
				{
					total += taskInfo.getMemory();
				}

				// new一个内存的对象
				MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
				// 拿到现在系统里面的内存信息
				activityManager.getMemoryInfo(memoryInfo);
				// 拿到有效的内存空间
				long size = memoryInfo.availMem;

				// 因为我们拿到的进程占用的内存是以KB为单位的,所以这里要乘以1024,也就是左移10位啦
				total = total << 10;
				// 加上可用的内存,就可以得到总内存啦
				total += size;

				totalMemory = TextFormater.dataSizeFormat(total);

				Message msg = new Message();
				msg.what = LOAD_FINISH;
				handler.sendMessage(msg);
			}
		}).start();
	}

	// 拿到当前运行的进程数目
	private int getRunningAppCount()
	{
		runningAppProcessInfos = activityManager.getRunningAppProcesses();
		return runningAppProcessInfos.size();
	}

	// 拿到系统剩余的内存
	private String getAvailMemory()
	{
		// new一个内存的对象
		MemoryInfo memoryInfo = new ActivityManager.MemoryInfo();
		// 拿到现在系统里面的内存信息
		activityManager.getMemoryInfo(memoryInfo);
		// 拿到有效的内存空间
		long size = memoryInfo.availMem;
		return TextFormater.dataSizeFormat(size);
	}

	// 设置title的信息
	private void initTitle()
	{
		availMemory = getAvailMemory();
		tv_process_count.setText("进程数目:" + getRunningAppCount());
		tv_process_memory.setText("剩余内存:" + availMemory);
	}

	// 一键清理的函数
	private void killTask()
	{
		int total = 0;
		int memorySize = 0;
		for (TaskInfo taskInfo : systemTaskInfos)
		{
			if (taskInfo.isCheck())
			{
				// 杀死进程
				activityManager.killBackgroundProcesses(taskInfo
						.getPackageName());
				total++;
				memorySize += taskInfo.getMemory();
				taskInfos.remove(taskInfo);
			}
		}

		for (TaskInfo taskInfo : userTaskInfos)
		{
			if (taskInfo.isCheck())
			{
				activityManager.killBackgroundProcesses(taskInfo
						.getPackageName());
				total++;
				memorySize += taskInfo.getMemory();
				taskInfos.remove(taskInfo);
			}
		}

		/*
		 * Toast.makeText( this, "已经杀死了" + total + "个进程!释放了" +
		 * TextFormater.getSizeFromKB(memorySize) + "空间",
		 * Toast.LENGTH_SHORT).show();
		 */

		// 显示成我们自己定义的Toast
		MyToast.showToast(this, R.drawable.notification, "已经杀死了" + total
				+ "个进程!释放了" + TextFormater.getSizeFromKB(memorySize) + "空间");

		// 重新加载界面
		adapter = new TaskInfoAdapter();
		lv_process_list.setAdapter(adapter);
	}

	// ===========================================================================

	private class TaskInfoAdapter extends BaseAdapter
	{

		public TaskInfoAdapter()
		{
			// 存放用户的应用进程
			userTaskInfos = new ArrayList<TaskInfo>();
			// 存放系统的应用进程
			systemTaskInfos = new ArrayList<TaskInfo>();

			for (TaskInfo taskInfo : taskInfos)
			{
				if (taskInfo.isSystemProcess())
				{
					systemTaskInfos.add(taskInfo);
				}
				else
				{
					userTaskInfos.add(taskInfo);
				}
			}
		}

		@Override
		public int getCount()
		{
			boolean showSystemProcess = sp.getBoolean("showSystemProcess", false);
			if(showSystemProcess)
			{
				// 加上两个标签,一个是系统标签,一个是用户标签
				return taskInfos.size() + 2;
			}
			else
			{
				return userTaskInfos.size() + 1;
			}
		}

		@Override
		public Object getItem(int position)
		{
			if (position == 0)
			{
				return 0; // 显示成用户应用的标签
			}
			else if (position <= userTaskInfos.size())
			{
				return userTaskInfos.get(position - 1); // 用户应用进程的条目
			}
			else if (position == userTaskInfos.size() + 1)
			{
				return position; // 显示成系统进程的标签
			}
			else if (position <= taskInfos.size() + 2)
			{
				// 系统应用进程的条目
				return systemTaskInfos.get(position - userTaskInfos.size() - 2);
			}
			else
			{
				return position;
			}
		}

		@Override
		public long getItemId(int position)
		{
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent)
		{
			View view;
			TaskInfoViews views;
			TaskInfo taskInfo;
			if (position == 0)
			{
				// 显示成用户应用的标签
				return newTextView("用户进程(" + userTaskInfos.size() + ")");
			}
			else if (position <= userTaskInfos.size())
			{
				// 用户应用进程的条目
				taskInfo = userTaskInfos.get(position - 1);
			}
			else if (position == userTaskInfos.size() + 1)
			{
				// 显示成系统进程的标签
				return newTextView("系统进程(" + systemTaskInfos.size() + ")");
			}
			else if (position <= taskInfos.size() + 2)
			{
				// 系统应用进程的条目
				taskInfo = systemTaskInfos.get(position - userTaskInfos.size()
						- 2);
			}
			else
			{
				taskInfo = new TaskInfo();
			}
			if (convertView == null || convertView instanceof TextView)
			{
				view = View.inflate(ProcessManagerActivity.this,
						R.layout.process_manager_item, null);

				views = new TaskInfoViews();
				views.iv_process_icon = (ImageView) view
						.findViewById(R.id.iv_process_manager_icon);
				views.tv_process_name = (TextView) view
						.findViewById(R.id.tv_process_manager_name);
				views.tv_process_memory = (TextView) view
						.findViewById(R.id.tv_process_manager_memory);
				views.cb_process_state = (CheckBox) view
						.findViewById(R.id.cb_process_manager_state);
				view.setTag(views);
			}
			else
			{
				view = convertView;
				views = (TaskInfoViews) view.getTag();
			}
			views.iv_process_icon.setImageDrawable(taskInfo.getIcon());
			views.tv_process_name.setText(taskInfo.getName());
			views.tv_process_memory.setText("占用内存:"
					+ TextFormater.getSizeFromKB(taskInfo.getMemory()));

			// 设置成不能杀死自己的进程,还有一些系统进程
			if ("com.xiaobin.security".equals(taskInfo.getPackageName())
					|| "system".equals(taskInfo.getPackageName())
					|| "android.process.media"
							.equals(taskInfo.getPackageName()))
			{
				views.cb_process_state.setVisibility(View.INVISIBLE);
			}
			else
			{
				views.cb_process_state.setVisibility(View.VISIBLE);
			}
			views.cb_process_state.setChecked(taskInfo.isCheck());
			return view;
		}

		private TextView newTextView(String title)
		{
			TextView tv_title = new TextView(ProcessManagerActivity.this);
			tv_title.setText(title);
			return tv_title;
		}

	}

	private class TaskInfoViews
	{
		ImageView iv_process_icon;
		TextView tv_process_name;
		TextView tv_process_memory;
		CheckBox cb_process_state;
	}

}



最后,和大家说一下

为了方便大家的交流,我创建了一个群,这样子大家有什么疑问也可以在群上交流

群号是298440981



今天源码下载


猜你喜欢

转载自blog.csdn.net/u011485531/article/details/12958275