關於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]
- 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://linux.linuxidc.com/
用戶名與密碼都是www.linuxidc.com
具體下載目錄在 /2012年資料/2月/2日/Android中獲取正在運行的服務-------ActivityManager.RunningServiceInfo的使用/
終於完成了這幾塊功能的介紹,這些功能的具體使用都挺類似的,最重要的是看你有沒有耐心去把他們做出來。
作為一個小小程序員,我還是一步一步來做吧。。