You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#!/bin/sh
# shellcheck disable=SC3010
# Exit the script if any commands error (return non-zero status code).
# set -e
# Print all commands before running them
# set -x
##
# Global variables and constants.
##
readonly is_debugging_enabled="NO"
readonly apk_id="$1"
# Useful docs: https://www.youtube.com/watch?v=PqgDvAAaTgA
readonly INSTALL_BUTTON_X_COORD="550" # Determined manually for Pixel 3a
readonly INSTALL_BUTTON_Y_COORD="800" # Determined manually for Pixel 3a
##
# Verify script arguments
##
readonly num_args="$#"
if [ ! "${num_args}" -eq 1 ]
then
echo "Wrong number of arguments!"
echo "Expected a single argument (the APK id), but got ${num_args} arguments."
echo "Example usage: \$> getapk com.authy.authy"
exit 1
fi
##
# Verify the number of Android devices available to adb
##
adb_devices_line_count=$(adb devices -l | wc -l)
device_count=$(( adb_devices_line_count - 2 ))
if [ ! "${device_count}" -eq 1 ]
then
echo "Wrong number of Android devices!"
echo "Expected a single Android device in debugging mode, but adb found ${device_count} devices."
exit 1
fi
##
# Debugging echo
##
debug_println() {
# if [[ "${is_debugging_enabled}" = "YES" ]]; then
if [ "${is_debugging_enabled}" = "YES" ]; then
printf "[DEBUG] %s\n" "$1"
fi
}
##
# Return "YES" if the APK is installed on the phone; "NO" otherwise.
##
is_apk_installed() {
# if [[ $(adb shell pm list packages | grep "${apk_id}") ]]
if [ $(adb shell pm list packages | grep "${apk_id}") ]
then
echo "YES"
else
echo "NO"
fi
}
##
# Install the APK from the Google Play Store onto the phone.
##
install_apk() {
##
# Open Google Play app to the entry for the given APK id
#
# Useful docs: https://stackoverflow.com/questions/53157208/automated-installation-of-an-apk-from-the-google-play-store
##
printf "Opening APK's Play Store entry on the phone..."
adb shell "am start -a android.intent.action.VIEW -d market://details?id=${apk_id}" > /dev/null
sleep 1
printf "done.\n"
##
# Tap the 'Install' button
##
printf "Tapping the Install button on the phone..."
adb shell input tap ${INSTALL_BUTTON_X_COORD} ${INSTALL_BUTTON_Y_COORD}
printf "done.\n"
##
# Wait for the app to be installed...
##
printf "Waiting for APK to install on the phone..."
# until [[ $(is_apk_installed) = "YES" ]]
until [ $(is_apk_installed) = "YES" ]
# Useful docs explaining double brackets: https://stackoverflow.com/a/3870055
do
printf "."
sleep 0.5
done
printf "done.\n"
}
##
# Copy the APK from the phone to the laptop.
#
# Useful docs: https://stackoverflow.com/questions/4032960/how-do-i-get-an-apk-file-from-an-android-device
##
download_apk() {
echo "Downloading APK file(s) from the phone..."
remote_apk_paths=$(adb shell pm path "${apk_id}")
readonly remote_apk_paths
debug_println "remote_apk_paths = ${remote_apk_paths}"
# The xargs is there to trim the whitespace from the line count
path_count=$(echo "${remote_apk_paths}" | wc -l | xargs)
readonly path_count
debug_println "path_count = ${path_count}"
# if [[ ${path_count} -eq 0 ]]; then
if [ ${path_count} -eq 0 ]; then
echo "APK with id ${apk_id} is not installed on the phone!"
fi
# Get APK package information, grep the versionName, split on '=', and
# return the left hand value (the APK version).
apk_version=$(
adb shell dumpsys package "${apk_id}" | \
grep versionName | \
awk -F '=' '{print $2}'
)
readonly apk_version
readonly apk_versioned_name_base="${apk_id}@v${apk_version}"
# Make the output directory in which to save the APK(s) and checksum(s)
readonly output_dir="${apk_versioned_name_base}/apk"
mkdir -p "${output_dir}"
path_number=1
for line in ${remote_apk_paths}; do
debug_println "Line = ${line}"
remote_apk_path=$(echo "${line}" | awk -F ':' '{print $2}')
debug_println "Remote APK path = ${remote_apk_path}"
# Return everything from remote_apk_path after the final slash "/"
remote_apk_filename="${remote_apk_path##*/}"
debug_println "Remote APK filename = ${remote_apk_filename}"
# if [[ "${remote_apk_filename}" = "base.apk" ]]; then
if [ "${remote_apk_filename}" = "base.apk" ]; then
local_apk_path="${output_dir}/${apk_versioned_name_base}-playstore.apk"
else
# Split into an array using period delimiter and return the second index.
# Filenames for multipart APKs look like: "split_config.en.apk"
multipart_apk_filename_part=$(echo "${remote_apk_filename}" | awk -F '.' '{print $2}')
debug_println "Multipart APK filename part = ${multipart_apk_filename_part}"
local_apk_path="${output_dir}/${apk_id}-${multipart_apk_filename_part}@${apk_version}-playstore.apk"
fi
debug_println "Local APK path = ${local_apk_path}"
# Copy the APK from the phone to the laptop
adb pull "${remote_apk_path}" "${local_apk_path}" > /dev/null
printf "APK (%s/%s) downloaded to:\n%s\n" "${path_number}" "${path_count}" "${local_apk_path}"
# Record the sha256 checksum of the downloaded APK
shasum --algorithm 256 --binary "${local_apk_path}" > "${local_apk_path}.sha256"
path_number=$(( path_number + 1))
done
}
main() {
echo "Getting APK from the Play Store with id: $apk_id..."
# if [[ $(is_apk_installed) = "YES" ]]
if [ $(is_apk_installed) = "YES" ]
then
echo "APK is already installed on the phone."
else
echo "Installing APK on the phone..."
install_apk
fi
download_apk
}
main
The text was updated successfully, but these errors were encountered:
The text was updated successfully, but these errors were encountered: