Skip to content

Migrate VLC Remote to work on modern Android devices#12

Open
juanpablo-santos wants to merge 6 commits into
samicemalone:masterfrom
juanpablo-santos:master
Open

Migrate VLC Remote to work on modern Android devices#12
juanpablo-santos wants to merge 6 commits into
samicemalone:masterfrom
juanpablo-santos:master

Conversation

@juanpablo-santos

Copy link
Copy Markdown

Hi!

I've been using this great app for several years until I decided to switch to a new Android phone, where the app refused to work. Usual choice these days, I steered Claude to modernize the app so it works on modern Android devices, and to replace the build toolchain with Gradle-based one. I've been testing the new version at home for a few weeks, and everything seems to work as usual.

Last commit on android-vlc-remote is from long time ago, but hopefully this PR can make it to master and be released through usual channels, as it is such a killer app.

thx,

juanpablo-santos and others added 6 commits July 13, 2026 11:26
Replace the removed Ant/Eclipse ADT toolchain with a Gradle build targeting
Android 16 (API 36) and migrate off the vendored support library.

Build system:
- Add settings.gradle, build.gradle, gradle.properties, Gradle 8.13 wrapper.
- Single-module project keeping the flat src/res/AndroidManifest.xml layout
  via sourceSets. namespace == applicationId ==
  org.peterbaldwin.client.android.vlcremote (matches every R import and the
  R.class.getPackage()->ComponentName coupling in PickServerFragment).
- compileSdk/targetSdk 36, minSdk 23, Java 17. Build JVM pinned to JDK 17.
- android.nonFinalResIds=false so R.id switch/case statements still compile.
- Remove package= from the manifest (forbidden by AGP 8).

Source migration:
- Rewrite the 13 support-v4 files to androidx.* (fragment, loader, viewpager,
  core). Native android.app fragment/preference island left as-is.
- Replace org.apache.http BasicScheme auth (removed on API 28+) with a
  Base64-encoded "Authorization: Basic" header (NO_WRAP) in MediaServer and
  ServerConnectionTest.
- Directory no longer implements Comparator<File> (collides with
  SequencedCollection.reversed() on API 35+); ordering moved into a nested
  DirectoriesFirstComparator and updated at the 3 sort call sites.
- Add android:exported to the 4 intent-filtered manifest components.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
API 31+ requires an explicit mutability flag on every PendingIntent or it
throws at creation. All six factory calls are immutable-safe:
- MediaServer.pending() and the AlarmManager path
- NotificationControls content intent (OR'd with FLAG_UPDATE_CURRENT)
- RemoteViewsFactory close-button and launch intents
- MediaAppWidgetProvider manual-update broadcast

Also target the manual-update broadcast at the widget provider class
explicitly; an implicit broadcast would not be delivered to the manifest
receiver on modern Android.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Make the app behave correctly at runtime on modern Android, not just build:

- Notifications: create a NotificationChannel (API 26+) before notifying and
  use the channel-id NotificationCompat.Builder constructor; declare and
  runtime-request POST_NOTIFICATIONS (API 33+) from PlaybackActivity.
- Background triggers: add a StatusUpdateWorker (WorkManager) and route the
  three background startService() callers to it (widget onUpdate/refresh,
  AlarmManager re-check broadcast, phone-state pause/resume). Background
  service starts are blocked on API 26+; the UI-triggered path keeps using
  the service. Adds a synchronous MediaServer.readCommand() so the worker can
  issue VLC commands off-thread without the service.
- Dynamic receivers: register the ~9 app-private status receivers with
  ContextCompat.RECEIVER_NOT_EXPORTED (required on API 34+).
- READ_PHONE_STATE: runtime-request it when the user enables pause-for-call;
  degrade gracefully if denied.
- Edge-to-edge: pad the content view by system-bar/cutout insets in both
  activities (forced edge-to-edge at targetSdk 35+ under the Holo theme).
- Deprecations: getResources().getDrawable(int) -> ContextCompat.getDrawable
  (3 files); Html.fromHtml(String) -> HtmlCompat.fromHtml(FROM_HTML_MODE_LEGACY)
  (3 files).
- Cleartext: add res/xml/network_security_config.xml permitting cleartext and
  reference it from the manifest (VLC's HTTP interface is http:// on the LAN).

Verified on an Android 16 (API 36) emulator: installs, launches, navigates to
the server picker, renders below the system bars, and the widget-update
broadcast no longer triggers a background-service-start crash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Move sources into src/main/{java,res} and src/main/AndroidManifest.xml;
  drop the custom sourceSets block so AGP defaults apply.
- Delete the dead Ant/Eclipse toolchain: build.xml, ant.properties,
  project.properties, .classpath, .project, .settings/, proguard.cfg,
  make_packagable_source, the vendored libs/android-support-v4.jar, and the
  stale tests/ instrumentation project.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant