Created
November 26, 2025 12:49
-
-
Save SarahElson/05659f15cc2389a3db0fde64c155d996 to your computer and use it in GitHub Desktop.
XAPK , APKM , ZIP converter for MacOs and Linux
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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