歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Android中獲取正在運行的服務:ActivityManager.RunningServiceInfo的使用

Android中獲取正在運行的服務:ActivityManager.RunningServiceInfo的使用

日期:2017/3/1 10:35:04   编辑:Linux編程

關於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的使用(一)> http://www.linuxidc.com/Linux/2012-02/53072.htm

Task任務的使用,我也就不在贅述了,大家可以仔細看下SDK,在此推薦一篇博客來幫助大家理解。

《Android系統的進程,任務,服務的信息》 http://www.linuxidc.com/Linux/2012-02/53080.htm

Demo說明:

我們獲取了系統裡正在運行的服務信息,包括包名,圖標,service類名等。為了達到Settings下應用程序模塊中的

正在運行服務的效果,我們點擊某一服務後,理論上來說是可以停止該服務的,但是由於權限permissions不夠,可能報SecurityException異常,導致應用程序發生異常。

關於權限不夠的問題,可以分為兩種:

1、 在AndroidManifest.xml文件中,為<activity/>或<service/>節點指定android:permission屬性時,在其他進程中操作時,需要 聲明該permission權限 。 具體可以參考下面這篇文章:

《android 自定義權限 permission》 http://www.linuxidc.com/Linux/2012-02/53081.htm

2、 系統權限,這個咱就沒什麼話說了。 可以參考下面這篇文章。

《android.uid.system 獲取系統權限 》 http://www.linuxidc.com/Linux/2012-02/53082.htm

老規矩,資源文件不在貼了。 主工程邏輯如下:

