Skip to content

Commit

Permalink
Split APK support!
Browse files Browse the repository at this point in the history
Apps shouldn't be broken after a restore anymore under most circumstances.
  • Loading branch information
mrrfv committed Apr 1, 2024
1 parent 2b99b04 commit d73da8a
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 12 deletions.
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Open Android Backup is a tiny shell script & Flutter app that makes securely bac

The following data types can be automatically restored back to the device.

- Apps (.apk files of installed apps - app data not included - split APK support is experimental and can be found in the `split-apk-support` branch)
- Apps (app data not included due to system limitations)
- Internal storage (pictures, downloads, videos, Signal backups if enabled, etc)
- Contacts (exported in vCard format)

Expand All @@ -33,11 +33,12 @@ These things are the majority of what most people would want to keep safe, but e
- Works on the 3 major operating systems, and supports *any* modern Android device.
- Wireless backups that allow you to normally use your phone while it's being backed up.
- Backs up data not normally accessible through ADB using a native companion app.
- Tiny - the script is 5KB in size, and the companion app is around 15 megabytes.
- Tiny - the whole package is about 20 MB.
- Doesn't use proprietary formats - your data is safe even if you can't run the script. Simply open archives created by this script using 7-Zip.
- Backups are encrypted along with their metadata.
- Optionally securely erases all unencrypted temporary files created by the script.
- All data is compressed using 7-Zip with maximum compression settings.
- All data is compressed using 7-Zip with configurable compression settings.

## Installation

### Linux
Expand Down
14 changes: 10 additions & 4 deletions functions/backup_func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ function backup_func() {
(
apk_path=${app%=*} # apk path on device
apk_path=${apk_path/package:} # strip "package:"
apk_clean_name=$(echo "$app" | awk -F "=" '{print $NF}' | tr -dc '[:alnum:].' | tr '[:upper:]' '[:lower:]') # package name
apk_base="$apk_clean_name-$RANDOM$RANDOM.apk" # apk filename in the backup archive
apk_clean_name=$(echo "$app" | awk -F "=" '{print $NF}' | tr -dc '[:alnum:]_.') # package name
#apk_base="$apk_clean_name-$RANDOM$RANDOM" # apk filename in the backup archive. Unused, removal pending?
# e.g.:
# app=package:/data/app/~~4wyPu0QoTM3AByZS==/org.fdroid.fdroid-iaTC9-W1lyR1FxO==/base.apk=org.fdroid.fdroid
# apk_path=/data/app/~~4wyPu0QoTM3AByZS==/org.fdroid.fdroid-iaTC9-W1lyR1FxO==/base.apk
Expand All @@ -62,8 +62,14 @@ function backup_func() {

echo "Backing up app: $apk_clean_name ($apps_exported/$app_count)"

get_file "$(dirname "$apk_path")" "$(basename "$apk_path")" ./backup-tmp/Apps
mv "./backup-tmp/Apps/$(basename "$apk_path")" "./backup-tmp/Apps/$apk_base" || cecho "Couldn't find app $(basename "$apk_path") after exporting from device - ignoring." 1>&2
# Get all the APKs associated with the package name, including split APKs
# TODO: Ensure the changes made to apk_clean_name don't break this under certain conditions
for apk in $(adb shell pm path "$apk_clean_name" | sed 's/package://g' | tr -d '\r'); do
# Create a directory for the app to store all the APKs
mkdir -p ./backup-tmp/Apps/"$apk_clean_name"
# Save the APK to its directory
get_file "$(dirname "$apk")" "$(basename "$apk")" ./backup-tmp/Apps/"$apk_clean_name"
done
)
done

Expand Down
40 changes: 35 additions & 5 deletions functions/restore_func.sh
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,45 @@ function restore_func() {
cecho "Restoring applications."
# We don't want a single app to break the whole script
set +e
# There's a 15 minute timeout for app installs just in case there is a
# misbehaving app blocking the whole restore process.
# Please note that this doesn't forcibly kill adb, rather it sends a simple SIGTERM signal.
# Apps containing their own directories may contain split APKs, which need to be installed using adb install-multiple.
# Those without directories were created by past versions of this script and need to be imported the traditional way.

# Handle split APKs
# Find directories in the Apps directory
apk_dirs=$(find ./backup-tmp/Apps -mindepth 1 -maxdepth 1 -type d)
for apk_dir in $apk_dirs; do
# Install all APKs in the directory
# the APK files are sorted to ensure that base.apk is installed before split APKs
apk_files=$(find "$apk_dir" -type f -name "*.apk" | sort | tr '\n' ' ')
if [[ "$(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/ip')" ]]; then
cecho "Windows/WSL detected"
# shellcheck disable=SC2086
timeout 900 ./windows-dependencies/adb/adb.exe install-multiple $apk_files
else
cecho "macOS/Linux detected"
# shellcheck disable=SC2086
timeout 900 adb install-multiple $apk_files
fi
done

# Now all that's left is ensuring backwards compatibility with old backups
# Look for APK files in the Apps directory
apk_files=$(find ./backup-tmp/Apps -maxdepth 1 -type f -name "*.apk" | sort)
# Notify if an old backup is being restored
if [ -n "$apk_files" ]; then
cecho "Old backup with no split APKs detected."
fi
# Install all APKs
if [[ "$(uname -r | sed -n 's/.*\( *Microsoft *\).*/\1/ip')" ]]; then
cecho "Windows/WSL detected"
find ./backup-tmp/Apps -type f -name "*.apk" -exec timeout 900 ./windows-dependencies/adb/adb.exe install {} \;
for apk_file in $apk_files; do
timeout 900 ./windows-dependencies/adb/adb.exe install "$apk_file"
done
else
cecho "macOS/Linux detected"
find ./backup-tmp/Apps -type f -name "*.apk" -exec timeout 900 adb install {} \;
for apk_file in $apk_files; do
timeout 900 adb install "$apk_file"
done
fi
set -e

Expand Down

0 comments on commit d73da8a

Please sign in to comment.