MobiLauncher

Offline bundles

Pro+ feature. Ship the launcher as a self-contained ZIP that runs from local storage on each device, with no network required to boot.

Why you might want this

The hosted launcher URL (app.mobilauncher.com/t/your-tenant) works great if your devices have network the moment they boot. They often don't:

  • Field handhelds that boot inside a warehouse with no Wi-Fi yet
  • Tablets staged in a back room before deployment
  • Devices in cellular dead zones that re-boot during travel
  • Sites where the launcher needs to come up BEFORE the VPN tunnel
  • Compliance shops where "phones home on boot" is a non-starter

The bundle solves all of those. The launcher renders entirely from files on the device. It still reaches our server later for things like broadcasts and (Enterprise) remote config — but it never needs the network just to show up.

What's in the bundle

A standard ZIP:

launcher/
├── index.html
├── assets/
│   ├── main-<hash>.js
│   ├── main-<hash>.css
│   └── ... (fonts, icons, lazy-loaded chunks)
├── config.json         ← your tenant's launcher config
├── license.json        ← your signed Pro/Ent license (the launcher verifies it on boot)
└── README.txt          ← deployment notes (this doc, short version)

Total size: ~400 KB gzipped renderer + your config + license. Under a megabyte for every customer. No frameworks pulled at runtime.

How to get one

Portal → Your fleets → click your tenant → Launcher tab → Download offline bundle button at the bottom.

What happens behind the scenes:

  1. Browser fetches the current renderer template from our R2 (Cloudflare's S3)
  2. Fetches your tenant's current config + license from our API
  3. Combines them in your browser with JSZip
  4. Hands you a .zip file to save

No server-side per-customer build. Generation is instant.

How to deploy with SOTI MobiControl File Sync

This is the production path for most Pro customers. MobiControl File Sync pushes the unpacked bundle to a known directory on every device, and the Lockdown Profile points at that directory's index.html via file://.

Step by step:

1. Unpack the ZIP

Locally, or on a build server. You'll push the contents of the launcher/ directory, not the ZIP itself.

unzip mobilauncher-bundle-<tenant>.zip
# → produces ./launcher/

2. Configure File Sync

MobiControl Console → Profiles → your profile → File Sync section:

Setting Value
Source The unpacked launcher/ directory on your build machine
Target directory /sdcard/mobilauncher/ (or another path of your choice)
Sync mode Replace (so old assets don't pile up between updates)
Sync on profile apply Yes

Save. Push the profile to a test device.

3. Point the Lockdown launcher at the local file

Same profile → Lockdown ProfileLauncher:

Setting Value
Mode Web URL
URL file:///sdcard/mobilauncher/index.html

Save and push. The device reboots into the launcher, loaded entirely from local storage.

4. Update workflow

When you change config in the Portal:

  1. Re-download the bundle
  2. Re-push via File Sync
  3. Devices pick up the change on next sync (or you can force a sync from MobiControl Console)

Yes, this is more steps than the hosted URL (where the device just re-fetches on next reload). The tradeoff is "boots on a sliced network without phoning home" — for fleets that need it, it's worth the extra friction.

How to deploy without MobiControl

If you're using our standalone Android app (no MDM):

# 1. Unpack the bundle locally
unzip mobilauncher-bundle-<tenant>.zip -d /tmp/bundle

# 2. Push the unpacked dir into the app's external files dir
adb push /tmp/bundle/. \
  /sdcard/Android/data/com.oakash.mobilauncher.beta/files/launcher

# 3. Launch pointing at the local index.html
adb shell am start -n com.oakash.mobilauncher.beta/.MainActivity \
  --es url "file:///sdcard/Android/data/com.oakash.mobilauncher.beta/files/launcher/index.html"

Re-push each time you want to roll out a new bundle.

What still needs network when bundled

  • Broadcasts — devices poll our server every 60s. No network = no new broadcasts. Existing ones already on the device continue to display until they expire.
  • Remote config (Enterprise) — devices poll for config updates. No network = stays on the bundled config.
  • License verification on boot — the license is in the bundle and is locally verified (Ed25519 signature against an embedded public key). No network needed.

If a device is offline indefinitely, it keeps running the bundled config indefinitely. Nothing breaks, nothing expires, no nag screens.

Bundle versioning

The bundle filename includes a content hash, so you can tell at a glance whether two devices are on the same bundle:

mobilauncher-bundle-acme-tools-2026-05-16-a3f7b21.zip

Internally, the renderer also records its assetBundleHash in the config — diagnostic overlay shows it on-device. If you're debugging a fleet, that's the first thing to check.

Bundle freshness

When you re-download from the Portal, you always get the current template + current config + current license. If you set up File Sync to grab from a CI artifact instead of a manual download, you can automate "re-bundle weekly so the renderer template stays fresh." Talk to us if you want help wiring that.