Skip to content

Instantly share code, notes, and snippets.

@SarahElson
Created November 26, 2025 12:49
Show Gist options
  • Select an option

  • Save SarahElson/05659f15cc2389a3db0fde64c155d996 to your computer and use it in GitHub Desktop.

Select an option

Save SarahElson/05659f15cc2389a3db0fde64c155d996 to your computer and use it in GitHub Desktop.
XAPK , APKM , ZIP converter for MacOs and Linux
#!/bin/bash
# ==============================================================================
# Universal XAPK/APKM Converter (Linux & macOS)
# Runs via: curl -sL <URL> | bash
# ==============================================================================
# --- CONFIGURATION ---
TEMP_DIR="/tmp/xapk_tool"
APKEDITOR_URL="https://github.com/REAndroid/APKEditor/releases/download/V1.4.5/APKEditor-1.4.5.jar"
SIGNER_URL="https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar"
OS_TYPE="$(uname -s)"
# Setup Temp Directory
mkdir -p "$TEMP_DIR"
cd "$TEMP_DIR" || exit
# --- HELPER FUNCTIONS ---
log() {
echo -e "\033[1;32m[INFO]\033[0m $1"
}
error() {
echo -e "\033[1;31m[ERROR]\033[0m $1"
if [[ "$OS_TYPE" == "Darwin" ]]; then
osascript -e "display notification \"$1\" with title \"Error\" sound name \"Basso\""
elif command -v notify-send &> /dev/null; then
notify-send "Error" "$1"
fi
exit 1
}
# --- 1. CHECK REQUIREMENTS ---
if ! command -v java &> /dev/null; then
if [[ "$OS_TYPE" == "Darwin" ]]; then
osascript -e 'display dialog "Java is missing! Please install JDK 17+." buttons {"OK"} default button "OK" with icon stop'
open "https://adoptium.net/temurin/releases/?version=17"
else
echo "Java is missing."
if command -v zenity &> /dev/null; then
zenity --error --text="Java is missing! Please install JDK 17+."
xdg-open "https://adoptium.net/temurin/releases/?version=17" 2>/dev/null
fi
fi
exit 1
fi
# --- 2. FILE SELECTION (GUI) ---
INPUT_FILE=""
if [[ "$OS_TYPE" == "Darwin" ]]; then
# macOS Native Selector
INPUT_FILE=$(osascript -e 'POSIX path of (choose file with prompt "Select .xapk, .apkm, or .zip file:" of type {"xapk", "apkm", "zip"})' 2>/dev/null)
else
# Linux (Zenity)
if command -v zenity &> /dev/null; then
INPUT_FILE=$(zenity --file-selection --title="Select Bundle File" --file-filter="*.xapk *.apkm *.zip")
else
# Fallback to CLI
echo "------------------------------------------------"
echo " GUI (Zenity) not found. Switching to CLI mode."
echo "------------------------------------------------"
read -e -p "Drag & Drop your file here and press Enter: " INPUT_FILE
# Remove single quotes if drag-dropped
INPUT_FILE="${INPUT_FILE%\'}"
INPUT_FILE="${INPUT_FILE#\'}"
fi
fi
if [[ -z "$INPUT_FILE" ]]; then
echo "No file selected. Exiting."
exit 0
fi
log "Selected: $INPUT_FILE"
# --- 3. DOWNLOAD TOOLS ---
if [[ ! -f "APKEditor.jar" ]]; then
log "Downloading APKEditor..."
curl -L -o "APKEditor.jar" "$APKEDITOR_URL" --progress-bar
fi
if [[ ! -f "uber-apk-signer.jar" ]]; then
log "Downloading Uber Signer..."
curl -L -o "uber-apk-signer.jar" "$SIGNER_URL" --progress-bar
fi
# --- 4. CONVERSION ---
log "Step 1/2: Merging..."
TEMP_APK="temp_merged.apk"
rm -f "$TEMP_APK"
java -jar APKEditor.jar m -i "$INPUT_FILE" -o "$TEMP_APK" > /dev/null 2>&1
if [[ ! -f "$TEMP_APK" ]]; then
error "Merge failed. File might be encrypted or corrupted."
fi
log "Step 2/2: Signing..."
java -jar uber-apk-signer.jar --apks "$TEMP_APK" > /dev/null 2>&1
# --- 5. FINALIZE ---
SIGNED_TEMP="temp_merged-aligned-debugSigned.apk"
INPUT_DIR=$(dirname "$INPUT_FILE")
INPUT_NAME=$(basename "$INPUT_FILE")
OUTPUT_NAME="${INPUT_NAME%.*}_Converted.apk"
FINAL_PATH="$INPUT_DIR/$OUTPUT_NAME"
if [[ -f "$SIGNED_TEMP" ]]; then
mv "$SIGNED_TEMP" "$FINAL_PATH"
log "SUCCESS! File saved at: $FINAL_PATH"
# --- 6. SUCCESS POPUP WITH COPY OPTION ---
if [[ "$OS_TYPE" == "Darwin" ]]; then
# macOS Popup
ACTION=$(osascript -e "display dialog \"Conversion Complete!\" & return & return & \"File saved at:\" & return & \"$FINAL_PATH\" buttons {\"OK\", \"Copy Path\"} default button \"OK\" with icon note")
if [[ "$ACTION" == *"Copy Path"* ]]; then
echo -n "$FINAL_PATH" | pbcopy
osascript -e 'display notification "Path copied to clipboard" with title "Success"'
fi
else
# Linux Popup
if command -v zenity &> /dev/null; then
# Zenity Entry allows user to Ctrl+C the text easily
zenity --entry --title="Success!" --text="Conversion Complete! Copy path below:" --entry-text="$FINAL_PATH"
else
echo "Done! Path: $FINAL_PATH"
fi
fi
else
error "Signing failed."
fi
# Cleanup
rm -f "$TEMP_APK"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment