Android任务管理器

本文介绍如何基于Android系统源代码创建一个任务管理器,包括获取任务列表、活动图标、Activity缩略图以及恢复和关闭任务的功能。需要系统级权限,并提供了在4.4.2和5.1.1系统上的实现示例代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

最近参考系统源代码,做了一个任务管理器。具体功能是获取用户的任务列表、活动图标、Activity的缩略图以及恢复任务、关闭任务。

完整的demo已上传到github,代码拙劣,将就看看:https://github.com/Ade8018/TaskManager

首先声明,任务管理器基本上的功能都会要求系统级权限。即你手中需要有系统签名文件。

以下代码在4.4.2及5.1.1系统上亲测可用。


一、获取任务列表

获取任务列表需要系统使用系统UIDandroid:sharedUserId="android.uid.system"及添加权限<uses-permission android:name="android.permission.GET_TASKS" />

然后调用ActivityManager的getRecentTasks(MAX_TASK_COUNT,ActivityManager.RECENT_IGNORE_UNAVAILABLE)方法可以获取到任务列表。

示例:

	public TaskList(ActivityManager am, PackageManager pm) {
		if (am == null || pm == null)
			throw new NullPointerException();
		mAm = am;
		mPm = pm;
		mInfos = am.getRecentTasks(MAX_TASK_COUNT,
				ActivityManager.RECENT_IGNORE_UNAVAILABLE);
		dofilter();
	}


二、获取活动图标

ActivityInfo类中有个loadIcon方法可以获取图标。而通过PackageManager中则有getActivityInfo可以根据组件名获取ActivityInfo。RecentTask中baseIntent.getComponent()可以获取到组件名。这样我们就可以根据任务列表获取活动的图标。

示例:

<span style="white-space:pre">	</span>public ComponentName getBaseActivityByIndex(int index) {
		return mInfos.get(index).baseIntent.getComponent();
	}

	public Drawable getIconDrawable(int index) {
		ComponentName cn = getBaseActivityByIndex(index);
		try {
			return mPm.getActivityInfo(cn, PackageManager.GET_INTENT_FILTERS)
					.loadIcon(mPm);
		} catch (NameNotFoundException e) {
			return null;
		}
	}

三、获取Activity缩略图

此功能需要权限:<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />

4.4.2版本与5.1.1版本的获取方法不同。分别如下:

4.4.2:

<span style="white-space:pre">	</span>public static Bitmap getTaskTopThumbnail(Context context,int persistentTaskId) {
		try {
			Method method_getTaskTopThumbnail = ActivityManager.class
					.getDeclaredMethod("getTaskTopThumbnail", int.class);
			method_getTaskTopThumbnail.setAccessible(true);
			return (Bitmap) method_getTaskTopThumbnail.invoke(
					context.getSystemService(Context.ACTIVITY_SERVICE),
					persistentTaskId);
		} catch (NoSuchMethodException | IllegalAccessException
				| IllegalArgumentException | InvocationTargetException e) {
			e.printStackTrace();
		}
		return null;
	}
5.1.1:

<span style="white-space:pre">	</span>public static Bitmap getThumbnail(ActivityManager activityManager,int persistentTaskId) {
		Bitmap thumbnail = null;
		try {
			Class cls_TaskThumbnail = Class
					.forName("android.app.ActivityManager$TaskThumbnail");
			Method m_getTaskThumbnail = ActivityManager.class
					.getDeclaredMethod("getTaskThumbnail", int.class);
			m_getTaskThumbnail.setAccessible(true);
			Object obj_TaskThumbnail = m_getTaskThumbnail.invoke(
					activityManager, persistentTaskId);
			if (obj_TaskThumbnail == null)
				return null;
			Field f_mainThumbnail = cls_TaskThumbnail.getField("mainThumbnail");
			Field f_thumbnailFileDescriptor = cls_TaskThumbnail
					.getField("thumbnailFileDescriptor");
			thumbnail = (Bitmap) f_mainThumbnail.get(obj_TaskThumbnail);
			ParcelFileDescriptor descriptor = (ParcelFileDescriptor) f_thumbnailFileDescriptor
					.get(obj_TaskThumbnail);
			if (thumbnail == null && descriptor != null) {
				thumbnail = BitmapFactory.decodeFileDescriptor(
						descriptor.getFileDescriptor(), null, sBitmapOptions);
			}
			if (descriptor != null) {
				try {
					descriptor.close();
				} catch (IOException e) {
				}
			}
		} catch (Exception e) {
		}
		return thumbnail;
	}
两个方法中需要的persistentTaskId参数都是RecentTask类中的属性persistentTaskId。


四、移除任务(移除后就不能再在任务列表中获取到这个活动)

此功能需要权限:<uses-permission android:name="android.permission.REMOVE_TASKS" />

4.4.2:

<span style="white-space:pre">	</span>public static boolean removeTask(ActivityManager am, int taskId, int flags) {
		try {
			Method method_removeTask = ActivityManager.class.getDeclaredMethod(
					"removeTask", int.class, int.class);
			method_removeTask.setAccessible(true);
			return (boolean) method_removeTask.invoke(am, taskId, flags);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
5.1.1:

<span style="white-space:pre">	</span>public static boolean removeTask(ActivityManager am, int taskId) {
		try {
			Method method_removeTask = ActivityManager.class.getDeclaredMethod(
					"removeTask", int.class);
			method_removeTask.setAccessible(true);
			return (boolean) method_removeTask.invoke(am, taskId);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return false;
	}
以上两个方法中的taskId都是RecentTask类中的属性--id。


五、恢复任务

此功能需要权限:<uses-permission android:name="android.permission.REORDER_TASKS" />

参考源码得知,系统采用的方法是:如果该任务还没别杀掉,则恢复该任务即将该任务从后台移动到前台。如果该任务已经被杀掉了,就重新启动该任务。当该任务的id<=0的时候表示该任务已经被傻掉了。方法如下:

<span style="white-space:pre">	</span>public void resumeTask(Context context, int position) {
		if (mInfos.get(position).id > 0) {
			mAm.moveTaskToFront(getPersistentIdByIndex(position), 0);
		} else {
			Intent intent = mInfos.get(position).baseIntent;
			intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY
					| Intent.FLAG_ACTIVITY_TASK_ON_HOME
					| Intent.FLAG_ACTIVITY_NEW_TASK);
			try {
				context.startActivity(intent);
			} catch (Exception e) {
			}
		}
	}



评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

番茄大圣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值