天天看点

Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用

关于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 获取系统权限

    截图如下:(加上了水印,请谅解)

Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用

     老规矩,资源文件不在贴了。 主工程逻辑如下:

[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

         终于完成了这几块功能的介绍,这些功能的具体使用都挺类似的,最重要的是看你有没有耐心去把他们做出来。

   作为一个小小程序员,我还是一步一步来做吧。