zoukankan      html  css  js  c++  java
  • Android中获取正在运行的应用程序-----ActivityManager.RunningAppProcessInfo类详解

    今天继续讲解关于ActivityManager的使用,通过前面一节的学习,我们学会了如何利用ActivityManager获取系统里

          正在运行的进程。本文要讲解的知识点是利用这些进程信息获取系统里正在运行的应用程序以及每个进程里运行的应用程序。

         用到的知识点也包括PackageManager的使用,读者阅读在我之前写的blog《PackageManager的使用

     

               

                  每一个应用程序都会运行在它独立的进程里,但是为了节省资源或者这些应用程序是为了完成某一共同工作,它们

          也可能会运行在一个进程里。

     

                                                                     

     

     

      知识点介绍:

     

       

            ActivityManager.RunningAppProcessInfo类

             说明: 封装了正在运行的进程信息

             常用字段

                       int   pid    进程ID

                       int   uid    进程所在的用户ID

                       String   processName 进程名,默认是包名或者由android:process=””属性指定

                       String [ ]   pkgList      运行在该进程下的所有应用程序包名

     

          关于ActivityManager.RunningAppProcessInfo更多信息,请查看<Android中应用程序的信息---ActivityManager的使用>

       

       PackageManger类

           说明: 封装了对应用程序信息的操作

     

            获得应用程序信息的的方法如下:

     

           public abstract ApplicationInfo  getApplicationInfo(String packageName, int flags)

              参数:packagename 包名

                           flags   该ApplicationInfo是此flags标记,通常可以直接赋予常数0即可

              功能:返回ApplicationInfo对象

     

     

       关于PackageManger更多信息,请查看<Android中获取应用程序(包)的信息-----PackageManager的使用(一)>

     

     

     Demo说明:

     

     

                我们利用ActivityManager获取所有正在运行的进程信息后,也就是获取了每个进程里正在运行的应用程序包名(pkgname),

         那么通过这些包名(pkgname),直接调用PackageManager类提供的方法,可以获取这些应用程序的信息了。

     

     

               一些资源文件就不贴了,直接贴出了主工程逻辑。需要注意的在这儿我们一次性获取了所有应用程序信息,然后对这些

         应用程序进行过滤,得到我们需要的对象。 读者可以使用PackageManager类提供的方法,进行循环遍历所有包名(pkgname),

         但是这样效率会比较低。

     

          截图如下:

     

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

     

                                          

       

     

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

     

     

    1. package com.qin.ammp;  
    2.   
    3. import java.util.ArrayList;  
    4. import java.util.Collections;  
    5. import java.util.HashMap;  
    6. import java.util.List;  
    7. import java.util.Map;  
    8.   
    9. import android.app.Activity;  
    10. import android.app.ActivityManager;  
    11. import android.content.Context;  
    12. import android.content.Intent;  
    13. import android.content.pm.ApplicationInfo;  
    14. import android.content.pm.PackageInfo;  
    15. import android.content.pm.PackageManager;  
    16. import android.content.pm.PackageManager.NameNotFoundException;  
    17. import android.os.Bundle;  
    18. import android.util.Log;  
    19. import android.view.View;  
    20. import android.widget.AdapterView;  
    21. import android.widget.ListView;  
    22. import android.widget.TextView;  
    23. import android.widget.AdapterView.OnItemClickListener;  
    24.   
    25. public class BrowseRunningAppActivity extends Activity {  
    26.   
    27.     private static String TAG = "BrowseRunningAppActivity";  
    28.   
    29.     private ListView listview = null;  
    30.   
    31.     private List<RunningAppInfo> mlistAppInfo = null;  
    32.     private TextView tvInfo = null ;  
    33.       
    34.     private PackageManager pm;  
    35.   
    36.     @Override  
    37.     public void onCreate(Bundle savedInstanceState) {  
    38.         super.onCreate(savedInstanceState);  
    39.         setContentView(R.layout.browse_app_list);  
    40.   
    41.         listview = (ListView) findViewById(R.id.listviewApp);  
    42.         tvInfo = (TextView)findViewById(R.id.tvInfo) ;  
    43.           
    44.         mlistAppInfo = new ArrayList<RunningAppInfo>();  
    45.   
    46.         // 查询某一特定进程的所有应用程序  
    47.         Intent intent = getIntent();  
    48.         //是否查询某一特定pid的应用程序  
    49.         int pid = intent.getIntExtra("EXTRA_PROCESS_ID", -1);  
    50.           
    51.         if ( pid != -1) {  
    52.             //某一特定经常里所有正在运行的应用程序  
    53.             mlistAppInfo =querySpecailPIDRunningAppInfo(intent, pid);  
    54.         }  
    55.         else{  
    56.             // 查询所有正在运行的应用程序信息: 包括他们所在的进程id和进程名  
    57.             tvInfo.setText("所有正在运行的应用程序有-------");  
    58.             mlistAppInfo = queryAllRunningAppInfo();   
    59.         }  
    60.         BrowseRunningAppAdapter browseAppAdapter = new BrowseRunningAppAdapter(this, mlistAppInfo);  
    61.         listview.setAdapter(browseAppAdapter);  
    62.     }  
    63.   
    64.     // 查询所有正在运行的应用程序信息: 包括他们所在的进程id和进程名  
    65.     // 这儿我直接获取了系统里安装的所有应用程序,然后根据报名pkgname过滤获取所有真正运行的应用程序  
    66.     private List<RunningAppInfo> queryAllRunningAppInfo() {  
    67.         pm = this.getPackageManager();  
    68.         // 查询所有已经安装的应用程序  
    69.         List<ApplicationInfo> listAppcations = pm.getInstalledApplications(PackageManager.GET_UNINSTALLED_PACKAGES);  
    70.         Collections.sort(listAppcations,new ApplicationInfo.DisplayNameComparator(pm));// 排序  
    71.   
    72.         // 保存所有正在运行的包名 以及它所在的进程信息  
    73.         Map<String, ActivityManager.RunningAppProcessInfo> pgkProcessAppMap = new HashMap<String, ActivityManager.RunningAppProcessInfo>();  
    74.   
    75.         ActivityManager mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);  
    76.         // 通过调用ActivityManager的getRunningAppProcesses()方法获得系统里所有正在运行的进程  
    77.         List<ActivityManager.RunningAppProcessInfo> appProcessList = mActivityManager  
    78.                 .getRunningAppProcesses();  
    79.   
    80.         for (ActivityManager.RunningAppProcessInfo appProcess : appProcessList) {  
    81.             int pid = appProcess.pid; // pid  
    82.             String processName = appProcess.processName; // 进程名  
    83.             Log.i(TAG, "processName: " + processName + "  pid: " + pid);  
    84.   
    85.             String[] pkgNameList = appProcess.pkgList; // 获得运行在该进程里的所有应用程序包  
    86.   
    87.             // 输出所有应用程序的包名  
    88.             for (int i = 0; i < pkgNameList.length; i++) {  
    89.                 String pkgName = pkgNameList[i];  
    90.                 Log.i(TAG, "packageName " + pkgName + " at index " + i+ " in process " + pid);  
    91.                 // 加入至map对象里  
    92.                 pgkProcessAppMap.put(pkgName, appProcess);  
    93.             }  
    94.         }  
    95.         // 保存所有正在运行的应用程序信息  
    96.         List<RunningAppInfo> runningAppInfos = new ArrayList<RunningAppInfo>(); // 保存过滤查到的AppInfo  
    97.   
    98.         for (ApplicationInfo app : listAppcations) {  
    99.             // 如果该包名存在 则构造一个RunningAppInfo对象  
    100.             if (pgkProcessAppMap.containsKey(app.packageName)) {  
    101.                 // 获得该packageName的 pid 和 processName  
    102.                 int pid = pgkProcessAppMap.get(app.packageName).pid;  
    103.                 String processName = pgkProcessAppMap.get(app.packageName).processName;  
    104.                 runningAppInfos.add(getAppInfo(app, pid, processName));  
    105.             }  
    106.         }  
    107.   
    108.         return runningAppInfos;  
    109.   
    110.     }  
    111.     // 某一特定经常里所有正在运行的应用程序  
    112.     private List<RunningAppInfo> querySpecailPIDRunningAppInfo(Intent intent , int pid) {  
    113.   
    114.   
    115.         String[] pkgNameList = intent.getStringArrayExtra("EXTRA_PKGNAMELIST");  
    116.         String processName = intent.getStringExtra("EXTRA_PROCESS_NAME");  
    117.           
    118.         //update ui  
    119.         tvInfo.setText("进程id为"+pid +" 运行的应用程序共有  :  "+pkgNameList.length);  
    120.                   
    121.         pm = this.getPackageManager();  
    122.       
    123.         // 保存所有正在运行的应用程序信息  
    124.         List<RunningAppInfo> runningAppInfos = new ArrayList<RunningAppInfo>(); // 保存过滤查到的AppInfo  
    125.   
    126.         for(int i = 0 ; i<pkgNameList.length ;i++){  
    127.            //根据包名查询特定的ApplicationInfo对象  
    128.            ApplicationInfo appInfo;  
    129.           try {  
    130.             appInfo = pm.getApplicationInfo(pkgNameList[i], 0);  
    131.             runningAppInfos.add(getAppInfo(appInfo, pid, processName));  
    132.           }  
    133.           catch (NameNotFoundException e) {  
    134.             // TODO Auto-generated catch block  
    135.             e.printStackTrace();  
    136.           }  // 0代表没有任何标记;  
    137.         }  
    138.         return runningAppInfos ;  
    139.     }  
    140.       
    141.       
    142.     // 构造一个RunningAppInfo对象 ,并赋值  
    143.     private RunningAppInfo getAppInfo(ApplicationInfo app, int pid, String processName) {  
    144.         RunningAppInfo appInfo = new RunningAppInfo();  
    145.         appInfo.setAppLabel((String) app.loadLabel(pm));  
    146.         appInfo.setAppIcon(app.loadIcon(pm));  
    147.         appInfo.setPkgName(app.packageName);  
    148.   
    149.         appInfo.setPid(pid);  
    150.         appInfo.setProcessName(processName);  
    151.   
    152.         return appInfo;  
    153.     }  
    154. }  
    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;
    	}
    }

     

     

             通过对这一节的介绍,我们基本上完成了Android系统里Settings模块了应用程序的功能,虽然在整体上,并没有贯穿起来,

      但是主轴线已经规划好了,大家也仔细体味吧。

     

     

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

  • 相关阅读:
    Numpy入门
    Numpy入门
    Spring源码之IoC原理
    LeetCode之连续子数组的最大和
    剑指Offer之从1到n整数中1出现的次数
    剑指Offer之最小的k个数
    剑指Offer之字符串的排列
    剑指Offer之二叉搜索树与双向链表
    剑指Offer之二叉树中和为某一值的路径
    剑指Offer之二叉搜索树的后序遍历序列
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/3651003.html
Copyright © 2011-2022 走看看