Android操作系统并没有提供任务管理程序,无从得知后台有哪些程序正在运行,但提供了正在运行的服务列表。这次我们来用MonoDroid来获取手机中正在运行的程序及服务,用ListView列出来,点击ListView的项可以实现关闭程序或服务。
这里我没有实现实时获取,而是通过点击两个按钮时才进行获取,布局文件如下:
- <?xml version="1.0" encoding="utf-8"?>
- <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent">
- <Button android:id="@+id/btnGetTask"
- android:text="正在运行的程序"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"/>
- <Button android:id="@+id/btnGetService"
- android:text="正在运行的服务"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/btnGetTask"/>
- <ListView android:id="@+id/lvTasks"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- android:layout_below="@id/btnGetTask"></ListView>
- </RelativeLayout>
要获取正在运行的程序,需使用ActivityManager类的GetRunningTasks方法,它的参数指定需要取出的任务数,由于资源有限,所以我们这里设置了最多取出30条任务:
- public class Activity1 : Activity
- {
- List<string> list = new List<string>();
- IList<ActivityManager.RunningTaskInfo> listRunningTasks;
- ActivityManager am;
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
- SetContentView(Resource.Layout.Main);
- Button btnGetTask = FindViewById<Button>(Resource.Id.btnGetTask);
- Button btnGetService = FindViewById<Button>(Resource.Id.btnGetService);
- ListView lvTasks = FindViewById<ListView>(Resource.Id.lvTasks);
- am = this.GetSystemService(ActivityService) as ActivityManager;
- btnGetTask.Click += (sender, e) =>
- {
- contentShown = 1;
- try
- {
- list.Clear();
- lvTasks.Adapter = null;
- listRunningTasks = am.GetRunningTasks(30);
- int index = 1;
- foreach (ActivityManager.RunningTaskInfo task in listRunningTasks)
- {
- list.Add(string.Format("{0}:{1}(ID={2})", index++, task.BaseActivity.ClassName, task.Id));
- }
- ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, list);
- if (adapter.Count == 0)
- {
- Toast.MakeText(this, "当前没有任何程序运行", ToastLength.Long).Show();
- }
- else
- {
- lvTasks.Adapter = adapter;
- }
- }
- catch (SecurityException)
- {
- Toast.MakeText(this, "没有获取运行程序的权限", ToastLength.Long).Show();
- }
- catch (System.Exception ex)
- {
- MessageBox.ShowErrorMessage(this, ex);
- }
- };
- lvTasks.ItemClick += (sender, e) =>
- {
- MessageBox.Confirm(this, "提示", "确定关闭此程序吗?", (s2, e2) =>
- {
- am.RestartPackage(listRunningTasks[e.Position].BaseActivity.PackageName);
- btnGetTask.PerformClick();
- }, (s3, e3) => { });
- };
- }
- }
注意要获取任务,必需要在AndroidManifest.xml中添加GET_Tasks权限,而要关闭程序,我们这里使用的是ActivityManager类的RestartPackage方法,根据程序的包名称来关闭,所以要添加RESTART_PACKAGES权限:
- <uses-permission android:name="android.permission.GET_TASKS" />
- <uses-permission android:name="android.permission.RESTART_PACKAGES" />
效果图:
下面我们来实现获取运行中服务的效果。获取服务与获取程序差不多,只要把GetRunningTasks改为GetRunningServices即可,同样我们还是取出30条。由于是在同一个ListView中显示,在单击列表项时需要区分单击的是程序还是服务,所以我们增加一个字段contentShown加以区分,contentShown=1时表示程序,contentShown=2时表示服务,完整的代码如下:
- public class Activity1 : Activity
- {
- List<string> list = new List<string>();
- IList<ActivityManager.RunningTaskInfo> listRunningTasks;
- IList<ActivityManager.RunningServiceInfo> listRunningServices;
- ActivityManager am;
- int contentShown = 0;
- protected override void OnCreate(Bundle bundle)
- {
- base.OnCreate(bundle);
- SetContentView(Resource.Layout.Main);
- Button btnGetTask = FindViewById<Button>(Resource.Id.btnGetTask);
- Button btnGetService = FindViewById<Button>(Resource.Id.btnGetService);
- ListView lvTasks = FindViewById<ListView>(Resource.Id.lvTasks);
- am = this.GetSystemService(ActivityService) as ActivityManager;
- btnGetTask.Click += (sender, e) =>
- {
- contentShown = 1;
- try
- {
- list.Clear();
- lvTasks.Adapter = null;
- listRunningTasks = am.GetRunningTasks(30);
- int index = 1;
- foreach (ActivityManager.RunningTaskInfo task in listRunningTasks)
- {
- list.Add(string.Format("{0}:{1}(ID={2})", index++, task.BaseActivity.ClassName, task.Id));
- }
- ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, list);
- if (adapter.Count == 0)
- {
- Toast.MakeText(this, "当前没有任何程序运行", ToastLength.Long).Show();
- }
- else
- {
- lvTasks.Adapter = adapter;
- }
- }
- catch (SecurityException)
- {
- Toast.MakeText(this, "没有获取运行程序的权限", ToastLength.Long).Show();
- }
- catch (System.Exception ex)
- {
- MessageBox.ShowErrorMessage(this, ex);
- }
- };
- btnGetService.Click += (sender, e) =>
- {
- contentShown = 2;
- try
- {
- lvTasks.Adapter = null;
- listRunningServices = am.GetRunningServices(30);
- int index = 1;
- list.Clear();
- foreach (ActivityManager.RunningServiceInfo service in listRunningServices)
- {
- list.Add(string.Format("{0}:{1}(ID={2})", index++, service.Process, service.Pid));
- }
- ArrayAdapter<string> adapter = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, list);
- if (adapter.Count == 0)
- {
- Toast.MakeText(this, "当前没有任何服务运行", ToastLength.Long).Show();
- }
- else
- {
- lvTasks.Adapter = adapter;
- }
- }
- catch (SecurityException)
- {
- Toast.MakeText(this, "没有获取运行服务的权限", ToastLength.Long).Show();
- }
- catch (System.Exception ex)
- {
- MessageBox.ShowErrorMessage(this, ex);
- }
- };
- lvTasks.ItemClick += (sender, e) =>
- {
- if (contentShown == 1)
- {
- MessageBox.Confirm(this, "提示", "确定关闭此程序吗?", (s2, e2) =>
- {
- am.RestartPackage(listRunningTasks[e.Position].BaseActivity.PackageName);
- btnGetTask.PerformClick();
- }, (s3, e3) => { });
- }
- else if (contentShown == 2)
- {
- MessageBox.Confirm(this, "提示", "确定关闭此服务吗?", (s2, e2) =>
- {
- am.RestartPackage(listRunningServices[e.Position].Service.PackageName);
- btnGetService.PerformClick();
- }, (s3, e3) => { });
- }
- };
- }
- }