Skip to content

shockjiang/mobile-eye

Repository files navigation

mobileEye

A phone-hosted file-browser web server for Android. Run it on your phone; any device on the same Wi-Fi opens the URL in a browser to view and upload files on the phone's storage. Inspired by TianYan, Kotlin-native with a bundled minimal frontend.

Features

  • Web server on the phone — NanoHTTPD inside a dataSync foreground service. The URL is shown in the app and the ongoing notification.
  • Auto-detects the device's storage root across Android variants (/sdcard, Environment.getExternalStorageDirectory(), /storage/emulated/0, /storage/self/primary, plus external volume roots). Exposed via GET /api/roots.
  • Storage scope: MANAGE_EXTERNAL_STORAGE (full primary external access). Navigation clamped at the discovered root.
  • Directory listings use Files.readAttributes(BasicFileAttributes) — one stat() per file (vs. 4× with bare File). ~4× faster on FUSE storage.
  • Bundled frontend (vanilla JS, no build step): path bar, dir listing with file-type icons, preview pane (image / video with Range / audio / pretty-printed JSON / text / binary fallback as download link).
  • Row actions (⋮, right-click, or long-press): Preview · Download · Rename · Copy path · Show full path.
  • Large multi-file uploads: files posted one at a time via XHR (server temp peaks at one file size, not Σ all); temp dir lives in external cache (Android/data/com.shock.mobileeye/cache/uploads, tens of GB available); temp→destination uses Files.move() when same-volume.

API

Method Path Notes
GET /api/health {"status":"ok"}
GET /api/roots {"default":"/sdcard","candidates":[…]}
GET /api/directory?path=… {path, parent, items:[{name,is_dir,size,mtime}]}
GET /api/file?path=…&download=1 raw bytes, supports Range; download=1 forces attachment
GET /api/video?path=… alias of /api/file (Range)
POST /api/upload multipart: dir, files[], paths[], overwrite
POST /api/rename JSON: {path, new_name} (refuses traversal / separators)

Static assets served from assets/web/; SPA fallback to index.html.

Stack

Kotlin · AndroidX · Material 3 · NanoHTTPD 2.3.1 · OkHttp 4.12 · ViewBinding · minSdk 26 · targetSdk 34.

Build

export JAVA_HOME=/path/to/jdk-17
export ANDROID_SDK_ROOT=/path/to/android-sdk
./gradlew assembleDebug
adb install -r app/build/outputs/apk/debug/app-debug.apk

First run: grant All files access when prompted (Settings → mobileEye → toggle on).

Source layout

app/src/main/java/com/shock/mobileeye/
├── MainActivity.kt       server control UI: URL display, start/stop, port, permission request
├── WebServerService.kt   foreground service; notification with URL; LAN IP detection
└── WebServer.kt          NanoHTTPD subclass, all route handlers, multipart upload, Range, rename

app/src/main/assets/web/
├── index.html            single page
├── app.js                directory browser, viewer, sequential uploader, row-action menu
└── app.css               styling

Security caveat

No auth. Anyone on the same Wi-Fi can read and upload. Stop the server on untrusted networks, or add a token/PIN before exposing more broadly.

License

MIT.

About

Phone-hosted file-browser web server for Android (TianYan-shaped API): NanoHTTPD, range-aware video, multi-GB uploads, bundled minimal frontend.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors