23

I'm looking for a possibility to retrieve both, the package names and the common names of apps installed on an Android device via ADB – or at least to retrieve the common name if the package name is known. A quick search on our site brought up two related questions, but they don't solve my issue:

I'm looking for a way to retrieve the information directly from the device, if possible – not "any" way (including "web lookups" or "via an app") as those two questions have it.

I know there are multiple tools available to obtain package details:

  • adb dumpsys package: While this lists all packages with a bunch of details, the "common name" is not shown
  • adb shell pm list: only gives the package names
  • aapt would be able to obtain the common name, but would require to first pull the .apk file from the device, which is not really convenient (and obviously will be pretty slow with many and/or large apps installed)

Did I miss something? I know the information must be on the device (how else could it show the app names in the GUI? I doubt Android parses the .apk file each time the GUI need the "common name"). So is there a way to get hold of it, using ADB directly?


TL;DR

Background (if somebody's curious): I want to be able to quickly obtain a list of user-apps from any of my devices, without having to revert to acrobatics. A list of their package names I can retrieve using adb shell pm list -3, but as those are package names only, recognizing apps is a guess-work. So if there were some ADB command to retrieve the common name for a given package name, I could simply use a loop like for pkg in $(adb shell pm list -3); do echo "- $(adb <whatever_the_command_is> $pkg) ($pkg)"; done – and get a listing of all the installed user-apps in a "human readable format" together with their package names.

Use-cases:

  • See what "superflous" apps are installed (which I could remove)
  • Cross-check lists from multiple devices
  • Documentation ;)
  • and probably more (but the above 3 are what I need it for)
11
  • Just an ideea (I think you tried already?). Why you just don't compile aapt for android and run instead from shell? :D
    – ares777
    May 13, 2015 at 10:15
  • 1
    @user3344236 I'm aware of that possibility; but it is not always an option to install something to the device in question, especially not a self-compiled binary (I sometimes get handed-in devices which are not rooted, and have to keep "forensics-like conditions" – i.e. "do not alter the device, just explore it").
    – Izzy
    May 13, 2015 at 10:37
  • So the second idea is to write yourself a tool which runs via adb shell... without using modified adbd on device and without pushing some files there. I think it will take you some time to accomplish this (if ever you succeed) :D
    – ares777
    May 13, 2015 at 10:50
  • @user3344236 too worrysome, especially as I'm not an Android dev. I currently use a "web based solution" (similar to that "Google Play lookup"), as there doesn't seem to be a native solution here (yet?).
    – Izzy
    May 13, 2015 at 12:22
  • Hi Izzy! Considering the comments (above), does it mean that you need a solution considering a non-rooted device in mind?
    – Firelord
    Jun 24, 2015 at 15:13

4 Answers 4

12

Here is my solution for a non-rooted phone which needed some slight changes from above which I ran on a Moto G 2nd gen running Android 5.0.2.

I didn't have aapt binary in /system/bin, so I first tried downloading from https://android.izzysoft.de/downloads

but when I tried to run it, I got an error saying:

error: only position independent executables (PIE) are supported.

So then I searched for a PIE version and found: https://github.com/Calsign/APDE/blob/fdc22eb31048862e1484f4b6eca229accda61466/APDE/src/main/assets/aapt-binaries/aapt-arm-pie

and this worked by copying binary to /data/local/tmp:

adb push aapt-arm-pie /data/local/tmp
adb shell chmod 0755 /data/local/tmp/aapt-arm-pie

So then:

adb shell pm list packages -3 -f

gets a list of 3rd party apps (apps you have installed, not system apps) and then you can use the package from the command above in aapt to get information on the package - example:

adb shell /data/local/tmp/aapt-arm-pie d badging /data/app/com.facebook.katana-3/base.apk

So, below is a script (for a Linux client) to get just "common" name for 3rd party apps:

for pkg in `adb shell pm list packages -3 -f | awk -F= '{sub("package:","");print $1}'`
do
  adb shell /data/local/tmp/aapt-arm-pie d badging $pkg | awk -F: '
      $1 == "application-label" {print $2}'
done

If you want package and version too, then change last but one line from:

$1 == "application-label" {print $2}'

to:

$1 == "package" { split($2,space," ")
name=space[1];version=space[3]}
$1 == "application-label" {print name, version, $2 }'

Example output:

name='com.ultimarom.launchnavigation' versionName='1.28' 'Navigation'
name='com.enhanced.skineditorstudio' versionName='3.3' 'Custom Skin Creator'
name='com.mojang.minecraftpe' versionName='1.2.6.60' 'Minecraft'
name='org.videolan.vlc' versionName='2.5.13' 'VLC'
name='com.jrustonapps.myauroraforecast' versionName='1.7.2' 'My Aurora Forecast'
name='de.j4velin.wifiAutoOff' versionName='1.7.6' 'WiFi Automatic'
name='com.facebook.katana' versionName='153.0.0.54.88' 'Facebook'
name='com.metago.astro' versionName='6.0.5' 'ASTRO File Manager'
name='za.co.hardrive.smartinfo.parkrun' versionName='2.0.2' 'My 5krun'
name='com.PYOPYO.StarTrackerVR' versionName='1.0.1' 'StarTracker VR'
name='cz.aponia.bor3.offlinemaps' versionName='1.1.19' 'Offline Maps'
name='com.groupon' versionName='16.11.63973' 'Groupon'
name='com.ebay.mobile' versionName='5.16.1.2' 'eBay'
name='com.runtastic.android' versionName='8.1.1' 'Runtastic
name='com.google.android.diskusage' versionName='3.8.3' 'DiskUsage'
1
  • PS: My download page now also links to the source you've specified – just "one level up", so folks can chose between ARM and x86 builds.
    – Izzy
    Jan 6, 2018 at 16:14
7

This is not a final answer, as it is not generic (only works on some devices) – but it's a start at least:

As we've figured out, at least CM based ROMs with Kitkat (Android 4.4) and above ship with the aapt binary available in /system/bin1. If your ROM doesn't have it, and installing the binary on the device is an option, you can find it here.

Using aapt, retrieving the app name is possible with

aapt d badging <path to apk> | grep "application: label" |awk '{print $2}'

The output will be something like label='Funny App', which you then easily can parse for the app name, e.g.

aapt d badging <path to apk> | grep 'application: label' | sed -n \"s/.*label\='\([^']*\)'.*/\1/p\"

(not good if the app name contains single quotes, but that might count as cosmetics – or you figure how to improve the sed part to deal with that).


1: we didn't find this in the Kitkat-and-above stock ROMs we've checked, so it might be CM based ROMs only

2
  • 5
    Note to readers: You need not to have a rooted device to use that aapt binary. You can very well download and rename the binary to aapt in PC, set Linux compatible executable permission on the binary and push it to /data/local/tmp, then use the absolute path /data/local/tmp/aapt to use the binary in those commands.
    – Firelord
    Jan 9, 2016 at 18:48
  • So for the name of the package (first part of the original question), you would do aapt d badging <path to apk> | grep 'package: name' | awk '{print $2}'
    – gmoz22
    Nov 14, 2019 at 23:19
4

This can be achieved with Android Java API:

import android.app.ActivityThread;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Looper;

public class Main {
  public static void main(String[] args) {
    Looper.prepareMainLooper();
    PackageManager pm = ActivityThread.systemMain().getSystemContext().getPackageManager();
    for (ApplicationInfo appInfo : pm.getInstalledApplications(PackageManager.MATCH_UNINSTALLED_PACKAGES)) {
      System.out.println(appInfo.uid + " " + appInfo.packageName + " " + pm.getApplicationLabel(appInfo));
    }
  }
}

Compile the code to a dex file, push it to /data/local/tmp/list_app_labels.dex, and run from ADB shell:

CLASSPATH=/data/local/tmp/list_app_labels.dex app_process / Main

It should print the UID, package name and app label of installed apps like this:

10099 com.android.packageinstaller Package installer
1002 com.android.bluetooth Bluetooth
1073 com.android.networkstack.permissionconfig com.android.server.NetworkPermissionConfig
10230 com.topjohnwu.magisk Magisk
10087 com.android.providers.blockednumber Blocked Numbers Storage
10176 com.termux.widget Termux:Widget
...

If you don't want to compile the code, here are convenience methods:

Option 1

Download the pre-compiled executable (for arm64 or arm), extract the zip file, push the binary to Android device, and run:

adb push list_app_labels /data/local/tmp/ && adb shell 'cd /data/local/tmp/ && chmod a+x list_app_labels && ./list_app_labels'

Option 2

Push the given script to Android device and run:

adb push list_app_labels.sh /data/local/tmp/ && adb shell sh /data/local/tmp/list_app_labels.sh

Tested on Android 7-13.

Note:

  • Do not change the script. tail extracts the dex from a hard-coded line number.
  • If you are on Windows, run dos2unix on the shell script before executing.

list_app_labels.sh:

#!/system/bin/sh

export CLASSPATH=/data/local/tmp/list_app_labels.dex
trap 'rm $CLASSPATH' EXIT
tail -n +10 "$0" | base64 -d >$CLASSPATH

app_process / Main
exit

ZGV4CjAzNwAEZ8DOwPQFGurk/iOA5Ry9+z0tMCP1fzNMCAAAcAAAAHhWNBIAAAAAAAAAAKwHAAAx
AAAAcAAAABQAAAA0AQAADwAAAIQBAAADAAAAOAIAABMAAABQAgAAAgAAAOgCAAAkBQAAKAMAAFoE
AABdBAAAZQQAAGgEAABrBAAAbwQAAHMEAAB7BAAAmQQAALQEAADPBAAA9QQAABoFAAAvBQAAQQUA
AFgFAAByBQAAhgUAAJoFAAC1BQAAyQUAAN8FAADxBQAA/AUAAP8FAAADBgAABgYAABsGAAAfBgAA
JwYAAC0GAAAyBgAARwYAAGEGAAB0BgAAhgYAAI8GAACZBgAAnwYAAKUGAACqBgAAtwYAALsGAADO
BgAA1wYAAOMGAADtBgAA8gYAAFkHAAACAAAABgAAAAcAAAAIAAAACQAAAAoAAAALAAAADAAAAA0A
AAAOAAAADwAAABAAAAARAAAAEgAAABMAAAAUAAAAFQAAABcAAAAZAAAAGgAAAAMAAAACAAAAAAAA
AAMAAAADAAAAAAAAAAMAAAAGAAAAAAAAAAUAAAAKAAAANAQAAAMAAAALAAAAAAAAAAMAAAAMAAAA
AAAAAAQAAAANAAAAPAQAAAUAAAANAAAARAQAAAUAAAANAAAATAQAAAMAAAAPAAAAAAAAAAQAAAAQ
AAAAPAQAABcAAAARAAAAAAAAABgAAAARAAAATAQAABgAAAARAAAAVAQAABkAAAASAAAAAAAAAAUA
DAAoAAAABQAAAC4AAAAOAAkAJwAAAAEACwABAAAAAQANACUAAAACAAEAIgAAAAIAAAAsAAAABAAC
ACEAAAAGAAMAHwAAAAYACgAgAAAABwALACoAAAAIAAsAAQAAAAkADAArAAAACwALAAEAAAANAAsA
AQAAAA0ABgAcAAAADQAHABwAAAANAAgAHAAAAA0ABQAtAAAADwAOACMAAAAPAAQAJgAAABAACQAk
AAAAAQAAAAEAAAALAAAAAAAAABYAAAAAAAAAkQcAAAAAAAAIAAAAEQAAAAsAAAAAAAAA/////wAA
AACfBwAAAAAAAAEAAQABAAAAEAQAAAQAAABwEAoAAAAOAAkAAQACAAAAFAQAAFMAAABxAAcAAABx
AAMAAAAMAG4QAgAAAAwAbhAEAAAADAETAgAgbiAGACEADAJyEBIAAgAMAnIQEAACAAoDOAM1AHIQ
EQACAAwDHwMFAGIEAgAiBQ0AcBALAAUAUjYBAG4gDABlAAwFGgYAAG4gDgBlAAwFVDcAAG4gDgB1
AAwFbiAOAGUADAVuIAUAMQAMBm4gDQBlAAwFbhAPAAUADAVuIAkAVAAoyA4AAAABAAEAAQAAAAAA
AAAEAAAAcBAKAAAADgAHAA4ACgEeDjyIAwAfBUwDASoHARYPAwMcBgEsDwUDHgAAAAABAAAABQAA
AAEAAAAAAAAAAQAAAAsAAAABAAAADAAAAAEAAAATAAEgAAY8aW5pdD4AAUkAAUwAAkxJAAJMTAAG
TE1haW47ABxMYW5kcm9pZC9hcHAvQWN0aXZpdHlUaHJlYWQ7ABlMYW5kcm9pZC9hcHAvQ29udGV4
dEltcGw7ABlMYW5kcm9pZC9jb250ZW50L0NvbnRleHQ7ACRMYW5kcm9pZC9jb250ZW50L3BtL0Fw
cGxpY2F0aW9uSW5mbzsAI0xhbmRyb2lkL2NvbnRlbnQvcG0vUGFja2FnZU1hbmFnZXI7ABNMYW5k
cm9pZC9vcy9Mb29wZXI7ABBMY29tL21pcmZhdGlmL1I7ABVMamF2YS9pby9QcmludFN0cmVhbTsA
GExqYXZhL2xhbmcvQ2hhclNlcXVlbmNlOwASTGphdmEvbGFuZy9PYmplY3Q7ABJMamF2YS9sYW5n
L1N0cmluZzsAGUxqYXZhL2xhbmcvU3RyaW5nQnVpbGRlcjsAEkxqYXZhL2xhbmcvU3lzdGVtOwAU
TGphdmEvdXRpbC9JdGVyYXRvcjsAEExqYXZhL3V0aWwvTGlzdDsACU1haW4uamF2YQABVgACVkwA
AVoAE1tMamF2YS9sYW5nL1N0cmluZzsAAmFpAAZhcHBlbmQABGFyZ3MAA2N4dAATZ2V0QXBwbGlj
YXRpb25MYWJlbAAYZ2V0SW5zdGFsbGVkQXBwbGljYXRpb25zABFnZXRQYWNrYWdlTWFuYWdlcgAQ
Z2V0U3lzdGVtQ29udGV4dAAHaGFzTmV4dAAIaXRlcmF0b3IABG1haW4ABG5leHQAA291dAALcGFj
a2FnZU5hbWUAAnBtABFwcmVwYXJlTWFpbkxvb3BlcgAHcHJpbnRsbgAKc3lzdGVtTWFpbgAIdG9T
dHJpbmcAA3VpZABlfn5EOHsiYmFja2VuZCI6ImRleCIsImNvbXBpbGF0aW9uLW1vZGUiOiJkZWJ1
ZyIsImhhcy1jaGVja3N1bXMiOnRydWUsIm1pbi1hcGkiOjI0LCJ2ZXJzaW9uIjoiMy4zLjgzIn0A
Nn5+fnsiTE1haW47IjoiNzg1NDY5ZTYiLCJMY29tL21pcmZhdGlmL1I7IjoiNjExMjVkMjEifQAA
AAIAAIGABKgGAQnABgAAAQAIgoAE+AcAAAANAAAAAAAAAAEAAAAAAAAAAQAAADEAAABwAAAAAgAA
ABQAAAA0AQAAAwAAAA8AAACEAQAABAAAAAMAAAA4AgAABQAAABMAAABQAgAABgAAAAIAAADoAgAA
ASAAAAMAAAAoAwAAAyAAAAIAAAAQBAAAARAAAAUAAAA0BAAAAiAAADEAAABaBAAAACAAAAIAAACR
BwAAABAAAAEAAACsBwAA
8
  • Hi! Just for the sake of curiosity and also clarity, do I get it right that the embedded Base64-encoded content is a Dalvik executable?
    – Andrew T.
    Feb 20, 2023 at 2:30
  • @AndrewT. Yes.. Feb 20, 2023 at 6:22
  • @IrfanLatif for transparency it would be nice to add the source code
    – Wanted
    Mar 29, 2023 at 18:19
  • 1
    @Wanted Java isn't compiled to a binary format. Java bytecode is as transparent as its source code is. I even don't have the source code. It would be a simple two liner loop calling getInstalledApplications and printing the required info to the terminal. Mar 29, 2023 at 20:55
  • 1
    Added decompiled code from @IrfanLatif for completness: gist.github.com/wanted0/6a54f08f78735ddfdec2622dc74c17fd
    – Wanted
    Mar 31, 2023 at 17:08
