Get Android App Sizes with ADB

1 minute read

Upon receiving a notification from my NVidia Shield indicating that it was running low on storage space, I attempted to use the device’s interface to troubleshoot the issue.
I found the interface to be cumbersome and unintuitive. Fortunately, I had recently enabled the Android Debug Bridge (ADB) for the purpose of automating tasks, so I decided to utilize it to solve the problem.

Connecting

$ adb connect shield.local

Complete whatever prompts pop up on the device

Script

#!/bin/bash
set -euo pipefail

get_field() {
  # Find correct field
  RES="$(echo "$1" | perl -ne 'print $1,$/ if /^'"$2"': (.+)$/')"
  # If numeric values, translate from bytes into GB with 0.1 percision
  if [[ -n "${3:-}" ]]; then
    RES="$(echo "$RES" | jq '. | map(. / 1024 / 1024 / 1024 | (. * 10 | floor | . / 10)) ')"
  fi
  # Return
  echo "$RES"
}

# https://android.stackexchange.com/a/220444
RAW="$(adb shell dumpsys diskstats)"

echo '{}' | jq \ 
  --argjson names "$(get_field "$RAW" "Package Names")" \
  --argjson sizes "$(get_field "$RAW" "App Sizes" n)" \
  --argjson data "$(get_field "$RAW" "App Data Sizes" n)" \
  --argjson cache "$(get_field "$RAW" "Cache Sizes" n)" \
  '[$names, $sizes, $data, $cache] | transpose | .[] | {"name": .[0], "app": .[1], "data": .[2], "cache":.[3]} | (.total = .app + .data + .cache)' |
  jq -s 'sort_by(.total) | reverse' | 
  jq -c '.[]'

Results

$ bin/android-app-stats
{"name":"org.xbmc.kodi","app":0.1,"data":1.7,"cache":0,"total":1.8}
{"name":"com.google.android.tvlauncher","app":0,"data":0.1,"cache":0.1,"total":0.2}
{"name":"com.nordvpn.android","app":0.1,"data":0,"cache":0,"total":0.1}
{"name":"com.google.android.gms","app":0.1,"data":0,"cache":0,"total":0.1}
{"name":"com.nvidia.tegrazone3","app":0.1,"data":0,"cache":0,"total":0.1}
{"name":"com.google.android.apps.mediashell","app":0.1,"data":0,"cache":0,"total":0.1}
{"name":"com.google.android.inputmethod.latin","app":0,"data":0,"cache":0,"total":0}
{"name":"com.nvidia.developerwidget","app":0,"data":0,"cache":0,"total":0}
{"name":"com.android.captiveportallogin","app":0,"data":0,"cache":0,"total":0}
{"name":"com.android.providers.contacts","app":0,"data":0,"cache":0,"total":0}
...

With some post-processing:

$ bin/android-app-stats | head | jq '{name, total}' -c
{"name":"org.xbmc.kodi","total":1.8}
{"name":"com.google.android.tvlauncher","total":0.2}
{"name":"com.nordvpn.android","total":0.1}
{"name":"com.google.android.gms","total":0.1}
{"name":"com.nvidia.tegrazone3","total":0.1}
{"name":"com.google.android.apps.mediashell","total":0.1}
{"name":"com.google.android.inputmethod.latin","total":0}
{"name":"com.nvidia.developerwidget","total":0}
{"name":"com.android.captiveportallogin","total":0}
{"name":"com.android.providers.contacts","total":0}

I found out that Kodi is the major offender, and did some spring cleaning.