A VR-optimized file manager for Meta Quest 3 / Quest 3S. This is a native Android 2D app designed for controller-first navigation with large touch targets and high contrast UI.
- SAF-compliant storage access - Works within Android's Scoped Storage model using Storage Access Framework
- USB OTG support - First-class support for USB drives via SAF folder picker
- Large file handling - Streaming copy with progress for files up to 20GB+
- VR-optimized UI - Three-panel layout with large typography and focus rings
- Controller navigation - D-pad/joystick navigation with clear focus indicators
- Android Studio Hedgehog (2023.1.1) or later
- JDK 17
- Android SDK 34
- ADB installed and configured
# Debug build
./gradlew assembleDebug
# Release build
./gradlew assembleReleaseThe APK will be at app/build/outputs/apk/debug/app-debug.apk
-
Enable Developer Mode on your Quest:
- Open the Oculus app on your phone
- Go to Settings → [Your Headset] → Developer Mode → Enable
-
Connect Quest via USB-C cable
-
Install the APK:
adb install -r app/build/outputs/apk/debug/app-debug.apk- Download and install SideQuest
- Connect your Quest
- Drag and drop the APK onto SideQuest
- Launch QuestFiles from Unknown Sources in your Quest library
- Tap the "Internal Storage" tile
- In the folder picker, select the folder you want to manage (e.g., "Download", "Movies", or a broader folder)
- Tap "Use this folder" and confirm
- Connect a USB drive to your Quest via USB-C adapter
- Tap the "USB Drive" tile
- In the folder picker, locate and select your USB drive
- Tap "Use this folder" and confirm
Note: Quest may not show USB drives immediately. See troubleshooting below.
If your USB drive doesn't appear in the folder picker:
- Replug the drive - Disconnect and reconnect the USB drive
- Restart Quest - Hold power button → Restart
- Check format - Ensure drive is FAT32 or exFAT (NTFS not supported)
- Check adapter - Ensure your USB-C adapter supports OTG
- Try different port - Some hubs don't work properly
- The app can only access folders you've explicitly granted via the folder picker
- You cannot access system folders or other app's private data
- If you revoke permission, you'll need to pick the folder again
- Large files (1GB+) are copied via streaming to prevent memory issues
- Progress is shown in a notification
- Do not force-stop the app during transfers
The Diagnostics screen shows:
- Currently configured root URIs
- Provider authority for each root
- All persisted URI permissions
- Write test functionality (creates/deletes a test file)
Use "Test Write" to verify the app can write to your selected folders.
app/src/main/java/com/questfiles/manager/
├── data/
│ ├── model/ # Data classes (FsItem, RootEntry, etc.)
│ └── datastore/ # DataStore persistence
├── files/
│ ├── SafRepository # SAF operations (list, copy, move, delete)
│ ├── MimeUtils # MIME type detection
│ └── BreadcrumbPath # Path navigation helpers
├── workers/
│ └── FileTransferWorker # WorkManager for long operations
├── ui/
│ ├── theme/ # VR-optimized dark theme
│ ├── components/ # Reusable UI components
│ └── screens/ # Home, Browser, Diagnostics screens
└── navigation/ # Jetpack Navigation setup
- No MANAGE_EXTERNAL_STORAGE - By design, to comply with store policies
- No root access - Standard SAF only
- No ZIP support - Not included in MVP
- File previews - Image thumbnails only, no video thumbnails
- Kotlin
- Jetpack Compose + Material 3
- MVVM with ViewModel
- Coroutines + Flow
- DataStore for persistence
- WorkManager for background operations
- DocumentFile + ContentResolver for SAF
- Timber for logging
MIT License - See LICENSE file for details.