fix(flutter/android): production manifest + AudioServiceActivity

Two related Android setup gaps caught when running on a clean Pixel 6
emulator:

1. MainActivity extended FlutterActivity, but the audio_service
   plugin requires AudioServiceActivity. AudioService.init() threw
   PlatformException("The Activity class declared in your
   AndroidManifest.xml is wrong"), and the partial-engine-reinit that
   followed cascaded into a flutter_cache_manager SQLite EXCLUSIVE
   lock crash. Both errors clear with the correct base class.

2. The main manifest was missing two production permissions:
   - POST_NOTIFICATIONS — Android 13+ runtime requirement for the
     media notification (now-playing tile in the system tray).
     audio_service auto-prompts at init() time once declared.
   - ACCESS_NETWORK_STATE — used by ConnectionErrorBanner +
     flutter_cache_manager for connectivity awareness.

Note for future contributors: src/main/AndroidManifest.xml IS the
production manifest. The src/debug and src/profile variants only add
dev-only entries (e.g. INTERNET re-declared in debug for hot-reload).
There is no separate "release" manifest in Flutter's convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-08 22:33:30 -04:00
parent c4cccea775
commit 751c2878f7
2 changed files with 14 additions and 2 deletions
@@ -1,8 +1,14 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Used in all build flavours (debug / profile / release). -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PLAYBACK" />
<!-- Android 13+ requires this to be declared AND prompted at runtime
for the media notification (now-playing tile) to appear. Audio
playback works without it; only the system-tray surface breaks. -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application
android:label="minstrel"
android:name="${applicationName}"
@@ -1,5 +1,11 @@
package com.fabledsword.minstrel
import io.flutter.embedding.android.FlutterActivity
import com.ryanheise.audioservice.AudioServiceActivity
class MainActivity : FlutterActivity()
// Must extend AudioServiceActivity (not FlutterActivity) so the
// audio_service plugin can wire its FlutterEngine through. Without this
// the platform call from AudioService.init() throws PlatformException
// "The Activity class declared in your AndroidManifest.xml is wrong",
// which on first start cascades into a flutter_cache_manager sqlite
// EXCLUSIVE-lock crash because the engine partially re-initialises.
class MainActivity : AudioServiceActivity()