#!/bin/bash # Push files to Android device via ADB # Author: Naomi Carrigan & Hikari 💕 set -euo pipefail # Color codes for pretty output RED='\033[0;31m' GREEN='\033[0;32m' BLUE='\033[0;34m' YELLOW='\033[1;33m' NC='\033[0m' # No Color # Function to display usage usage() { echo -e "${BLUE}Usage: $0 [source_file/directory] [android_destination]${NC}" echo -e "${YELLOW}If no arguments provided, interactive mode will start${NC}" echo "" echo "Common Android paths:" echo " /sdcard/Download/ - Downloads folder" echo " /sdcard/DCIM/ - Camera folder" echo " /sdcard/Pictures/ - Pictures folder" echo " /sdcard/Documents/ - Documents folder" echo " /sdcard/Music/ - Music folder" echo "" echo "Examples:" echo " $0 photo.jpg /sdcard/Pictures/" echo " $0 ~/Documents/file.pdf /sdcard/Download/" echo " $0" exit 1 } # Function to check if ADB is installed and device is connected check_adb() { if ! command -v adb &> /dev/null; then echo -e "${RED}❌ Error: ADB is not installed or not in PATH${NC}" echo "Please install Android Debug Bridge (ADB) first" exit 1 fi # Check if device is connected if ! adb devices | grep -q "device$"; then echo -e "${RED}❌ Error: No Android device connected${NC}" echo "Please connect your device and enable USB debugging" echo "" echo "Current devices:" adb devices exit 1 fi } # Function to validate Android path validate_android_path() { local path="$1" # Check if path starts with / if [[ ! "$path" =~ ^/ ]]; then echo -e "${YELLOW}⚠️ Warning: Path doesn't start with /, prepending /sdcard/${NC}" path="/sdcard/$path" fi # Check if destination exists (create if it's a directory) if [[ "$path" =~ /$ ]]; then adb shell "mkdir -p '$path' 2>/dev/null || true" else # Check if parent directory exists local parent_dir=$(dirname "$path") adb shell "mkdir -p '$parent_dir' 2>/dev/null || true" fi echo "$path" } # Interactive mode interactive_mode() { echo -e "${BLUE}🚀 ADB Push - Interactive Mode${NC}" echo "" # Get source file/directory read -p "Enter source file/directory path: " -e source_path # Expand tilde and validate source source_path="${source_path/#\~/$HOME}" if [[ ! -e "$source_path" ]]; then echo -e "${RED}❌ Error: Source '$source_path' does not exist${NC}" exit 1 fi # Show common destinations echo "" echo -e "${YELLOW}Common Android destinations:${NC}" echo "1) /sdcard/Download/" echo "2) /sdcard/Pictures/" echo "3) /sdcard/DCIM/" echo "4) /sdcard/Documents/" echo "5) /sdcard/Music/" echo "6) /sdcard/Movies/" echo "7) Custom path" echo "" read -p "Select destination (1-7): " choice case $choice in 1) dest_path="/sdcard/Download/" ;; 2) dest_path="/sdcard/Pictures/" ;; 3) dest_path="/sdcard/DCIM/" ;; 4) dest_path="/sdcard/Documents/" ;; 5) dest_path="/sdcard/Music/" ;; 6) dest_path="/sdcard/Movies/" ;; 7) read -p "Enter custom destination path: " -e dest_path ;; *) echo -e "${RED}❌ Invalid choice${NC}" exit 1 ;; esac # Push the file/directory push_to_android "$source_path" "$dest_path" } # Function to push files to Android push_to_android() { local source="$1" local dest="$2" # Validate destination path dest=$(validate_android_path "$dest") echo -e "${BLUE}📦 Pushing to Android device...${NC}" echo "Source: $source" echo "Destination: $dest" echo "" # Check if source is directory if [[ -d "$source" ]]; then echo -e "${YELLOW}Pushing directory...${NC}" # For directories, adb push handles recursion automatically if adb push "$source" "$dest"; then echo -e "${GREEN}✅ Directory pushed successfully!${NC}" else echo -e "${RED}❌ Failed to push directory${NC}" exit 1 fi else # Single file if adb push "$source" "$dest"; then echo -e "${GREEN}✅ File pushed successfully!${NC}" # Show file info on device if [[ "$dest" =~ /$ ]]; then # Destination is a directory filename=$(basename "$source") full_path="${dest}${filename}" else # Destination is a file full_path="$dest" fi echo "" echo -e "${BLUE}📱 File on device:${NC}" adb shell "ls -lh '$full_path'" 2>/dev/null || true else echo -e "${RED}❌ Failed to push file${NC}" exit 1 fi fi } # Main script main() { check_adb if [[ $# -eq 0 ]]; then # No arguments, run interactive mode interactive_mode elif [[ $# -eq 1 ]]; then if [[ "$1" == "-h" ]] || [[ "$1" == "--help" ]]; then usage else echo -e "${RED}❌ Error: Missing destination path${NC}" usage fi elif [[ $# -eq 2 ]]; then # Arguments provided source_path="${1/#\~/$HOME}" if [[ ! -e "$source_path" ]]; then echo -e "${RED}❌ Error: Source '$source_path' does not exist${NC}" exit 1 fi push_to_android "$source_path" "$2" else echo -e "${RED}❌ Error: Too many arguments${NC}" usage fi } main "$@"