Android中获得正在运行的程序和系统服务的方法
activitymanager.runningappprocessinfo类与获取正在运行的应用程序
每一个应用程序都会运行在它独立的进程里,但是为了节省资源或者这些应用程序是为了完成某一共同工作,它们
也可能会运行在一个进程里。
知识点介绍:
activitymanager.runningappprocessinfo类
说明: 封装了正在运行的进程信息
常用字段:
int pid 进程id
int uid 进程所在的用户id
string processname 进程名,默认是包名或者由android:process=””属性指定
string [ ] pkglist 运行在该进程下的所有应用程序包名
demo说明:
我们利用activitymanager获取所有正在运行的进程信息后,也就是获取了每个进程里正在运行的应用程序包名(pkgname),那么通过这些包名(pkgname),直接调用packagemanager类提供的方法,可以获取这些应用程序的信息了。
一些资源文件就不贴了,直接贴出了主工程逻辑。需要注意的在这儿我们一次性获取了所有应用程序信息,然后对这些应用程序进行过滤,得到我们需要的对象。 读者可以使用packagemanager类提供的方法,进行循环遍历所有包名(pkgname),但是这样效率会比较低。
截图如下:
点击某一进程后
查看某一进程运行的应用程序信息、所有正在运行的进程信息:
显示正在运行应用程序的工程代码如下:
package com.qin.ammp; import java.util.arraylist; import java.util.collections; import java.util.hashmap; import java.util.list; import java.util.map; import android.app.activity; import android.app.activitymanager; import android.content.context; import android.content.intent; import android.content.pm.applicationinfo; import android.content.pm.packageinfo; import android.content.pm.packagemanager; import android.content.pm.packagemanager.namenotfoundexception; import android.os.bundle; import android.util.log; import android.view.view; import android.widget.adapterview; import android.widget.listview; import android.widget.textview; import android.widget.adapterview.onitemclicklistener; public class browserunningappactivity extends activity { private static string tag = "browserunningappactivity"; private listview listview = null; private list<runningappinfo> mlistappinfo = null; private textview tvinfo = null ; private packagemanager pm; @override public void oncreate(bundle savedinstancestate) { super.oncreate(savedinstancestate); setcontentview(r.layout.browse_app_list); listview = (listview) findviewbyid(r.id.listviewapp); tvinfo = (textview)findviewbyid(r.id.tvinfo) ; mlistappinfo = new arraylist<runningappinfo>(); // 查询某一特定进程的所有应用程序 intent intent = getintent(); //是否查询某一特定pid的应用程序 int pid = intent.getintextra("extra_process_id", -1); if ( pid != -1) { //某一特定经常里所有正在运行的应用程序 mlistappinfo =queryspecailpidrunningappinfo(intent, pid); } else{ // 查询所有正在运行的应用程序信息: 包括他们所在的进程id和进程名 tvinfo.settext("所有正在运行的应用程序有-------"); mlistappinfo = queryallrunningappinfo(); } browserunningappadapter browseappadapter = new browserunningappadapter(this, mlistappinfo); listview.setadapter(browseappadapter); } // 查询所有正在运行的应用程序信息: 包括他们所在的进程id和进程名 // 这儿我直接获取了系统里安装的所有应用程序,然后根据报名pkgname过滤获取所有真正运行的应用程序 private list<runningappinfo> queryallrunningappinfo() { pm = this.getpackagemanager(); // 查询所有已经安装的应用程序 list<applicationinfo> listappcations = pm.getinstalledapplications(packagemanager.get_uninstalled_packages); collections.sort(listappcations,new applicationinfo.displaynamecomparator(pm));// 排序 // 保存所有正在运行的包名 以及它所在的进程信息 map<string, activitymanager.runningappprocessinfo> pgkprocessappmap = new hashmap<string, activitymanager.runningappprocessinfo>(); activitymanager mactivitymanager = (activitymanager) getsystemservice(context.activity_service); // 通过调用activitymanager的getrunningappprocesses()方法获得系统里所有正在运行的进程 list<activitymanager.runningappprocessinfo> appprocesslist = mactivitymanager .getrunningappprocesses(); for (activitymanager.runningappprocessinfo appprocess : appprocesslist) { int pid = appprocess.pid; // pid string processname = appprocess.processname; // 进程名 log.i(tag, "processname: " + processname + " pid: " + pid); string[] pkgnamelist = appprocess.pkglist; // 获得运行在该进程里的所有应用程序包 // 输出所有应用程序的包名 for (int i = 0; i < pkgnamelist.length; i++) { string pkgname = pkgnamelist[i]; log.i(tag, "packagename " + pkgname + " at index " + i+ " in process " + pid); // 加入至map对象里 pgkprocessappmap.put(pkgname, appprocess); } } // 保存所有正在运行的应用程序信息 list<runningappinfo> runningappinfos = new arraylist<runningappinfo>(); // 保存过滤查到的appinfo for (applicationinfo app : listappcations) { // 如果该包名存在 则构造一个runningappinfo对象 if (pgkprocessappmap.containskey(app.packagename)) { // 获得该packagename的 pid 和 processname int pid = pgkprocessappmap.get(app.packagename).pid; string processname = pgkprocessappmap.get(app.packagename).processname; runningappinfos.add(getappinfo(app, pid, processname)); } } return runningappinfos; } // 某一特定经常里所有正在运行的应用程序 private list<runningappinfo> queryspecailpidrunningappinfo(intent intent , int pid) { string[] pkgnamelist = intent.getstringarrayextra("extra_pkgnamelist"); string processname = intent.getstringextra("extra_process_name"); //update ui tvinfo.settext("进程id为"+pid +" 运行的应用程序共有 : "+pkgnamelist.length); pm = this.getpackagemanager(); // 保存所有正在运行的应用程序信息 list<runningappinfo> runningappinfos = new arraylist<runningappinfo>(); // 保存过滤查到的appinfo for(int i = 0 ; i<pkgnamelist.length ;i++){ //根据包名查询特定的applicationinfo对象 applicationinfo appinfo; try { appinfo = pm.getapplicationinfo(pkgnamelist[i], 0); runningappinfos.add(getappinfo(appinfo, pid, processname)); } catch (namenotfoundexception e) { // todo auto-generated catch block e.printstacktrace(); } // 0代表没有任何标记; } return runningappinfos ; } // 构造一个runningappinfo对象 ,并赋值 private runningappinfo getappinfo(applicationinfo app, int pid, string processname) { runningappinfo appinfo = new runningappinfo(); appinfo.setapplabel((string) app.loadlabel(pm)); appinfo.setappicon(app.loadicon(pm)); appinfo.setpkgname(app.packagename); appinfo.setpid(pid); appinfo.setprocessname(processname); return appinfo; } }
activitymanager.runningserviceinfo类获取正在运行的服务
activitymanager.runningserviceinfo类: 封装了正在运行的服务信息
获取系统里所有真正运行的服务是通过调用activitymanager方法来得到的,具体方法如下:
list<activitymanager.runningserviceinfo> getrunningservices (int maxnum)
功能:返回所有正在运行的服务
参数: maxnum 代表我们希望返回的服务数目大小,一般给个稍大的值即可, 例如,50 。
activitymanager.runningserviceinfo 类
常用字段:
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信息
packagemanger类
说明: 封装了对应用程序信息的操作
获得应用程序信息的的方法如下:
public abstractapplicationinfo getapplicationinfo(string packagename, int flags)
参数:packagename 包名
flags 该applicationinfo是此flags标记,通常可以直接赋予常数0即可
功能:返回applicationinfo对象
demo说明:
我们获取了系统里正在运行的服务信息,包括包名,图标,service类名等。为了达到settings下应用程序模块中的正在运行服务的效果,我们点击某一服务后,理论上来说是可以停止该服务的,但是由于权限permissions不够,可能报securityexception异常,导致应用程序发生异常。
关于权限不够的问题,可以分为两种:
1、 在androidmanifest.xml文件中,为<activity/>或<service/>节点指定android:permission属性时,在其他进程中操作时,需要声明该permission权限 。
2、 系统权限,这个咱就没什么话说了。
截图如下:
主工程逻辑如下:
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()); } } }
上一篇: 对于Map的理解
推荐阅读
-
Android中获得正在运行的程序和系统服务的方法
-
Android开发中调用系统相册上传图片到服务器OPPO等部分手机上出现短暂的显示桌面问题的解决方法
-
Android开发中调用系统相册上传图片到服务器OPPO等部分手机上出现短暂的显示桌面问题的解决方法
-
Android中获得正在运行的程序和系统服务的方法
-
Android中系统默认输入法设置的方法(输入法的显示和隐藏)
-
C#列出当前系统所有正在运行程序的方法
-
Android中系统默认输入法设置的方法(输入法的显示和隐藏)
-
Android实现判断某个服务是否正在运行的方法
-
往Android系统中添加服务的方法教程
-
C#列出当前系统所有正在运行程序的方法