Android shell 获取前台应用包名

Android shell get foreground app package name

我正在使用 tasker 自动发送短信,为此我需要检查当前前台应用程序包名称是否为 x。如果是 x 则做其他事情做其他事情。我尝试使用 pgrep 但它 returns 即使应用程序 x 在后台也是如此。有没有办法从 shell 检查 x 是否在前台? 谢谢

这对我有用:

adb shell dumpsys window windows | grep -E 'mCurrentFocus' | cut -d '/' -f1 | sed 's/.* //g'

com.facebook.katana

Android Q 的更新答案,因为 mCurrentFocus 不再适合我:

adb shell dumpsys activity recents | grep 'Recent #0' | cut -d= -f2 | sed 's| .*||' | cut -d '/' -f1

接受的答案在很多情况下可能会产生意想不到的结果。

某些 UI 元素(例如对话框)不会在 mCurrentFocus(mFocusedApp)字段中显示包名称。例如,当应用程序抛出一个对话框时,mCurrentFocus 通常是对话框的标题。一些应用程序在应用程序启动时显示这些,使得这种方法无法用于检测应用程序是否已成功进入前台。

例如,应用程序com.imo.android.imoimbeta在启动时询问用户国家,其当前焦点是:

$ adb shell dumpsys window windows | grep mCurrentFocus
  mCurrentFocus=Window{21e4cca8 u0 Choose a country}

在这种情况下 mFocusedApp 为 null,因此要知道哪个应用程序包名称源自此对话框的唯一方法是检查其 mOwnerUID:

Window #3 Window{21d12418 u0 Choose a country}:
    mDisplayId=0 mSession=Session{21cb88b8 5876:u0a10071} mClient=android.os.BinderProxy@21c32160
    mOwnerUid=10071 mShowToOwnerOnly=true package=com.imo.android.imoimbeta appop=NONE 

根据用例,可接受的解决方案可能就足够了,但值得一提的是它的局限性。

到目前为止我发现有效的解决方案:

window_output = %x(adb shell dumpsys window windows)
windows = Hash.new
app_window = nil

window_output.each_line do |line| 

    case line

      #matches the mCurrentFocus, so we can check the actual owner
      when /Window #\d+[^{]+({[^}]+})/ #New window
        app_window= 

      #owner of the current window
      when /mOwnerUid=[\d]+\s[^\s]+\spackage=([^\s]+)/ 
        app_package=

        #Lets store the respective app_package
        windows[app_window] = app_package

      when /mCurrentFocus=[^{]+({[^}]+})/
        app_focus=

        puts "Current Focus package name: #{windows[app_focus]}"

        break
    end
end