当前位置: 移动技术网 > IT编程>移动开发>Android > Android中获得正在运行的程序和系统服务的方法

Android中获得正在运行的程序和系统服务的方法

2019年07月24日  | 移动技术网IT编程  | 我要评论

qq农场种子大全,特种都市,CPO

activitymanager.runningappprocessinfo类与获取正在运行的应用程序
每一个应用程序都会运行在它独立的进程里,但是为了节省资源或者这些应用程序是为了完成某一共同工作,它们
也可能会运行在一个进程里。

2016228174335726.gif (295×68)

 知识点介绍:
activitymanager.runningappprocessinfo类
说明: 封装了正在运行的进程信息
常用字段:
int   pid    进程id
int   uid    进程所在的用户id
string   processname 进程名,默认是包名或者由android:process=””属性指定
string [ ]   pkglist      运行在该进程下的所有应用程序包名

demo说明:
我们利用activitymanager获取所有正在运行的进程信息后,也就是获取了每个进程里正在运行的应用程序包名(pkgname),那么通过这些包名(pkgname),直接调用packagemanager类提供的方法,可以获取这些应用程序的信息了。
一些资源文件就不贴了,直接贴出了主工程逻辑。需要注意的在这儿我们一次性获取了所有应用程序信息,然后对这些应用程序进行过滤,得到我们需要的对象。 读者可以使用packagemanager类提供的方法,进行循环遍历所有包名(pkgname),但是这样效率会比较低。
截图如下:
点击某一进程后

2016228174354207.gif (323×347)

查看某一进程运行的应用程序信息、所有正在运行的进程信息:

2016228174412674.gif (329×297)

2016228174430158.gif (345×425)

显示正在运行应用程序的工程代码如下:

 
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、 系统权限,这个咱就没什么话说了。
截图如下:

2016228174507748.gif (320×480)

主工程逻辑如下:

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()); 
    } 
 
  } 
 
} 

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网