A universal Infrared (IR) TV Remote Android application with priority support for Samsung TVs. Built with Kotlin and Jetpack Compose following modern Android development best practices.
- Universal TV Control - Support for Samsung, LG, Sony, Vizio, Panasonic, TCL, Hisense, and more
- Samsung Priority - Comprehensive Samsung TV code coverage
- Offline Operation - No internet connection required
- Modern UI - Built with Jetpack Compose and Material Design 3
- Secure - OWASP Mobile Security compliant, no unnecessary permissions
- Clean Architecture - MVVM pattern with clean separation of concerns
- Android device with built-in IR blaster
- Android 5.0 (API 21) or higher
| Brand | Models |
|---|---|
| Vivo | Various models with IR blaster |
| Xiaomi | Mi/Redmi series |
| Samsung | Galaxy S4, S5, S6, Note series |
| Huawei | Mate/P series (select models) |
| LG | G3, G4, G5, V series |
- Samsung (full remote functionality)
- LG
- Sony
- Vizio
- Panasonic
- TCL
- Hisense
- Sharp
- Toshiba
- Philips
- And more...
Choose your platform:
- Linux / WSL Build (Recommended for developers)
- Windows Build
- macOS Build
Run the automated setup script:
cd /path/to/android-app-tv-remote
./setup-linux.shThis script will:
- Install Java JDK 17
- Download and configure Android SDK
- Set environment variables
- Accept SDK licenses
- Build the APK
APK output: app/build/outputs/apk/debug/app-debug.apk
If you prefer manual installation:
sudo apt update
sudo apt install -y openjdk-17-jdk unzip wget
# Verify installation
java -version# Create Android SDK directory
mkdir -p ~/android-sdk/cmdline-tools
cd ~/android-sdk/cmdline-tools
# Download command line tools
wget https://dl.google.com/android/repository/commandlinetools-linux-11076708_latest.zip
# Unzip and organize
unzip commandlinetools-linux-11076708_latest.zip
mv cmdline-tools latest
rm commandlinetools-linux-11076708_latest.zipAdd to your ~/.bashrc:
echo '' >> ~/.bashrc
echo '# Android SDK Environment Variables' >> ~/.bashrc
echo 'export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64' >> ~/.bashrc
echo 'export ANDROID_HOME=$HOME/android-sdk' >> ~/.bashrc
echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin' >> ~/.bashrc
echo 'export PATH=$PATH:$ANDROID_HOME/platform-tools' >> ~/.bashrc
# Apply changes
source ~/.bashrc# Accept all licenses
yes | sdkmanager --sdk_root=$ANDROID_HOME --licenses
# Install required components
sdkmanager --sdk_root=$ANDROID_HOME "platforms;android-34" "build-tools;34.0.0" "platform-tools"cd /path/to/android-app-tv-remote
# Create local.properties
echo "sdk.dir=$HOME/android-sdk" > local.properties# Make gradlew executable (if needed)
chmod +x ./gradlew
# Build debug APK
./gradlew assembleDebugapp/build/outputs/apk/debug/app-debug.apk
Option A: Using ADB (phone connected via USB)
# Install directly
./gradlew installDebug
# Or manually
adb install app/build/outputs/apk/debug/app-debug.apkOption B: Manual Transfer
- Copy APK to your phone (via USB, cloud, etc.)
- Open the APK file on your phone
- Enable "Install from Unknown Sources" if prompted
- Install and run
Android Studio is recommended for Windows users.
- Download from: https://developer.android.com/studio
- Run the installer
- During setup, ensure these are selected:
- Android SDK
- Android SDK Platform 34
- Android Virtual Device (optional)
- Launch Android Studio
- Click File → Open
- Navigate to the project folder and click OK
- Wait for Gradle sync to complete (5-10 minutes first time)
Method A: Build Menu
- Go to Build → Build Bundle(s) / APK(s) → Build APK(s)
- Wait for build to complete
- Click "locate" in the notification popup
Method B: Keyboard Shortcut
- Press
Ctrl + F9
app\build\outputs\apk\debug\app-debug.apk
Option A: Direct Install via USB
- Connect your phone via USB
- Enable USB Debugging on your phone:
- Settings → About Phone → Tap "Build Number" 7 times
- Settings → Developer Options → Enable USB Debugging
- Click the green Run button (or
Shift + F10) - Select your device
Option B: Transfer APK
- Copy the APK to your phone
- Open and install on the phone
Same as Windows instructions above. Download Android Studio for macOS.
# Install Homebrew (if not installed)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Java 17
brew install openjdk@17
# Set JAVA_HOME
echo 'export JAVA_HOME=$(/usr/libexec/java_home -v 17)' >> ~/.zshrc
source ~/.zshrc
# Install Android SDK via Homebrew
brew install --cask android-commandlinetools
# Set Android environment
echo 'export ANDROID_HOME=$HOME/Library/Android/sdk' >> ~/.zshrc
echo 'export PATH=$PATH:$ANDROID_HOME/cmdline-tools/latest/bin' >> ~/.zshrc
echo 'export PATH=$PATH:$ANDROID_HOME/platform-tools' >> ~/.zshrc
source ~/.zshrc
# Install SDK components
sdkmanager "platforms;android-34" "build-tools;34.0.0" "platform-tools"
yes | sdkmanager --licenses
# Build
cd /path/to/android-app-tv-remote
echo "sdk.dir=$ANDROID_HOME" > local.properties
./gradlew assembleDebug| Command | Description |
|---|---|
./gradlew assembleDebug |
Build debug APK (signed, ready to install) |
./gradlew assembleRelease |
Build release APK (unsigned, smaller) |
./gradlew installDebug |
Build and install on connected device |
./gradlew clean |
Clean build files |
./gradlew test |
Run unit tests |
| Build Type | Location | Notes |
|---|---|---|
| Debug APK | app/build/outputs/apk/debug/app-debug.apk |
Ready to install |
| Release APK | app/build/outputs/apk/release/app-release-unsigned.apk |
Requires signing |
| Feature | Debug | Release |
|---|---|---|
| Size | ~17 MB | ~7 MB |
| Signed | Yes (debug key) | No (unsigned) |
| Install directly | Yes | No (needs signing) |
| Debugging | Enabled | Disabled |
| ProGuard/R8 | Disabled | Enabled (minified) |
For personal use: Use the debug APK - it's signed and ready to install.
For distribution: Sign the release APK using the instructions below.
To create a signed release APK for distribution:
keytool -genkey -v -keystore my-release-key.jks -keyalg RSA -keysize 2048 -validity 10000 -alias my-key-aliasYou'll be prompted for:
- Keystore password
- Key password
- Your name, organization, etc.
Create or edit keystore.properties in the project root:
storeFile=../my-release-key.jks
storePassword=your_keystore_password
keyAlias=my-key-alias
keyPassword=your_key_password# Sign the APK
apksigner sign --ks my-release-key.jks --out app-release-signed.apk app/build/outputs/apk/release/app-release-unsigned.apk
# Verify signature
apksigner verify app-release-signed.apkSecurity Note: Never commit keystore files or passwords to version control.
| Issue | Platform | Solution |
|---|---|---|
SDK location not found |
All | Create local.properties with sdk.dir=/path/to/sdk |
JAVA_HOME not set |
Linux/Mac | Add export JAVA_HOME=/path/to/jdk to shell config |
java: command not found |
Linux | Run sudo apt install openjdk-17-jdk |
gradlew: Permission denied |
Linux/Mac | Run chmod +x ./gradlew |
License not accepted |
All | Run sdkmanager --licenses |
| Gradle sync failed | All | Check internet, try File → Invalidate Caches (Android Studio) |
adb: command not found |
Linux | Ensure platform-tools is in PATH |
app/
├── src/main/
│ ├── java/com/example/tvremote/
│ │ ├── TvRemoteApp.kt # Application class
│ │ ├── MainActivity.kt # Main entry point
│ │ ├── di/ # Dependency injection
│ │ ├── data/
│ │ │ ├── ir/ # IR hardware abstraction
│ │ │ ├── database/ # Room database
│ │ │ └── repository/ # Data repositories
│ │ ├── domain/
│ │ │ ├── model/ # Domain models
│ │ │ ├── repository/ # Repository interfaces
│ │ │ └── usecase/ # Business logic
│ │ └── ui/
│ │ ├── remote/ # Remote control UI
│ │ ├── setup/ # Device setup
│ │ ├── components/ # Reusable components
│ │ └── theme/ # App theming
│ ├── assets/ir_codes/ # IR code databases
│ └── res/ # Android resources
└── build.gradle.kts
The app follows Clean Architecture with MVVM pattern:
┌─────────────────────────────────────────┐
│ Presentation Layer │
│ (Compose UI + ViewModels + States) │
├─────────────────────────────────────────┤
│ Domain Layer │
│ (Use Cases + Repositories) │
├─────────────────────────────────────────┤
│ Data Layer │
│ (Room DB + IR Hardware + JSON Assets) │
└─────────────────────────────────────────┘
| Category | Technology |
|---|---|
| Language | Kotlin 1.9 |
| UI | Jetpack Compose + Material 3 |
| Architecture | MVVM + Clean Architecture |
| DI | Hilt |
| Database | Room |
| Async | Kotlin Coroutines + Flow |
| Build | Gradle Kotlin DSL |
This app is built with security as a priority:
- Minimal Permissions - Only TRANSMIT_IR permission required
- Offline First - No network access, no data collection
- Input Validation - All IR codes validated before transmission
- Code Obfuscation - ProGuard/R8 enabled for release builds
- No WebViews - Eliminates web-based attack vectors
- Secure Storage - EncryptedSharedPreferences for user data
- Launch the app on your IR-enabled device
- Select your TV brand (Samsung recommended first)
- Point your phone at the TV's IR receiver
- Test the power button to verify connectivity
- Use the remote to control your TV
- Keep the phone within 3 meters of the TV
- Point directly at the TV's IR sensor (usually near the power LED)
- If buttons don't work, try alternative code sets for your brand
Contributions are welcome! Please read the development plan in DEVELOPMENT_PLAN.md.
- Add IR codes to
app/src/main/assets/ir_codes/ - Follow the existing JSON schema
- Test on actual hardware before submitting
This project is for personal and educational use.
- IR code patterns from open-source LIRC database
- Android ConsumerIrManager documentation
- Material Design 3 guidelines
Note: This app requires a physical IR blaster. Software-based IR emulation is not supported as it requires specialized hardware.