zoukankan      html  css  js  c++  java
  • Android中获取正在运行的服务-------ActivityManager.RunningServiceInfo的使用

                    关于PackageManager和ActivityManager的使用 ,自己也写了一些DEMO 了,基本上写的线路参考了Settings模块下的

            应用程序,大家如果真正的有所兴趣,建议大家看看源码,不过丑化说在前面,我自己也没怎么看过这方面的源码,只在

            需要的时候,才跑过去翻翻。

             

                 今天,在耐着最后一点性子,写下了这篇博文,基本上完成了整个应用程序功能模块的介绍,大家也在此系列上慢慢拓展。

     

      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对象

     

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

     

     

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

     

                                                     

     

     

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

     

     

    1. package com.qin.runservice;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.Collections;  
    5. import java.util.Comparator;  
    6. import java.util.List;  
    7.   
    8. import android.app.Activity;  
    9. import android.app.ActivityManager;  
    10. import android.app.AlertDialog;  
    11. import android.app.Dialog;  
    12. import android.content.ComponentName;  
    13. import android.content.Context;  
    14. import android.content.DialogInterface;  
    15. import android.content.Intent;  
    16. import android.content.pm.ApplicationInfo;  
    17. import android.content.pm.PackageManager;  
    18. import android.content.pm.PackageManager.NameNotFoundException;  
    19. import android.os.Bundle;  
    20. import android.os.Debug;  
    21. import android.util.Log;  
    22. import android.view.ContextMenu;  
    23. import android.view.Menu;  
    24. import android.view.MenuItem;  
    25. import android.view.View;  
    26. import android.view.ContextMenu.ContextMenuInfo;  
    27. import android.widget.AdapterView;  
    28. import android.widget.ListView;  
    29. import android.widget.TextView;  
    30. import android.widget.AdapterView.OnItemClickListener;  
    31.   
    32. public class BrowseRunningServiceActivity extends Activity implements  
    33.         OnItemClickListener {  
    34.   
    35.     private static String TAG = "RunServiceInfo";  
    36.   
    37.     private ActivityManager mActivityManager = null;  
    38.     // ProcessInfo Model类 用来保存所有进程信息  
    39.     private List<RunSericeModel> serviceInfoList = null;  
    40.   
    41.     private ListView listviewService;  
    42.     private TextView tvTotalServiceNo;  
    43.   
    44.     public void onCreate(Bundle savedInstanceState) {  
    45.         super.onCreate(savedInstanceState);  
    46.   
    47.         setContentView(R.layout.browse_service_list);  
    48.   
    49.         listviewService = (ListView) findViewById(R.id.listviewService);  
    50.         listviewService.setOnItemClickListener(this);  
    51.   
    52.         tvTotalServiceNo = (TextView) findViewById(R.id.tvTotalServiceNo);  
    53.   
    54.         // 获得ActivityManager服务的对象  
    55.         mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
    56.   
    57.         // 获得正在运行的Service信息  
    58.         getRunningServiceInfo();  
    59.         // 对集合排序  
    60.         Collections.sort(serviceInfoList, new comparatorServiceLable());  
    61.   
    62.         System.out.println(serviceInfoList.size() + "-------------");  
    63.   
    64.         // 为ListView构建适配器对象  
    65.         BrowseRunningServiceAdapter mServiceInfoAdapter = new   
    66.                  BrowseRunningServiceAdapter(BrowseRunningServiceActivity.this, serviceInfoList);  
    67.   
    68.         listviewService.setAdapter(mServiceInfoAdapter);  
    69.   
    70.         tvTotalServiceNo.setText("当前正在运行的服务共有:" + serviceInfoList.size());  
    71.     }  
    72.     // 获得系统正在运行的进程信息  
    73.     private void getRunningServiceInfo() {  
    74.   
    75.         // 设置一个默认Service的数量大小  
    76.         int defaultNum = 20;  
    77.         // 通过调用ActivityManager的getRunningAppServicees()方法获得系统里所有正在运行的进程  
    78.         List<ActivityManager.RunningServiceInfo> runServiceList = mActivityManager  
    79.                 .getRunningServices(defaultNum);  
    80.   
    81.         System.out.println(runServiceList.size());  
    82.   
    83.         // ServiceInfo Model类 用来保存所有进程信息  
    84.         serviceInfoList = new ArrayList<RunSericeModel>();  
    85.   
    86.         for (ActivityManager.RunningServiceInfo runServiceInfo : runServiceList) {  
    87.   
    88.             // 获得Service所在的进程的信息  
    89.             int pid = runServiceInfo.pid; // service所在的进程ID号  
    90.             int uid = runServiceInfo.uid; // 用户ID 类似于Linux的权限不同,ID也就不同 比如 root等  
    91.             // 进程名,默认是包名或者由属性android:process指定  
    92.             String processName = runServiceInfo.process;   
    93.   
    94.             // 该Service启动时的时间值  
    95.             long activeSince = runServiceInfo.activeSince;  
    96.   
    97.             // 如果该Service是通过Bind方法方式连接,则clientCount代表了service连接客户端的数目  
    98.             int clientCount = runServiceInfo.clientCount;  
    99.   
    100.             // 获得该Service的组件信息 可能是pkgname/servicename  
    101.             ComponentName serviceCMP = runServiceInfo.service;  
    102.             String serviceName = serviceCMP.getShortClassName(); // service 的类名  
    103.             String pkgName = serviceCMP.getPackageName(); // 包名  
    104.   
    105.             // 打印Log  
    106.             Log.i(TAG, "所在进程id :" + pid + " 所在进程名:" + processName + " 所在进程uid:"  
    107.                     + uid + " " + " service启动的时间值:" + activeSince  
    108.                     + " 客户端绑定数目:" + clientCount + " " + "该service的组件信息:"  
    109.                     + serviceName + " and " + pkgName);  
    110.   
    111.             // 这儿我们通过service的组件信息,利用PackageManager获取该service所在应用程序的包名 ,图标等  
    112.             PackageManager mPackageManager = this.getPackageManager(); // 获取PackagerManager对象;  
    113.   
    114.             try {  
    115.                 // 获取该pkgName的信息  
    116.                 ApplicationInfo appInfo = mPackageManager.getApplicationInfo(  
    117.                         pkgName, 0);  
    118.   
    119.                 RunSericeModel runService = new RunSericeModel();  
    120.                 runService.setAppIcon(appInfo.loadIcon(mPackageManager));  
    121.                 runService.setAppLabel(appInfo.loadLabel(mPackageManager) + "");  
    122.                 runService.setServiceName(serviceName);  
    123.                 runService.setPkgName(pkgName);  
    124.                 // 设置该service的组件信息  
    125.                 Intent intent = new Intent();  
    126.                 intent.setComponent(serviceCMP);  
    127.                 runService.setIntent(intent);  
    128.   
    129.                 runService.setPid(pid);  
    130.                 runService.setProcessName(processName);  
    131.   
    132.                 // 添加至集合中  
    133.                 serviceInfoList.add(runService);  
    134.   
    135.             } catch (NameNotFoundException e) {  
    136.                 // TODO Auto-generated catch block  
    137.                 System.out.println("--------------------- error -------------");  
    138.                 e.printStackTrace();  
    139.             }  
    140.   
    141.         }  
    142.     }  
    143.   
    144.     // 触摸可停止  
    145.     @Override  
    146.     public void onItemClick(AdapterView<?> arg0, View arg1, int position,  
    147.             long arg3) {  
    148.         // TODO Auto-generated method stub  
    149.         final Intent stopserviceIntent = serviceInfoList.get(position)  
    150.                 .getIntent();  
    151.   
    152.         new AlertDialog.Builder(BrowseRunningServiceActivity.this).setTitle(  
    153.                 "是否停止服务").setMessage(  
    154.                 "服务只有在重新启动后,才可以继续运行。但这可能会给电子市场应用程序带来意想不到的结果。")  
    155.                 .setPositiveButton("停止"new DialogInterface.OnClickListener() {  
    156.   
    157.                     @Override  
    158.                     public void onClick(DialogInterface dialog, int which) {  
    159.                         // TODO Auto-generated method stub  
    160.                         // 停止该Service  
    161.                         //由于权限不够的问题,为了避免应用程序出现异常,捕获该SecurityException ,并弹出对话框  
    162.                         try {  
    163.                             stopService(stopserviceIntent);  
    164.                         } catch (SecurityException sEx) {  
    165.                             //发生异常 说明权限不够   
    166.                             System.out.println(" deny the permission");  
    167.                             new AlertDialog.Builder(BrowseRunningServiceActivity.this).setTitle(  
    168.                             "权限不够").setMessage("对不起,您的权限不够,无法停止该Service").create().show();  
    169.                         }  
    170.                         // 刷新界面  
    171.                         // 获得正在运行的Service信息  
    172.                         getRunningServiceInfo();  
    173.                         // 对集合排序  
    174.                         Collections.sort(serviceInfoList, new comparatorServiceLable());  
    175.                         // 为ListView构建适配器对象  
    176.                         BrowseRunningServiceAdapter mServiceInfoAdapter = new BrowseRunningServiceAdapter(  
    177.                                 BrowseRunningServiceActivity.this,  
    178.                                 serviceInfoList);  
    179.                         listviewService.setAdapter(mServiceInfoAdapter);  
    180.                         tvTotalServiceNo.setText("当前正在运行的服务共有:"  
    181.                                 + serviceInfoList.size());  
    182.                     }  
    183.   
    184.                 }).setNegativeButton("取消",  
    185.                         new DialogInterface.OnClickListener() {  
    186.   
    187.                             @Override  
    188.                             public void onClick(DialogInterface dialog,  
    189.                                     int which) {  
    190.                                 // TODO Auto-generated method stub  
    191.                                 dialog.dismiss(); // 取消对话框  
    192.                             }  
    193.                         }).create().show();  
    194.     }  
    195.   
    196.     // 自定义排序 根据AppLabel排序  
    197.     private class comparatorServiceLable implements Comparator<RunSericeModel> {  
    198.   
    199.         @Override  
    200.         public int compare(RunSericeModel object1, RunSericeModel object2) {  
    201.             // TODO Auto-generated method stub  
    202.             return object1.getAppLabel().compareTo(object2.getAppLabel());  
    203.         }  
    204.   
    205.     }  
    206.   
    207. }  

     

             代码下载地址:http://download.csdn.net/detail/qinjuning/3846097

         

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

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

  • 相关阅读:
    108. Convert Sorted Array to Binary Search Tree
    107. Binary Tree Level Order Traversal II
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
    104. Maximum Depth of Binary Tree
    103. Binary Tree Zigzag Level Order Traversal
    102. Binary Tree Level Order Traversal
    系统和进程相关信息
    文件I/0缓冲
    系统编程概念(文件系统mount等函数的使用)
  • 原文地址:https://www.cnblogs.com/wangxingliu/p/3531176.html
Copyright © 2011-2022 走看看