[java]

  1. package com.qin.runservice;
  2. import java.util.ArrayList;
  3. import java.util.Collections;
  4. import java.util.Comparator;
  5. import java.util.List;
  6. import android.app.Activity;
  7. import android.app.ActivityManager;
  8. import android.app.AlertDialog;
  9. import android.app.Dialog;
  10. import android.content.ComponentName;
  11. import android.content.Context;
  12. import android.content.DialogInterface;
  13. import android.content.Intent;
  14. import android.content.pm.ApplicationInfo;
  15. import android.content.pm.PackageManager;
  16. import android.content.pm.PackageManager.NameNotFoundException;
  17. import android.os.Bundle;
  18. import android.os.Debug;
  19. import android.util.Log;
  20. import android.view.ContextMenu;
  21. import android.view.Menu;
  22. import android.view.MenuItem;
  23. import android.view.View;
  24. import android.view.ContextMenu.ContextMenuInfo;
  25. import android.widget.AdapterView;
  26. import android.widget.ListView;
  27. import android.widget.TextView;
  28. import android.widget.AdapterView.OnItemClickListener;
  29. public class BrowseRunningServiceActivity extends Activity implements
  30. OnItemClickListener {
  31. private static String TAG = "RunServiceInfo";
  32. private ActivityManager mActivityManager = null;
  33. // ProcessInfo Model類 用來保存所有進程信息
  34. private List<RunSericeModel> serviceInfoList = null;
  35. private ListView listviewService;
  36. private TextView tvTotalServiceNo;
  37. public void onCreate(Bundle savedInstanceState) {
  38. super.onCreate(savedInstanceState);
  39. setContentView(R.layout.browse_service_list);
  40. listviewService = (ListView) findViewById(R.id.listviewService);
  41. listviewService.setOnItemClickListener(this);
  42. tvTotalServiceNo = (TextView) findViewById(R.id.tvTotalServiceNo);
  43. // 獲得ActivityManager服務的對象
  44. mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
  45. // 獲得正在運行的Service信息
  46. getRunningServiceInfo();
  47. // 對集合排序
  48. Collections.sort(serviceInfoList, new comparatorServiceLable());
  49. System.out.println(serviceInfoList.size() + "-------------");
  50. // 為ListView構建適配器對象
  51. BrowseRunningServiceAdapter mServiceInfoAdapter = new
  52. BrowseRunningServiceAdapter(BrowseRunningServiceActivity.this, serviceInfoList);
  53. listviewService.setAdapter(mServiceInfoAdapter);
  54. tvTotalServiceNo.setText("當前正在運行的服務共有:" + serviceInfoList.size());
  55. }
  56. // 獲得系統正在運行的進程信息
  57. private void getRunningServiceInfo() {
  58. // 設置一個默認Service的數量大小
  59. int defaultNum = 20;
  60. // 通過調用ActivityManager的getRunningAppServicees()方法獲得系統裡所有正在運行的進程
  61. List<ActivityManager.RunningServiceInfo> runServiceList = mActivityManager
  62. .getRunningServices(defaultNum);
  63. System.out.println(runServiceList.size());
  64. // ServiceInfo Model類 用來保存所有進程信息
  65. serviceInfoList = new ArrayList<RunSericeModel>();
  66. for (ActivityManager.RunningServiceInfo runServiceInfo : runServiceList) {
  67. // 獲得Service所在的進程的信息
  68. int pid = runServiceInfo.pid; // service所在的進程ID號
  69. int uid = runServiceInfo.uid; // 用戶ID 類似於Linux的權限不同,ID也就不同 比如 root等
  70. // 進程名,默認是包名或者由屬性android:process指定
  71. String processName = runServiceInfo.process;
  72. // 該Service啟動時的時間值
  73. long activeSince = runServiceInfo.activeSince;
  74. // 如果該Service是通過Bind方法方式連接,則clientCount代表了service連接客戶端的數目
  75. int clientCount = runServiceInfo.clientCount;
  76. // 獲得該Service的組件信息 可能是pkgname/servicename
  77. ComponentName serviceCMP = runServiceInfo.service;
  78. String serviceName = serviceCMP.getShortClassName(); // service 的類名
  79. String pkgName = serviceCMP.getPackageName(); // 包名
  80. // 打印Log
  81. Log.i(TAG, "所在進程id :" + pid + " 所在進程名:" + processName + " 所在進程uid:"
  82. + uid + "\n" + " service啟動的時間值:" + activeSince
  83. + " 客戶端綁定數目:" + clientCount + "\n" + "該service的組件信息:"
  84. + serviceName + " and " + pkgName);
  85. // 這兒我們通過service的組件信息,利用PackageManager獲取該service所在應用程序的包名 ,圖標等
  86. PackageManager mPackageManager = this.getPackageManager(); // 獲取PackagerManager對象;
  87. try {
  88. // 獲取該pkgName的信息
  89. ApplicationInfo appInfo = mPackageManager.getApplicationInfo(
  90. pkgName, 0);
  91. RunSericeModel runService = new RunSericeModel();
  92. runService.setAppIcon(appInfo.loadIcon(mPackageManager));
  93. runService.setAppLabel(appInfo.loadLabel(mPackageManager) + "");
  94. runService.setServiceName(serviceName);
  95. runService.setPkgName(pkgName);
  96. // 設置該service的組件信息
  97. Intent intent = new Intent();
  98. intent.setComponent(serviceCMP);
  99. runService.setIntent(intent);
  100. runService.setPid(pid);
  101. runService.setProcessName(processName);
  102. // 添加至集合中
  103. serviceInfoList.add(runService);
  104. } catch (NameNotFoundException e) {
  105. // TODO Auto-generated catch block
  106. System.out.println("--------------------- error -------------");
  107. e.printStackTrace();
  108. }
  109. }
  110. }
  111. // 觸摸可停止
  112. @Override
  113. public void onItemClick(AdapterView<?> arg0, View arg1, int position,
  114. long arg3) {
  115. // TODO Auto-generated method stub
  116. final Intent stopserviceIntent = serviceInfoList.get(position)
  117. .getIntent();
  118. new AlertDialog.Builder(BrowseRunningServiceActivity.this).setTitle(
  119. "是否停止服務").setMessage(
  120. "服務只有在重新啟動後,才可以繼續運行。但這可能會給電子市場應用程序帶來意想不到的結果。")
  121. .setPositiveButton("停止", new DialogInterface.OnClickListener() {
  122. @Override
  123. public void onClick(DialogInterface dialog, int which) {
  124. // TODO Auto-generated method stub
  125. // 停止該Service
  126. //由於權限不夠的問題,為了避免應用程序出現異常,捕獲該SecurityException ,並彈出對話框
  127. try {
  128. stopService(stopserviceIntent);
  129. } catch (SecurityException sEx) {
  130. //發生異常 說明權限不夠
  131. System.out.println(" deny the permission");
  132. new AlertDialog.Builder(BrowseRunningServiceActivity.this).setTitle(
  133. "權限不夠").setMessage("對不起,您的權限不夠,無法停止該Service").create().show();
  134. }
  135. // 刷新界面
  136. // 獲得正在運行的Service信息
  137. getRunningServiceInfo();
  138. // 對集合排序
  139. Collections.sort(serviceInfoList, new comparatorServiceLable());
  140. // 為ListView構建適配器對象
  141. BrowseRunningServiceAdapter mServiceInfoAdapter = new BrowseRunningServiceAdapter(
  142. BrowseRunningServiceActivity.this,
  143. serviceInfoList);
  144. listviewService.setAdapter(mServiceInfoAdapter);
  145. tvTotalServiceNo.setText("當前正在運行的服務共有:"
  146. + serviceInfoList.size());
  147. }
  148. }).setNegativeButton("取消",
  149. new DialogInterface.OnClickListener() {
  150. @Override
  151. public void onClick(DialogInterface dialog,
  152. int which) {
  153. // TODO Auto-generated method stub
  154. dialog.dismiss(); // 取消對話框
  155. }
  156. }).create().show();
  157. }
  158. // 自定義排序 根據AppLabel排序
  159. private class comparatorServiceLable implements Comparator<RunSericeModel> {
  160. @Override
  161. public int compare(RunSericeModel object1, RunSericeModel object2) {
  162. // TODO Auto-generated method stub
  163. return object1.getAppLabel().compareTo(object2.getAppLabel());
  164. }
  165. }
  166. }

代碼下載地址:

免費下載地址在 http://linux.linuxidc.com/

用戶名與密碼都是www.linuxidc.com

具體下載目錄在 /2012年資料/2月/2日/Android中獲取正在運行的服務-------ActivityManager.RunningServiceInfo的使用/

終於完成了這幾塊功能的介紹,這些功能的具體使用都挺類似的,最重要的是看你有沒有耐心去把他們做出來。

作為一個小小程序員,我還是一步一步來做吧。。

Copyright © Linux教程網 All Rights Reserved