I am batman
This commit is contained in:
271
modules/android/README.md
Normal file
271
modules/android/README.md
Normal file
@@ -0,0 +1,271 @@
|
||||
# Android Development Module for NixOS
|
||||
|
||||
This module provides Android development environment setup using NixOS-specific approaches that respect the immutable filesystem while maintaining full functionality.
|
||||
|
||||
## Features
|
||||
|
||||
- **Android Studio Full** - Includes FHS environment for compatibility
|
||||
- **androidenv** - Declarative Android SDK management (reproducible)
|
||||
- **Android Emulator** - Optimized for NixOS with GPU acceleration
|
||||
- **Flutter SDK** - Optional Dart and Flutter support
|
||||
- **Build Tools** - Gradle, Maven, Kotlin, Java
|
||||
- **Additional Tools** - scrcpy for device screen sharing, APK signing utilities
|
||||
|
||||
## Configuration
|
||||
|
||||
Add to your `home.nix`:
|
||||
|
||||
```nix
|
||||
modules.android = {
|
||||
enable = true;
|
||||
enableEmulator = true;
|
||||
apiLevel = 34;
|
||||
enableFlutterSupport = true;
|
||||
};
|
||||
```
|
||||
|
||||
## Configuration Options
|
||||
|
||||
- **enable** - Master switch for the module
|
||||
- **enableEmulator** - Include Android emulator (default: true)
|
||||
- **apiLevel** - Default Android API level (default: 34)
|
||||
- **enableFlutterSupport** - Install Flutter SDK (default: true)
|
||||
|
||||
## Why This Approach is Better for NixOS
|
||||
|
||||
### Problem with Standard Android Tools on NixOS
|
||||
|
||||
NixOS uses an immutable filesystem and unique file structure that standard Android tools struggle with:
|
||||
- Expected `/system`, `/data`, `/cache` paths don't exist
|
||||
- SDK expects mutable `/opt` directories
|
||||
- Dynamic library linking issues
|
||||
|
||||
### Solution: NixOS-Specific Tools
|
||||
|
||||
**android-studio-full** - The recommended approach for NixOS
|
||||
- Provides FHS (Filesystem Hierarchy Standard) environment
|
||||
- Works out-of-the-box with proper file hierarchy
|
||||
- Pre-configured with SDK, emulator, and build tools
|
||||
- Manages mutable state in `~/.android` directory
|
||||
- No immutability conflicts
|
||||
|
||||
## Initial Setup
|
||||
|
||||
After applying the module:
|
||||
|
||||
```bash
|
||||
# Accept Android licenses
|
||||
android-setup
|
||||
|
||||
# Or manually
|
||||
yes | sdkmanager --licenses
|
||||
|
||||
# Create and start emulator
|
||||
android-emulator
|
||||
|
||||
# Verify Flutter setup
|
||||
flutter doctor
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Launch Emulator
|
||||
|
||||
```bash
|
||||
# Default emulator (flutter-dev, API 34)
|
||||
android-emulator
|
||||
|
||||
# Custom name
|
||||
android-emulator my-device
|
||||
|
||||
# Custom name and API level
|
||||
android-emulator my-device 33
|
||||
```
|
||||
|
||||
### Launch Android Studio
|
||||
|
||||
```bash
|
||||
android-studio
|
||||
```
|
||||
|
||||
### Flutter Development
|
||||
|
||||
```bash
|
||||
# Create new project
|
||||
flutter create my_app
|
||||
|
||||
# Run on emulator
|
||||
cd my_app
|
||||
flutter run
|
||||
|
||||
# Run with verbose output
|
||||
flutter run -v
|
||||
```
|
||||
|
||||
### Physical Device Development
|
||||
|
||||
```bash
|
||||
# Check connected devices
|
||||
adb devices
|
||||
|
||||
# Screen sharing (requires scrcpy)
|
||||
scrcpy
|
||||
|
||||
# View logs
|
||||
adb logcat
|
||||
```
|
||||
|
||||
## Available API Levels
|
||||
|
||||
The module includes these Android API levels by default:
|
||||
- API 28 (Android 9)
|
||||
- API 31 (Android 12)
|
||||
- API 33 (Android 13)
|
||||
- API 34 (Android 14)
|
||||
- API 35 (Android 15)
|
||||
|
||||
To use a specific API level:
|
||||
|
||||
```bash
|
||||
android-emulator test-device 31
|
||||
android-emulator latest 35
|
||||
```
|
||||
|
||||
## Build Tools
|
||||
|
||||
Included by default:
|
||||
- Gradle (build system)
|
||||
- Maven (alternative build system)
|
||||
- Kotlin compiler
|
||||
- Java JDK (11 and 21)
|
||||
- CMake, Ninja, GNU Make
|
||||
|
||||
## Hyprland Keybind
|
||||
|
||||
The module includes a Hyprland keybind:
|
||||
|
||||
```
|
||||
SUPER + ALT + A → Launch Android emulator
|
||||
```
|
||||
|
||||
Edit `modules/hyprland/config.nix` to customize.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### "avdmanager: command not found"
|
||||
|
||||
Ensure the module is properly enabled and rebuilt:
|
||||
|
||||
```bash
|
||||
home-manager switch --flake .#cody@nixos
|
||||
```
|
||||
|
||||
Then source environment:
|
||||
|
||||
```bash
|
||||
exec $SHELL
|
||||
```
|
||||
|
||||
### Emulator won't start
|
||||
|
||||
Check that the system image is available:
|
||||
|
||||
```bash
|
||||
avdmanager list all
|
||||
```
|
||||
|
||||
If the API level isn't listed, it may not be in the androidenv configuration. Edit the module to add it.
|
||||
|
||||
### Flutter doctor shows issues
|
||||
|
||||
```bash
|
||||
flutter doctor --verbose
|
||||
|
||||
# Accept licenses
|
||||
yes | flutter doctor --android-licenses
|
||||
|
||||
# Clean cache
|
||||
flutter clean
|
||||
rm -rf pubspec.lock
|
||||
flutter pub get
|
||||
```
|
||||
|
||||
### Physical device not detected
|
||||
|
||||
```bash
|
||||
# Check ADB sees the device
|
||||
adb devices
|
||||
|
||||
# Reload udev rules if you added a new device
|
||||
sudo udevadm control --reload-rules
|
||||
sudo udevadm trigger
|
||||
|
||||
# Ensure user is in correct group
|
||||
groups # Check for adbusers
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Automatically configured:
|
||||
|
||||
```bash
|
||||
ANDROID_HOME # Points to androidenv SDK
|
||||
ANDROID_SDK_ROOT # Points to androidenv SDK
|
||||
ANDROID_USER_HOME # $HOME/.android
|
||||
JAVA_HOME # JDK path
|
||||
ANDROID_JAVA_HOME # JDK for Android tools
|
||||
```
|
||||
|
||||
## Nix-Specific Notes
|
||||
|
||||
**android-studio-full** provides:
|
||||
- Complete Android SDK with tools
|
||||
- Emulator with hardware acceleration
|
||||
- System images for multiple API levels
|
||||
- Proper FHS environment for compatibility with standard Android tools
|
||||
|
||||
The module automatically configures:
|
||||
- `ANDROID_HOME` environment variable
|
||||
- `ANDROID_SDK_ROOT` for SDK location
|
||||
- `JAVA_HOME` for Java toolchain
|
||||
- All necessary PATH entries
|
||||
|
||||
### Adding More API Levels
|
||||
|
||||
Android Studio's SDK Manager handles API level management. After installation:
|
||||
|
||||
1. Open Android Studio
|
||||
2. Go to SDK Manager (Tools → SDK Manager)
|
||||
3. Select additional API levels and download system images
|
||||
4. Use `android-emulator my-device 31` for the new level
|
||||
|
||||
## Advanced: Manual SDK Management
|
||||
|
||||
If you prefer not to use Android Studio, you can manage the SDK manually using `android-tools`:
|
||||
|
||||
```bash
|
||||
# List available SDK components
|
||||
sdkmanager --list
|
||||
|
||||
# Install specific SDK component
|
||||
sdkmanager "system-images;android-34;google_apis;x86_64"
|
||||
|
||||
# Create AVD
|
||||
avdmanager create avd --name test --package "system-images;android-34;google_apis;x86_64"
|
||||
```
|
||||
|
||||
## Additional Resources
|
||||
|
||||
- [NixOS Android Environment](https://search.nixos.org/packages?channel=unstable&query=androidenv)
|
||||
- [Android Studio on NixOS](https://github.com/NixOS/nixpkgs/blob/master/pkgs/applications/editors/android-studio)
|
||||
- [Android Developer Docs](https://developer.android.com/)
|
||||
- [Flutter Documentation](https://flutter.dev/docs)
|
||||
|
||||
## Module Implementation Details
|
||||
|
||||
The module uses:
|
||||
- `android-studio-full` for complete Android SDK with FHS environment
|
||||
- `android-tools` for command-line utilities
|
||||
- Standard Nix packages for build tools (Gradle, Maven, CMake)
|
||||
- Environment variable configuration for automatic tool discovery
|
||||
- Helper scripts for emulator management
|
||||
210
modules/android/default.nix
Normal file
210
modules/android/default.nix
Normal file
@@ -0,0 +1,210 @@
|
||||
{ config, pkgs, lib, ... }:
|
||||
|
||||
let
|
||||
cfg = config.modules.android;
|
||||
in
|
||||
{
|
||||
options.modules.android = {
|
||||
enable = lib.mkEnableOption "Android development environment with emulator support";
|
||||
|
||||
enableEmulator = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Enable Android emulator for testing Flutter and Android apps";
|
||||
};
|
||||
|
||||
apiLevel = lib.mkOption {
|
||||
type = lib.types.int;
|
||||
default = 34;
|
||||
description = "Default Android API level for the emulator";
|
||||
};
|
||||
|
||||
enableFlutterSupport = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = true;
|
||||
description = "Enable Flutter SDK and related tools";
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
home.packages = with pkgs; [
|
||||
# Android Studio Full with FHS environment (recommended for NixOS)
|
||||
# This includes SDK, emulator, and all necessary tools
|
||||
android-studio-full
|
||||
|
||||
# Core Android command-line tools
|
||||
android-tools
|
||||
|
||||
# Build and compilation tools
|
||||
gradle
|
||||
maven
|
||||
ninja
|
||||
cmake
|
||||
gnumake
|
||||
pkg-config
|
||||
|
||||
# Java/Kotlin development
|
||||
jdk
|
||||
jdk21
|
||||
kotlin
|
||||
|
||||
# Flutter SDK for app development
|
||||
(if cfg.enableFlutterSupport then flutter else null)
|
||||
|
||||
# Flutter Version Manager
|
||||
(if cfg.enableFlutterSupport then fvm else null)
|
||||
|
||||
# Additional Android tools
|
||||
scrcpy # Screen sharing for Android devices
|
||||
apksigner # Sign APKs
|
||||
];
|
||||
|
||||
# Environment variables for Android development
|
||||
home.sessionVariables = lib.mkIf cfg.enable {
|
||||
ANDROID_HOME = "$HOME/.android";
|
||||
ANDROID_SDK_ROOT = "$HOME/Android/Sdk";
|
||||
ANDROID_USER_HOME = "$HOME/.android";
|
||||
JAVA_HOME = "${pkgs.jdk}/lib/openjdk";
|
||||
# For Flutter development
|
||||
ANDROID_JAVA_HOME = "${pkgs.jdk}";
|
||||
};
|
||||
|
||||
# Create a script to launch the Android emulator
|
||||
# Note: This works with the NixOS androidenv setup
|
||||
home.file.".local/share/bin/android-emulator" = lib.mkIf cfg.enableEmulator {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/usr/bin/env bash
|
||||
# Android Emulator launcher script for NixOS
|
||||
# Uses android-studio-full's built-in tools
|
||||
|
||||
set -e
|
||||
|
||||
EMULATOR_NAME="''${1:-flutter-dev}"
|
||||
API_LEVEL="''${2:-${toString cfg.apiLevel}}"
|
||||
|
||||
echo "Starting Android Emulator: $EMULATOR_NAME (API $API_LEVEL)"
|
||||
|
||||
# Check if AVD exists, if not create it
|
||||
if ! grep -q "^[^#]*name=$EMULATOR_NAME" ~/.android/avd/devices.txt 2>/dev/null; then
|
||||
echo "Creating AVD: $EMULATOR_NAME..."
|
||||
|
||||
# Try using avdmanager from Android Studio
|
||||
if command -v avdmanager &> /dev/null; then
|
||||
echo "no" | avdmanager create avd \
|
||||
--name "$EMULATOR_NAME" \
|
||||
--package "system-images;android-$API_LEVEL;google_apis;x86_64" \
|
||||
--device "pixel_6" \
|
||||
--force 2>&1 || {
|
||||
echo "Error: Could not create AVD"
|
||||
echo "Try running: android-studio to set up SDK from the IDE"
|
||||
exit 1
|
||||
}
|
||||
else
|
||||
echo "Error: avdmanager not found"
|
||||
echo "Please open Android Studio and complete the SDK setup:"
|
||||
echo " android-studio"
|
||||
echo ""
|
||||
echo "Then use SDK Manager to download system images for API $API_LEVEL"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Launch emulator with optimizations for NixOS
|
||||
emulator -avd "$EMULATOR_NAME" \
|
||||
-memory 2048 \
|
||||
-partition-size 4096 \
|
||||
-dns-server 8.8.8.8 \
|
||||
-no-snapshot-load \
|
||||
-no-snapshot-save \
|
||||
-gpu auto \
|
||||
-no-boot-anim \
|
||||
&
|
||||
|
||||
EMULATOR_PID=$!
|
||||
echo "Emulator starting in background (PID: $EMULATOR_PID)"
|
||||
echo "Waiting for boot..."
|
||||
|
||||
# Wait for emulator to boot
|
||||
for i in {1..90}; do
|
||||
if adb shell getprop sys.boot_completed 2>/dev/null | grep -q "1"; then
|
||||
echo "✓ Emulator fully booted!"
|
||||
exit 0
|
||||
fi
|
||||
echo -n "."
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo "⚠ Timeout waiting for emulator to boot"
|
||||
exit 1
|
||||
'';
|
||||
};
|
||||
|
||||
# Create a setup script to initialize Android environment on first use
|
||||
home.file.".local/share/bin/android-setup" = lib.mkIf cfg.enable {
|
||||
executable = true;
|
||||
text = ''
|
||||
#!/usr/bin/env bash
|
||||
# One-time setup script for Android development on NixOS
|
||||
|
||||
echo "Setting up Android development environment..."
|
||||
echo ""
|
||||
|
||||
# Check if sdkmanager is available
|
||||
if ! command -v sdkmanager &> /dev/null; then
|
||||
echo "Warning: sdkmanager not found in PATH"
|
||||
echo "This is normal on NixOS. You'll need to use Android Studio to manage SDKs."
|
||||
echo ""
|
||||
echo "Opening Android Studio for SDK setup..."
|
||||
android-studio &
|
||||
echo ""
|
||||
echo "In Android Studio:"
|
||||
echo " 1. Go to Tools → SDK Manager"
|
||||
echo " 2. Select API levels you want to download"
|
||||
echo " 3. Click 'Apply' and 'OK'"
|
||||
echo " 4. Close Android Studio when done"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Accept Android licenses
|
||||
echo "Accepting Android licenses..."
|
||||
yes | sdkmanager --licenses 2>&1 | tail -10
|
||||
|
||||
echo ""
|
||||
echo "✓ Android environment setup complete!"
|
||||
echo ""
|
||||
echo "Next steps:"
|
||||
echo " 1. Run: android-emulator (to create and start emulator)"
|
||||
echo " 2. For Flutter: flutter doctor"
|
||||
echo " 3. For Android Studio: android-studio"
|
||||
echo ""
|
||||
'';
|
||||
};
|
||||
|
||||
# Optional: Add udev rules for Android devices
|
||||
# This allows debugging on physical devices without root
|
||||
home.file.".config/udev/rules.d/51-android.rules" = lib.mkIf cfg.enable {
|
||||
text = ''
|
||||
# Android debug bridge - allows USB debugging without sudo
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0bb4", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0e79", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0502", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0b05", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="413c", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0489", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="091e", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0d4d", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04da", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04b7", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04b8", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="04b9", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="0bed", MODE="0666", GROUP="adbusers"
|
||||
SUBSYSTEM=="usb", ATTR{idVendor}=="1d4d", MODE="0666", GROUP="adbusers"
|
||||
'';
|
||||
};
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user