关于packagemanager和activitymanager的使用 ,自己也写了一些demo 了,基本上写的线路参考了settings模块下的
应用程序,大家如果真正的有所兴趣,建议大家看看源码,不过丑化说在前面,我自己也没怎么看过这方面的源码,只在
需要的时候,才跑过去翻翻。
今天,在耐着最后一点性子,写下了这篇博文,基本上完成了整个应用程序功能模块的介绍,大家也在此系列上慢慢拓展。
activitymanager.runningserviceinfo类: 封装了正在运行的服务信息
获取系统里所有真正运行的服务是通过调用activitymanager方法来得到的,具体方法如下:
list<activitymanager.runningserviceinfo> getrunningservices (int
maxnum)
功能:返回所有正在运行的服务
参数: maxnum 代表我们希望返回的服务数目大小,一般给个稍大的值即可, 例如,50 。
常用字段:
long activesince 服务第一次被激活的时间, 包括启动和绑定方式
int clientcount 如果该service是通过bind方法方式连接,则clientcount代表了service连接客户端的数目
int crashcount 服务运行期间,出现死机的次数
boolean foreground 若为true,则该服务在后台执行
int pid 如果不为0,表示该service所在的进程id号( ps:为0的话我也不清楚 - - 求指点)
int uid 用户id 类似于linux的用户权限,例如root等
string process 进程名,默认是包名或者由属性android:process指定
componentname service 获得该service的组件信息 包含了pkgname / servicename信息
说明: 封装了对应用程序信息的操作
获得应用程序信息的的方法如下:
public abstractapplicationinfo getapplicationinfo(string
packagename, int flags)
参数:packagename 包名
flags 该applicationinfo是此flags标记,通常可以直接赋予常数0即可
功能:返回applicationinfo对象
关于packagemanger更多信息,请查看<android中获取应用程序(包)的信息-----packagemanager的使用(一)>
task任务的使用,我也就不在赘述了,大家可以仔细看下sdk,在此推荐一篇博客来帮助大家理解。
《android系统的进程,任务,服务的信息》
demo说明:
我们获取了系统里正在运行的服务信息,包括包名,图标,service类名等。为了达到settings下应用程序模块中的
正在运行服务的效果,我们点击某一服务后,理论上来说是可以停止该服务的,但是由于权限permissions不够,可能报
securityexception异常,导致应用程序发生异常。
关于权限不够的问题,可以分为两种:
1、 在androidmanifest.xml文件中,为<activity/>或<service/>节点指定android:permission属性时,在其他进程中操作时,
需要 声明该permission权限 。 具体可以参考下面这篇文章:
《android 自定义权限 permission》
2、 系统权限,这个咱就没什么话说了。 可以参考下面这篇文章。
《android.uid.system 获取系统权限
》
截图如下:(加上了水印,请谅解)
老规矩,资源文件不在贴了。 主工程逻辑如下:
[java] view
plaincopyprint?
package com.qin.runservice;
import java.util.arraylist;
import java.util.collections;
import java.util.comparator;
import java.util.list;
import android.app.activity;
import android.app.activitymanager;
import android.app.alertdialog;
import android.app.dialog;
import android.content.componentname;
import android.content.context;
import android.content.dialoginterface;
import android.content.intent;
import android.content.pm.applicationinfo;
import android.content.pm.packagemanager;
import android.content.pm.packagemanager.namenotfoundexception;
import android.os.bundle;
import android.os.debug;
import android.util.log;
import android.view.contextmenu;
import android.view.menu;
import android.view.menuitem;
import android.view.view;
import android.view.contextmenu.contextmenuinfo;
import android.widget.adapterview;
import android.widget.listview;
import android.widget.textview;
import android.widget.adapterview.onitemclicklistener;
public class browserunningserviceactivity extends activity implements
onitemclicklistener {
private static string tag = "runserviceinfo";
private activitymanager mactivitymanager = null;
// processinfo model类 用来保存所有进程信息
private list<runsericemodel> serviceinfolist = null;
private listview listviewservice;
private textview tvtotalserviceno;
public void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.browse_service_list);
listviewservice = (listview) findviewbyid(r.id.listviewservice);
listviewservice.setonitemclicklistener(this);
tvtotalserviceno = (textview) findviewbyid(r.id.tvtotalserviceno);
// 获得activitymanager服务的对象
mactivitymanager = (activitymanager) getsystemservice(context.activity_service);
// 获得正在运行的service信息
getrunningserviceinfo();
// 对集合排序
collections.sort(serviceinfolist, new comparatorservicelable());
system.out.println(serviceinfolist.size() + "-------------");
// 为listview构建适配器对象
browserunningserviceadapter mserviceinfoadapter = new
browserunningserviceadapter(browserunningserviceactivity.this, serviceinfolist);
listviewservice.setadapter(mserviceinfoadapter);
tvtotalserviceno.settext("当前正在运行的服务共有:" + serviceinfolist.size());
}
// 获得系统正在运行的进程信息
private void getrunningserviceinfo() {
// 设置一个默认service的数量大小
int defaultnum = 20;
// 通过调用activitymanager的getrunningappservicees()方法获得系统里所有正在运行的进程
list<activitymanager.runningserviceinfo> runservicelist = mactivitymanager
.getrunningservices(defaultnum);
system.out.println(runservicelist.size());
// serviceinfo model类 用来保存所有进程信息
serviceinfolist = new arraylist<runsericemodel>();
for (activitymanager.runningserviceinfo runserviceinfo : runservicelist) {
// 获得service所在的进程的信息
int pid = runserviceinfo.pid; // service所在的进程id号
int uid = runserviceinfo.uid; // 用户id 类似于linux的权限不同,id也就不同 比如 root等
// 进程名,默认是包名或者由属性android:process指定
string processname = runserviceinfo.process;
// 该service启动时的时间值
long activesince = runserviceinfo.activesince;
// 如果该service是通过bind方法方式连接,则clientcount代表了service连接客户端的数目
int clientcount = runserviceinfo.clientcount;
// 获得该service的组件信息 可能是pkgname/servicename
componentname servicecmp = runserviceinfo.service;
string servicename = servicecmp.getshortclassname(); // service 的类名
string pkgname = servicecmp.getpackagename(); // 包名
// 打印log
log.i(tag, "所在进程id :" + pid + " 所在进程名:" + processname + " 所在进程uid:"
+ uid + "\n" + " service启动的时间值:" + activesince
+ " 客户端绑定数目:" + clientcount + "\n" + "该service的组件信息:"
+ servicename + " and " + pkgname);
// 这儿我们通过service的组件信息,利用packagemanager获取该service所在应用程序的包名 ,图标等
packagemanager mpackagemanager = this.getpackagemanager(); // 获取packagermanager对象;
try {
// 获取该pkgname的信息
applicationinfo appinfo = mpackagemanager.getapplicationinfo(
pkgname, 0);
runsericemodel runservice = new runsericemodel();
runservice.setappicon(appinfo.loadicon(mpackagemanager));
runservice.setapplabel(appinfo.loadlabel(mpackagemanager) + "");
runservice.setservicename(servicename);
runservice.setpkgname(pkgname);
// 设置该service的组件信息
intent intent = new intent();
intent.setcomponent(servicecmp);
runservice.setintent(intent);
runservice.setpid(pid);
runservice.setprocessname(processname);
// 添加至集合中
serviceinfolist.add(runservice);
} catch (namenotfoundexception e) {
// todo auto-generated catch block
system.out.println("--------------------- error -------------");
e.printstacktrace();
}
}
// 触摸可停止
@override
public void onitemclick(adapterview<?> arg0, view arg1, int position,
long arg3) {
// todo auto-generated method stub
final intent stopserviceintent = serviceinfolist.get(position)
.getintent();
new alertdialog.builder(browserunningserviceactivity.this).settitle(
"是否停止服务").setmessage(
"服务只有在重新启动后,才可以继续运行。但这可能会给电子市场应用程序带来意想不到的结果。")
.setpositivebutton("停止", new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog, int which) {
// todo auto-generated method stub
// 停止该service
//由于权限不够的问题,为了避免应用程序出现异常,捕获该securityexception ,并弹出对话框
try {
stopservice(stopserviceintent);
} catch (securityexception sex) {
//发生异常 说明权限不够
system.out.println(" deny the permission");
new alertdialog.builder(browserunningserviceactivity.this).settitle(
"权限不够").setmessage("对不起,您的权限不够,无法停止该service").create().show();
}
// 刷新界面
// 获得正在运行的service信息
getrunningserviceinfo();
// 对集合排序
collections.sort(serviceinfolist, new comparatorservicelable());
// 为listview构建适配器对象
browserunningserviceadapter mserviceinfoadapter = new browserunningserviceadapter(
browserunningserviceactivity.this,
serviceinfolist);
listviewservice.setadapter(mserviceinfoadapter);
tvtotalserviceno.settext("当前正在运行的服务共有:"
+ serviceinfolist.size());
}
}).setnegativebutton("取消",
new dialoginterface.onclicklistener() {
@override
public void onclick(dialoginterface dialog,
int which) {
// todo auto-generated method stub
dialog.dismiss(); // 取消对话框
}
}).create().show();
// 自定义排序 根据applabel排序
private class comparatorservicelable implements comparator<runsericemodel> {
@override
public int compare(runsericemodel object1, runsericemodel object2) {
// todo auto-generated method stub
return object1.getapplabel().compareto(object2.getapplabel());
}
代码下载地址:http://download.csdn.net/detail/qinjuning/3846097
终于完成了这几块功能的介绍,这些功能的具体使用都挺类似的,最重要的是看你有没有耐心去把他们做出来。
作为一个小小程序员,我还是一步一步来做吧。