This document describes the Android implementation of the GOZAR VPN client.
-
XrayVpnService: Foreground VPN service that manages the VPN tunnel
- Runs as a foreground service with notification (Android 8+)
- Handles Android 12+ foreground service restrictions
- Requests Android 13+ notification runtime permissions
- Persists connection state across app restarts
- Supports immediate reconnection when selected connection changes
-
Data Layer:
- Room Database: Stores connection configurations
- Connection Entity: Represents a VPN connection (id, name, link, protocol, host, port)
- ConnectionDao: Database access operations
- ConnectionRepository: Repository pattern for data access
- SharedPreferences: Stores selected connection ID and connection state
-
UI Layer:
- MainActivity: Main screen with connection list and connect button
- ConnectionAdapter: RecyclerView adapter for connection list
- QrScanActivity: QR code scanner for importing connections
- MainViewModel: ViewModel managing app state and business logic
-
Utilities:
- ConnectionParser: Parses and validates connection links (vmess, vless, trojan, ss)
- XrayConfigBuilder: Generates Xray JSON configuration with outbounds and routing rules
- Connect button is disabled until a connection is selected
- Shows "Select a connection first" error if clicked without selection
- Changes to "Disconnect" when VPN is active
- Only accepts connection links from
persiangames.onlinedomain - Validates both subscription URLs and direct connection links
- Rejects all other domains with clear error messages
- Parse and validate vmess://, vless://, trojan://, ss:// links
- Store connections in Room database
- Generate unique Xray outbound per connection
- Support connection selection and deletion
- Manual Entry: Text input dialog for pasting links
- Clipboard: Paste button to import from clipboard
- QR Code: Camera-based QR scanner using ML Kit
- Room Database: Persists all connections across app restarts
- SharedPreferences: Stores selected connection ID and VPN state
- Auto-reconnect: Restores VPN connection on app restart if it was connected before
- Foreground Service: Keeps VPN running when app is minimized or closed
- When a new connection is selected while VPN is active, automatically reconnects
- Seamless switching between connections without manual disconnect/connect
- VPN Permission: Requests VpnService permission before connecting
- Notification Permission: Requests POST_NOTIFICATIONS on Android 13+
- Camera Permission: Requests for QR code scanning
- Android SDK (API 21+, target API 34)
- Kotlin 1.9.22
- Gradle 8.2.2
-
Open the
androiddirectory in Android Studio -
Build the project:
cd android ./gradlew build -
Install on device:
./gradlew installDebug
The Android app is designed to integrate with the Go core via gomobile:
-
Build the Go module as an Android AAR:
cd core/go gomobile bind -target=android -o ../../android/app/libs/gozar.aar ./...
-
Update
android/app/build.gradleto include the AAR:dependencies { implementation fileTree(dir: 'libs', include: ['*.aar']) }
-
Call Go functions from Kotlin in
XrayVpnService.kt:import gozar.Gozar // Start Xray Gozar.start(configJson) // Stop Xray Gozar.stop()
The app generates a complete Xray configuration with:
- Inbounds: SOCKS5 (port 10808) and HTTP (port 10809) proxies
- Outbounds:
- One outbound per connection with unique tag
outbound_<id> - Selected connection aliased as
outbound_selected - Direct outbound for local traffic
- Blackhole outbound for blocked traffic
- One outbound per connection with unique tag
- Routing Rules:
- Block ads using geosite:category-ads-all
- Direct route for private IPs (geoip:private)
- Direct route for local domains
- Proxy route for international sites
- Default to proxy
-
Connection Management:
- Add connection via manual input
- Add connection via clipboard
- Add connection via QR code
- Select a connection
- Delete a connection
- Verify domain validation rejects invalid domains
-
VPN Lifecycle:
- Connect button disabled without selection
- Connect to VPN successfully
- VPN notification appears
- Minimize app - VPN stays connected
- Close app - VPN stays connected
- Reopen app - VPN state restored
- Disconnect from VPN
-
Auto-reconnect:
- Connect to VPN
- Select different connection
- Verify auto-reconnect happens
- Close app while connected
- Reopen app - verify auto-reconnect
-
Permissions:
- VPN permission requested before first connect
- Notification permission requested on Android 13+
- Camera permission requested for QR scan
-
Android Versions:
- Test on Android 12+ (foreground service restrictions)
- Test on Android 13+ (notification runtime permission)
- Go Integration: The actual Xray core integration via gomobile is marked as TODO and needs to be implemented
- Icons: Placeholder launcher icons need to be replaced with actual app icons
- Settings: Settings screen is not yet implemented
- Subscription Import: Subscription URL functionality is defined but not fully wired in Android UI
- VPN service requires BIND_VPN_SERVICE permission
- All connection links must be from
persiangames.onlinedomain - Connections stored in encrypted Room database (if device encryption enabled)
- No analytics or tracking by default
- Complete Go core integration via gomobile
- Add subscription URL import and auto-refresh
- Implement settings screen
- Add connection statistics and traffic monitoring
- Add connection speed test
- Implement custom routing rules editor