# DSH Mobile Sync — Android client An optional native Android client for the DSH Mobile Sync plugin. It is a small WebView shell plus a native QR scanner; DSH itself still runs on the computer. It is useful on LAN HTTP addresses, where mobile browsers refuse to open the camera, and it can remember more than one computer. ## Features - First launch opens the native camera scanner immediately. - Native ZXing decoding works on plain `http://` LAN addresses and does not use Google Play Services. - Saves multiple computers in a local profile list; switch, rename, delete. - Pairs once through the DSH PWA, then opens the saved computer directly. - PWA link `#pair=` is opened only for a new scan; later launches use the saved computer address, so a valid pairing is not recreated on every launch. - A `DSHMobile.scan()` bridge lets the PWA request the native scanner from its own “打开相机扫描” button. ## Build Requirements: - JDK 17 - Android SDK Platform 34 (`platforms;android-34`) - Android Build Tools 34.0.0 (`build-tools;34.0.0`) - `libs/core-3.5.3.jar` (checked in; Apache-2.0 ZXing core) ```bash export JAVA_HOME="/path/to/jdk-17" export ANDROID_SDK_ROOT="/path/to/android-sdk" ./build.sh ``` Output: `dist/DSH-Mobile.apk` (`fun.wystan.dshmobile`, version 2.3.0). The script creates a local `dsh-mobile.keystore` on first run and signs the APK. Do **not** commit the keystore or `dist/`. If you publish an update, keep using the same keystore so Android accepts it as an upgrade. ## First launch and profiles 1. Open the APK; it requests camera permission and opens the scanner. 2. Scan the QR code shown by the DSH **手机同步** panel. 3. The app extracts the computer origin, stores it as a profile, and opens the PWA with the one-time `#pair=` fragment. 4. The PWA creates a per-device token and remembers it. Later launches open the saved computer address without the fragment. 5. Use the “+ / 扫描” button on the home list to add another computer. Tap a card to switch; tap `⋯` to rename or remove a profile. If the camera is unavailable, use **手动输入电脑地址** and paste the full pairing link or the address shown in the desktop panel. ## Notes - `usesCleartextTraffic` is enabled because the LAN listener uses HTTP. Use HTTPS (Cloudflare) when the phone is not on the same LAN. - The scanner uses the camera1 API and a single background decoder thread; it releases the camera in `onDestroy` and when the surface is destroyed. - Removing a profile from the Android list does not revoke the device on the computer. Use the DSH side panel or the PWA **设备 → 断开** action for that. - The PWA stores the per-device token in its own WebView `localStorage`; clearing app data removes it and requires pairing again.