2

None of the suggestions were particularly good for me, so after some fiddling, here's my 100% on-device solution using Termux:

Get Termux and install adb and aapt through its package manager:

pkg install android-tools aapt

You need to be connected to a Wi-Fi network - any network will do - to pair Termux's ADB to your phone for "wireless" debugging.

Now here's the script I've made, with comments to make it easier to read and tweak (and also for me to understand as I've never been that good at shell scripting):

# ,- list all packages including APK path, in the format: package:/data/.../path/to.apk=com.package.name
# |  note that the path to the APK includes equals signs
# |  
# |                                              ,- replace the last "=" (before the package name) with a ":"
# |                                              |
# |                                              |                       ,- remove leading "package:"
# |                                              |                       |                              ,- parse into shell vars $apk and $pkgname
# |                                              |                       |                              |
adb shell cmd package list packages -f | sed -e 's/=\([^=]*\)$/:\1/' -e 's/^package://' - | while IFS=: read -r apk pkgname; do
  # get label using aapt and filter out just the label with sed
  label=$(aapt dump badging $apk | sed --quiet --expression='s/^application-label://p')
  echo "pkgname: $pkgname"
  echo "apk: $apk"
  echo "label: $label"
  echo ""
done

Save this to a file somewhere in the termux home folder for easy access (e.g. ~/list.sh), and run it with sh list.sh

It takes about a second per app for aapt to process the apk, but it doesn't need to copy it anywhere - it accesses the apk directly where it is. The output is easily tweakable in the script as it's just a few echo commands. You can also change which files get listed by changing the arguments of adb shell cmd package, e.g. by adding -3, but be sure to keep the -f flag.

This may not be useful for the original question asker, but I do hope it would be useful to others!

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .