Android - 如何通过PID获取进程名称或包名?

18
我的问题是:如何根据一个进程的PID获取它的"processName"或"packageName"?
因为在我的任务管理器中,我想使用PID来使用killBackgroundProcesses代码来结束进程。问题是我需要这个进程的packageName/processName才能做到这一点,如果要求用户输入进程名字而不仅仅是PID的话,这对用户来说将是一个麻烦。
这是我的任务管理器的图像: http://i.imgur.com/1zpXg.jpg

1
不是你要求的,但也许在你的任务管理器的最终版本中,你可以让用户点击选择要关闭的应用程序,或使用复选框。让他们输入PID似乎是一个额外的、不必要的步骤。 - Rob I
是的,那是我的理想计划。然而,我还不知道如何使用复选框或单击选择方法。这就是为什么我首先选择了这种方法。但如果你有任何想法,那对我来说真的会很有帮助。:D - Loren
1
你可以尝试使用ListView,或者对于复选框,这里有一个教程链接 - Rob I
3个回答

21

这段代码是对 Yaqub 代码的简化版本。我将其作为一个静态方法放在了 Util 类中:

public static String getAppNameByPID(Context context, int pid){
    ActivityManager manager 
               = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);

    for(RunningAppProcessInfo processInfo : manager.getRunningAppProcesses()){
        if(processInfo.pid == pid){
            return processInfo.processName;
        }
    }
    return "";
}

抱歉,我没有理解你的观点。我们正在传递到此函数的pid已经从RunningAppProcessInfo对象中获取,因此,我们可以直接从RunningAppProcessInfo对象调用属性processInfo.processName,而无需再次获取所有运行应用程序的列表。 - Naveed
由于getRunningAppProcesses()只返回您的应用程序进程,因此无法在API 23以上的版本上运行。显然,没有正确的方法通过其PID获取其他应用程序包。请参阅Dianne Hackborn对类似问题的回答。https://groups.google.com/d/msg/android-platform/pmL5wl2w7PU/8r4SSQ6jKVkJ - Amaksoft

14

你好,你可以使用这段代码,在我的Android 2.3.3版本中有效:

private String getAppName(int pID)
{
    String processName = "";
    ActivityManager am = (ActivityManager)this.getSystemService(ACTIVITY_SERVICE);
    List l = am.getRunningAppProcesses();
    Iterator i = l.iterator();
    PackageManager pm = this.getPackageManager();
    while(i.hasNext()) 
    {
          ActivityManager.RunningAppProcessInfo info = (ActivityManager.RunningAppProcessInfo)(i.next());
          try 
          { 
              if(info.pid == pID)
              {
                  CharSequence c = pm.getApplicationLabel(pm.getApplicationInfo(info.processName, PackageManager.GET_META_DATA));
                  //Log.d("Process", "Id: "+ info.pid +" ProcessName: "+ info.processName +"  Label: "+c.toString());
                  //processName = c.toString();
                  processName = info.processName;
              }
          }
          catch(Exception e) 
          {
                //Log.d("Process", "Error>> :"+ e.toString());
          }
   }
    return processName;
}

谢谢你的代码。我只是想先弄清楚它,因为我对Android不是很熟悉,而且我已经很久没有编程了。 :) - Loren
我想问一下Log.d是做什么用的? - Loren
有关日志窗口(Log.d)请参见: http://stackoverflow.com/questions/4584103/log-in-android-development - Yaqub Ahmad
现在它已经完全与我的其余代码配合运行了。非常感谢你!:D - Loren
如果应用程序使用非标准进程名称,则此方法将无法正常工作。 - Felix
如果您的进程是远程服务,则此方法不起作用。您需要执行相同的操作,但调用am.getRunningServices(),并使用ActivityManager.RunningServiceInfo对象。对于我而言,info.process 然后具有:com.[包名]:[进程名称] - Mike Venzke

2
“结束其他进程通常不是一个好主意。请看这个问题Android process killerandroid task kill。还有这篇博客Android: Killing a running process with processid(pid) and package name。至于你的问题如何从pid获取进程名称,可以尝试以下方法:安装一个终端模拟器,启动它并运行命令:”
ps | grep 10058

“ps”命令可以列出进程,而“grep”命令可以筛选你想要的ID。但是,这只有在运行该命令时应用程序正在运行时才有效。

是的,我已经读了好几遍了。但由于这是我们班级的一个项目,所以我别无选择,只能遵守要求。谢谢你的帮助。 - Loren
1
在终端中出现“grep未找到”的错误 - Gabor
我的Android控制台没有grep,Android 4.4 CyanogenMod。 - dazito

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接