74

I'm developing an application that uses ADB Shell to interface with android devices, and I need some way of printing out the application name or label of an application, given maybe their package name.

In short, I need a way of getting app names (i.e. "Angry Birds v1.0.0") for user installed applications through adb shell.

Any light on the matter? Any help is appreciated on this.

msanford
  • 11,803
  • 11
  • 66
  • 93
hamsteyr
  • 751
  • 1
  • 6
  • 5

7 Answers7

94

adb shell pm list packages will give you a list of all installed package names.

You can then use dumpsys | grep -A18 "Package \[my.package\]" to grab the package information such as version identifiers etc

rcbevans
  • 7,101
  • 4
  • 30
  • 46
  • 12
    why dump all services when you only need `dumpsys package packages`? also no need to grep - dumpsys package supports filtering by package name – Alex P. May 20 '13 at 16:26
  • I know of that command, and sure, it's a start, giving me the package names of all installed applications. I've tried using dumpsys, but to not much success, leaving me to believe that I may not be using it right. Does it only work on running applications? or does it work on ones that haven't been launched at all as well. Also, could I get a usage example just in case? Your help is greatly appreciated. – hamsteyr May 20 '13 at 18:34
  • 18
    As per above, I managed to get the above code working to dumping package information, however it does not give me the data that I'm looking for. I'm referring to something similar to `aapt d badging` where I'd get information like `application-label: ES File Explorer` and `versionName='1.6.2.5'`. Is there anything that can give me this information through shell? – hamsteyr May 20 '13 at 19:00
  • 1
    @hamsteyr Any success meanwhile? If so: you can answer your own question. I'll certainly upvote then if your solution works (currently looking for the same) ;) – Izzy Nov 02 '14 at 22:53
  • 2
    This answer is not working. `dumpsys` does not output any text matching or nearby "Package [package.name]" that helps determine the app's label. appLabel is listed by `dumpsys package`, but only for a few apps ("BusyBox Pro", "BusyBox", and " ES File Manager" are some of the 5ish I get). Anyone have another solution? – Michael Hoffmann Nov 07 '15 at 21:19
  • windows users can use **findstr** instead of grep `adb shell pm list packages | findstr -s "package:com.twitter.android"` – equiman May 19 '16 at 21:24
  • 1
    Command `pm list` has been moved to `cmd package`, use `adb shell cmd package list packages` to list all installed package names in newer version. – Corey Apr 23 '19 at 03:35
  • 4
    @o0rebelious0o Cannot find the full application name of the [com.akh.livestream](https://play.google.com/store/apps/details?id=com.akh.livestream) package from your `dumpsys | grep -A18 "Package \[my.package\]"` – SebMa Dec 12 '19 at 03:44
  • This no longer works as tested on Android 11. – Marvin Sep 21 '21 at 02:23
31

just enter the following command on command prompt after launching the app:

adb shell dumpsys window windows | find "mCurrentFocus"

if executing the command on linux terminal replace find by grep

Akshay Kadam
  • 502
  • 4
  • 8
13

If you know the app id of the package (like org.mozilla.firefox), it is easy. First to get the path of actual package file of the appId,

$  adb shell pm list packages -f com.google.android.apps.inbox
package:/data/app/com.google.android.apps.inbox-1/base.apk=com.google.android.apps.inbox

Now you can do some grep|sed magic to extract the path : /data/app/com.google.android.apps.inbox-1/base.apk

After that aapt tool comes in handy :

$  adb shell aapt dump badging /data/app/com.google.android.apps.inbox-1/base.apk
...
application-label:'Inbox'
application-label-hi:'Inbox'
application-label-ru:'Inbox'
...

Again some grep magic to get the Label.

Love_for_CODE
  • 197
  • 1
  • 10
  • 9
    That last command won't work because aapt is only on your developer machine. You'll need to pull the apk from the device first. – Six Aug 29 '16 at 02:52
  • 1
    Even if you use it on the local machine the argument after "-f" acts like a wildcard, so if there are more than one package containing that string it will show several packages. The best way to do it is: `adb shell pm list packages -f` and then filter out the result. – Smeterlink Dec 24 '16 at 02:28
4

A shell script to accomplish this:

#!/bin/bash

# Remove whitespace
function remWS {
    if [ -z "${1}" ]; then
        cat | tr -d '[:space:]'
    else
        echo "${1}" | tr -d '[:space:]'
    fi
}

for pkg in $(adb shell pm list packages -3 | cut -d':' -f2); do
    apk_loc="$(adb shell pm path $(remWS $pkg) | cut -d':' -f2 | remWS)"
    apk_name="$(adb shell aapt dump badging $apk_loc | pcregrep -o1 $'application-label:\'(.+)\'' | remWS)"
    apk_info="$(adb shell aapt dump badging $apk_loc | pcregrep -o1 '\b(package: .+)')"

    echo "$apk_name v$(echo $apk_info | pcregrep -io1 -e $'\\bversionName=\'(.+?)\'')"
done
smac89
  • 39,374
  • 15
  • 132
  • 179
3

Inorder to find an app's name (application label), you need to do the following:
(as shown in other answers)

  1. Find the APK path of the app whose name you want to find.
  2. Using aapt command, find the app label.

But devices don't ship with the aapt binary out-of-the-box.
So you will need to install it first. You can download it from here:
https://github.com/Calsign/APDE/tree/master/APDE/src/main/assets/aapt-binaries


Check this guide for complete steps:
How to find an app name using package name through ADB Android?
(Disclaimer: I am the author of that blog post)

Gokul NC
  • 1,111
  • 4
  • 17
  • 39
1

This is what I just came up with. It gives a few errors but works well enough for my needs, matching package names to labels.

It pulls copies of all packages into subdirectories of $PWD, so keep that in mind if storage is a concern.

#!/bin/bash
TOOLS=~/Downloads/adt-bundle-linux-x86_64-20130717/sdk/build-tools/19.1.0
AAPT=$TOOLS/aapt
PMLIST=adb_shell_pm_list_packages_-f.txt
TEMP=$(echo $(adb shell mktemp -d -p /data/local/tmp) | sed 's/\r//')
mkdir -p packages
[ -f $PMLIST ] || eval $(echo $(basename $PMLIST) | tr '_' ' ') > $PMLIST
while read line; do
 package=${line##*:}
 apk=${package%%=*}
 name=${package#*=}
 copy=packages$apk
 mkdir -p $(dirname $copy)
 if [ ! -s $copy ]; then  # copy it because `adb pull` doesn't see /mnt/expand/
  adb shell cp -f $apk $TEMP/copy.apk
  adb pull $TEMP/copy.apk $copy
 fi
 label=$($AAPT dump badging $copy || echo ERROR in $copy >&2 | \
  sed -n 's/^application-label:\(.\)\(.*\)\1$/\2/p')
 echo $name:$label
done < <(sed 's/\r//' $PMLIST)
adb shell rm -rf $TEMP
jcomeau_ictx
  • 37,688
  • 6
  • 92
  • 107
1

So I extremely grateful to jcomeau_ictx for providing the info on how to extract application-label info from apk and the idea to pull apk from phone directly! However I had to make several alteration to script it self:

  1. while read line; do done are breaking as a result of commands within while loop interacting with stdin/stdout and as a result while loop runs only once and then stops, as it is discussed in While loop stops reading after the first line in Bash - the comment from cmo I used solution provided and switched while loop to use unused file descriptor number 9.
  2. All that the script really need is a package name and adb shell pm list packages -f is really excessive so I changed it to expect a file with packages list only and provided example on how one can get one from adb.
  3. jcomeau_ictx script variant do not take in to account that some packages may have multiple apk associated with them which breaks the script.
  4. And the least and last, I made every variable to start with underscore, it's just something that makes it easier to read script.

So here another variant of the same script:

#!/bin/bash
_TOOLS=/opt/android-sdk-update-manager/build-tools/29.0.3
_AAPT=${_TOOLS}/aapt
#adb shell pm list packages --user 0 | sed -e 's|^package:||' | sort >./packages_list.txt
_PMLIST=packages_list.txt
rm ./packages_list_with_names.txt
_TEMP=$(echo $(adb shell mktemp -d -p /data/local/tmp) | sed 's/\r//')
mkdir -p packages
[ -f ${_PMLIST} ] || eval $(echo $(basename ${_PMLIST}) | tr '_' ' ') > ${_PMLIST}
while read -u 9 _line; do
    _package=${_line##*:}
    _apkpath=$(adb shell pm path ${_package} | sed -e 's|^package:||' | head -n 1)
    _apkfilename=$(basename "${_apkpath}")
    adb shell cp -f ${_apkpath} ${_TEMP}/copy.apk
    adb pull ${_TEMP}/copy.apk ./packages
    _name=$(${_AAPT} dump badging ./packages/copy.apk | sed -n 's|^application-label:\(.\)\(.*\)\1$|\2|p' )
#'
    echo "${_package} - ${_name}" >>./packages_list_with_names.txt
done 9< ${_PMLIST}
adb shell rm -rf $TEMP
hash
  • 11
  • 1
  • What about `sed --silent --regexp-extended "s/^application-label:'(.*)'$/\1/p"`? I think, it's easier to understand (I mean single quotes in clear text). And thank you for your script enhancements. – Andrei Korshikov Mar 18 '23 at 20:34
  • Yes, that's also works, about easy to read, all depends on what you used to, for me it's easier to read with shielding backslash. – hash Mar 19 '23 at 21:47