19 Commits
Author SHA1 Message Date
XoséandClaude Opus 5.5 c771aa01bd Podlite 1.12: set speed and skipping silences before the audio opens; reopen on a skip toggle
ExoPlayer 2.18 sets up skipping silences when it opens the audio, so the engine now gets both settings before
prepare, and turning the option on or off while an episode plays reopens it at the same spot. Tested on the
Xperia J against test/mock_abs.py: 2x speed, silences skipped, the toggle mid-play, notification buttons.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 22:33:51 +01:00
XoséandClaude Opus 5.5 666a7eb8cd Podlite 1.12: a build for Android 4.1 (Xperia J) with ExoPlayer, speed and skip silences
- One build per Android level, as in Tenda and Plexamp Lite: build/Podlite.apk (Android 2.2+, versionCode 1308) and
  build/Podlite-api16.apk (Android 4.1+, 1316), from shared src/ plus platform/api8 or platform/api16; build.sh now
  runs on the local toolchain (aapt2, dx or R8, signapk.py; the JKS key converted for the run).
- Android 4.1 build: ExoPlayer 2.18.7 behind an Engine interface, with playback speed (player header) and skipping
  silences (Settings), a 3-minute buffer and MediaPlayer as fallback for audio it can't decode; a notification and
  lock screen with the cover and buttons; Holo; a menu button on phones without a Menu key; metered networks for
  "download on Wi-Fi only".
- Both builds: tlskit's Http.abort fix (a finished response's pooled connection is no longer closed under a later
  request); the lock screen's and newer headsets' play/pause keys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-01 21:56:18 +01:00
XoséandClaude Opus 5.5 b2ca212c45 Add spec.md: goal, limits and rules for working on the project
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 09:05:36 +01:00
XoséandClaude Opus 5.5 4044303764 Merge branch 'internal-install' into main
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 14:02:40 +02:00
XoséandClaude Opus 5.5 04ac5ae725 Podlite 1.11: install internally, keep loaded roots
Installed on the SD card, the app was killed whenever the card was shared over USB,
and a failed root read left HTTPS broken until a restart.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-20 14:00:50 +02:00
xocko 084d7e9cad Merge pull request 'Podlite 1.10: bundled TLS 1.2, renamed from MiniABS, radio icon and amber' (#2) from bundled-tls into main 2026-10-19 17:11:36 +00:00
XoséandClaude Opus 5.5 db1175d25c Podlite 1.10: amber instead of purple, to match the radio icon
The purple came from the old Audiobookshelf icon. Accent and button gradient now take the radio's
brass and dial glow (#C27A1E, light #E8A64A, buttons #D98C2B to #A35F14), and the backgrounds,
lines and greys lose their purple tint for warm ones. The blue 'new episode' dot stays.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 19:05:22 +02:00
XoséandClaude Opus 5.5 c673a0ba5d Podlite 1.9: radio icon
New launcher icon (the Podcasts Radio pack, master in art/icon-master.png). The status-bar icon
was cut out of the old headphones artwork; make_icons.py now draws a white radio silhouette.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:57:02 +02:00
XoséandClaude Opus 5.5 042364b45c README: APK size, former name, JSON_JAR for the tests
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:40:21 +02:00
XoséandClaude Opus 5.5 bede72ed09 README: Newslite is now Noticias Lite
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 18:20:12 +02:00
XoséandClaude Opus 5.5 a4be0bab44 Podlite 1.8: MiniABS is now Podlite
Renames the app (label, texts, Audiobookshelf client name, User-Agent, APK). The package name,
preferences and signing key stay, so it installs over MiniABS and keeps its settings.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-19 16:57:47 +02:00
XoséandClaude Opus 5.5 06a5c7078f MiniABS 1.7: bundled TLS 1.2, no legacy HTTPS port needed
All requests (API, covers, downloads, the streaming proxy) go through Minamp's own
HTTP/TLS client (Bouncy Castle TLS 1.2, Mozilla roots, keep-alive, session
resumption) via NetConnection, a drop-in HttpURLConnection, as the iPod version does
with BearSSL. The phone reaches the normal https:// address directly; nothing changes
on the server.

- Trust: Mozilla roots + the user's pinned CAs/certificates feed the new verifier; the
  trust prompt, renew-safe CA pinning and forged-chain protection behave as before
- PATCH is a normal request now (no raw-socket path)
- Job, covers, player, downloads and proxy threads get big stacks for the handshake
- embedded Roots.java and gen_roots.py replaced by assets/roots
- tests: desktop shims read assets; all 104 checks pass (HTTP and HTTPS)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 19:20:53 +02:00
xocko 10a2aa9ef5 Merge pull request 'Backport from the iOS version: never mark early endings as played, stall warning, Close' (#1) from ios-backports into main
Reviewed-on: xocko/miniabs#1
2026-10-17 14:26:41 +00:00
XoséandClaude Opus 5.5 6cbe3596e4 MiniABS 1.6: never mark early endings as played, stall warning, Close
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 16:13:26 +02:00
XoséandClaude Opus 5.5 a6d2c8b2d2 Backport from the iOS version: never mark early endings as played, stall warning, Close
- An episode only counts as played when playback reaches the last minute.
  Saved files that "complete" early (cut-short download, SD card problems) were
  marked as played on the server, as were streams ending 30-60 s early; now a
  stream is retried and a file is reported.
- "Playing" but the position not moving for 12 s: say so.
- Menu -> "Pechar MiniABS" (Latest/Shows/Saved and the player): save the
  position, stop playback and close the app.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 16:05:13 +02:00
xockoandClaude Opus 5.5 2c23ec9131 MiniABS 1.5: Audiobookshelf icon and purple theme
- Launcher icon from the Audiobookshelf icon pack (art/icon_master_512.png),
  including an xhdpi size
- Notification icon cut out of the same artwork; player icons redrawn in the
  icon's lilac (tools/make_icons.py)
- Purple colour scheme taken from the icon: gradient accent buttons, lilac
  text accents (accent_light), purple-tinted backgrounds
- README: where the icon and colours come from

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 10:07:49 +02:00
xockoandClaude Opus 5.5 0fea07f1b2 MiniABS 1.4: smaller player controls
- Play/pause becomes a rounded rectangle (58x46dp) instead of a 78dp circle,
  with 32dp icons and wider spacing (play_w/play_h/play_gap in dimens.xml)
- Skip buttons shrink from 82x56dp to 62x42dp, with 16sp text
- Version 1.4 (versionCode 5); there was no public 1.3

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 08:02:53 +02:00
xockoandClaude Opus 5.5 275bee3c11 MiniABS 1.2: Galician interface, larger text and touch targets
- Translate the interface to Galician (tools/translate_gl.py), including
  Galician month abbreviations for dates, which Android 2.3 lacks
- Resize for the Galaxy Mini's 240x320 screen: larger text, rows, tabs and
  buttons; all sizes now live in res/values/dimens.xml
- Redraw play/pause/refresh icons for every density; slightly brighter
  secondary text colours

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:29:17 +02:00
xockoandClaude Opus 5.5 b7e43d7d61 MiniABS 1.1: HTTPS support
- Bundle current root certificates (Let's Encrypt, GTS, Sectigo, DigiCert G2,
  Amazon, ...) missing from Android 2.x's store (Roots.java, tools/gen_roots.py)
- Ask once for unknown certificates, showing the SHA-256 fingerprint, and
  remember the answer; replaces "accept any certificate" (Trust*, Settings)
- Local streaming proxy so Android 2.x's MediaPlayer can play https:// servers,
  with seeking and a fresh token per request (StreamProxy.java)
- Tests over real TLS with good, expired, wrong-host, forged and self-signed
  certificates (test/make_pki.sh, TrustTest.java)
- README: server setup for a legacy TLS 1.0 port

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 20:07:55 +02:00
218 changed files with 4364 additions and 672 deletions

No files matched your search

+6 -4
View File
@@ -1,9 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- build.sh makes one APK per Android level from this file: it sets minSdkVersion and targetSdkVersion for each,
and versionCode = the one below x 100 + the level (13 -> 1308 for Android 2.2, 1316 for 4.1). -->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.miniabs"
android:versionCode="1"
android:versionName="1.0"
android:installLocation="auto">
android:versionCode="13"
android:versionName="1.12"
android:installLocation="internalOnly">
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="10" />
@@ -54,7 +56,7 @@
<activity
android:name=".SettingsActivity"
android:label="Settings"
android:label="Axustes"
android:theme="@android:style/Theme"
android:screenOrientation="portrait"
android:configChanges="keyboardHidden|orientation" />
+61 -14
View File
@@ -1,20 +1,37 @@
# MiniABS
# Podlite
A tiny Audiobookshelf **podcast** client for the Samsung Galaxy Mini (GT-S5570) and other Android 2.2+ phones. Native Java, no libraries, ~100 KB.
A tiny Audiobookshelf **podcast** client for the Samsung Galaxy Mini (GT-S5570) and other Android 2.2+ phones, with a
second build for Android 4.1 and later (Xperia J, Galaxy S II…): see *Android 4.1 build*. Native Java; the APK is about 1.1 MB, nearly all of it the bundled TLS stack. Formerly MiniABS. The interface is in Galician, with large text and touch targets sized for the Mini's 240×320 screen. The launcher icon is the "Podcasts Radio" pack (master in `art/icon-master.png`); `tools/make_icons.py` draws the notification icon (a white radio silhouette) and the player icons. Its warm dark colours and amber accent come from the radio: brass and the glow of its dial.
## Install
1. Copy `MiniABS.apk` to the phone (USB to the SD card, or download it in the browser).
1. Copy `Podlite.apk` (Android 4.1+: `Podlite-api16.apk`; Tenda picks the right one by itself) to the phone (USB to the SD card, or download it in the browser).
2. On the phone: **Settings → Applications → Unknown sources** → tick it.
3. Open the APK from a file manager and install. It can be moved to the SD card (Settings → Applications → Manage applications → MiniABS → Move to SD card).
3. Open the APK from a file manager and install. Podlite installs to internal storage (about 1 MB): an app on the SD card is killed whenever the phone shares its SD card over USB, which stopped playback and broke HTTPS until a restart.
## Connecting
Use your server's **local http:// address**, e.g. `http://192.168.1.10:13378`.
At home, the simplest option is your server's **local http:// address**, e.g. `http://192.168.1.10:13378`.
Android 2.x only speaks old TLS and has an outdated certificate list, so it usually can't connect to modern HTTPS servers (including Let's Encrypt behind a reverse proxy). The "Accept any HTTPS certificate" box only helps with self-signed certificates on servers that still allow older TLS.
Sign in with your username and password, or tick "Use an API key instead". It works with both current servers (2.26+, short-lived access tokens that Podlite refreshes automatically) and older ones (single long-lived token).
Sign in with your username and password, or tick "Use an API key instead". It works with both current servers (2.26+, short-lived access tokens that MiniABS refreshes automatically) and older ones (single long-lived token).
## HTTPS (from outside your home)
Android 2.3 only speaks TLS 1.0, which modern servers refuse, so since 1.7 Podlite brings its own
**TLS 1.2** (Bouncy Castle, the same client as Plexamp Lite, with Mozilla's root certificates,
keep-alive and session resumption). Sign in with your server's normal `https://` address, at
home or away; nothing changes on the server. (A legacy TLS 1.0 port set up for older versions
keeps working too.)
### App: certificates
- **Built-in roots:** Podlite checks certificates against Mozilla's current root list (`assets/roots`), so Let's Encrypt, Google Trust Services, Sectigo/ZeroSSL and the rest just work.
- **Anything else** (self-signed, a private CA, a new root): Podlite shows the certificate's SHA-256 fingerprint and asks once. Compare it with the fingerprint your computer's browser shows for the site before tapping Trust. It then trusts the CA that issued it, so renewals keep working.
- **Settings → Certificates you trusted** lets you forget them.
### App: streaming
Android 2.x's media player can't stream modern https:// URLs, so for HTTPS servers Podlite runs a small proxy on the phone (127.0.0.1 only, random unguessable URLs). It forwards seeks and gets a fresh sign-in token for each request, so long episodes don't break when the token expires.
## Using it
@@ -22,27 +39,57 @@ Sign in with your username and password, or tick "Use an API key instead". It wo
- **Shows**: every podcast; tap one for its episodes. Menu key → sort oldest/newest, hide played.
- **Saved**: episodes downloaded to the SD card, plus download progress.
- **Tap** an episode to play. **Long-press** for Download, Delete download, Mark as played/unplayed, Go to show.
- **Player**: skip back/forward (set the amounts in Settings), seek bar, show notes. Menu key → sleep timer, mark as played, download, stop.
- **Player**: skip back/forward (set the amounts in Settings), seek bar, show notes. Menu key → sleep timer, mark as played, download, stop, close Podlite.
- **Close**: Menu key → *Pechar Podlite* (on the Latest/Shows/Saved screen or the player) saves the position, stops playback and closes the app.
- **Headset buttons**: play/pause; next/previous skip forward/back. Playback pauses when headphones are unplugged and during calls.
Colored dots: blue = new, amber = in progress (with a bar), grey = played.
## Progress sync
Playback opens an Audiobookshelf session and syncs every 15 seconds and on pause, so progress follows you to other apps. Saved episodes play offline; their positions are kept on the phone and sent to the server next time you're online (or tap refresh on the Saved tab).
Playback opens an Audiobookshelf session and syncs every 15 seconds and on pause, so progress follows you to other apps. An episode only counts as played when playback gets within a minute of its end: a stream that drops or a saved file cut short is retried or reported, never marked as played. If playback says it's playing but stops moving for 12 seconds, Podlite says so. Saved episodes play offline; their positions are kept on the phone and sent to the server next time you're online (or tap refresh on the Saved tab).
## Android 4.1 build
One build per **Android level**, never per phone (the same pattern as Tenda and Plexamp Lite): `build/Podlite.apk`
for Android 2.2+ and `build/Podlite-api16.apk` for 4.1+, from the same source, package and key. `versionCode` is
the manifest's × 100 + the level (13 → 1308 and 1316), so a phone that moves up a level gets the newer build as an
ordinary update. What only one level can do is in `platform/api8/…/Platform.java` and `platform/api16/…/Platform.java`
(the same methods; keep them in step), plus `platform/api16/res` (Holo). The Android 4.1 build adds:
- **ExoPlayer 2.18** (`platform/api16/…/ExoEngine.java`) behind the small `Engine` interface the player service
uses (`MediaPlayerEngine` on Android 2.x), with **playback speed** (the button at the top of the player: 0,8× to 2×)
and **skip silences** (Settings → Reprodución). It keeps up to 3 minutes buffered. An episode ExoPlayer can't
decode is retried with Android's own player.
- A **notification** with the cover and −15 ⏯ +30 ✕ (pull it down for a larger one); swiping it away while paused stops.
- **Lock-screen controls** with the cover (⏮ ⏭ skip back and forward).
- Android 4's **Holo** dialogs, menus and Settings; a ⋮ button on phones without a Menu key.
- "Download on Wi-Fi only" means any network that doesn't cost: a phone's Wi-Fi hotspot counts as mobile data.
## Limits
- Episodes are streamed with direct play. Formats Android 2.x can't decode (e.g. Opus) can't be played, since the transcoded HLS stream isn't supported on 2.x.
- No playback speed control: Android 2.x's media player doesn't support it.
- No playback speed control on Android 2.x (its media player doesn't support it); the Android 4.1 build has it.
- Downloads need an SD card. "Download on Wi-Fi only" is on by default.
## Building
Needs a JDK, `aapt`, `dalvik-exchange` (dx), `zipalign`, `apksigner` (Ubuntu: `apt install aapt dalvik-exchange zipalign apksigner`) and an API 8 `android.jar`:
With the toolchain Plexamp Lite's `tools/setup_toolchain.sh` prepares (`~/android-toolchain`: aapt2, dx, the API 8
jar, Bouncy Castle renamed to `com.minamp.bc`, a Python venv with `cryptography`), plus for the Android 4.1 build the
API 16 jar, ExoPlayer (`tools/fetch_exoplayer.sh`), R8 (`d8.jar` from build-tools 34, in
`~/android-toolchain/calendar-tools/`) and a JDK 11+ (`build.sh` finds Homebrew's openjdk@17). No Gradle, no SDK:
ANDROID_JAR=/path/to/android-8/android.jar ./build.sh
./build.sh # -> build/Podlite.apk (Android 2.2+) and build/Podlite-api16.apk (4.1+)
./build.sh 16 # one level only
Compiling against the API 8 jar guarantees no newer Android APIs are used. The APK is signed with `miniabs.keystore` (password `miniabs`); keep it to install updates over the top.
Per level: aapt2 → javac (Java 8 bytecode against that level's `android.jar`) → for Android 2.x the Dalvik 2.x link
check and dx, for 4.1 R8 (`tools/r8-rules.pro`: keeps the app whole, shrinks ExoPlayer and Guava, one dex) →
`tools/signapk.py` (v1, SHA-1, the classic SignApk format Android ≤ 4.2 needs) → `tools/check_dex.py`. The APK is
signed with `miniabs.keystore` (JKS, password and alias `miniabs`; build.sh converts it to a PKCS#12 copy in `build/`
for the run); keep it to install updates over the top.
`test/run_tests.sh` runs the API, JSON and progress code on the desktop against a mock Audiobookshelf server (`test/mock_abs.py`).
All sizes (text, rows, buttons, covers) are in `res/values/dimens.xml`; change them there and rebuild.
`src/com/miniabs/net/` is the bundled HTTP/TLS client shared with Plexamp Lite, Noticias Lite and Calendar Lite; `assets/roots/` holds Mozilla's roots (regenerate with Plexamp Lite's `tools/make_roots.py`).
`JSON_JAR=/path/to/json.jar test/run_tests.sh` (any org.json jar) runs the API, JSON, progress, HTTPS-trust and streaming-proxy code on the desktop JVM against a mock Audiobookshelf server (`test/mock_abs.py`), over plain HTTP and over TLS with good, expired, wrong-host, forged and self-signed certificates (`test/make_pki.sh`).
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Loaded 100 of 218 files, more files were not shown because too many files have changed in this diff. Show more