floaty_chatheads_android 2.0.0
floaty_chatheads_android: ^2.0.0 copied to clipboard
Android implementation of floaty_chatheads with SYSTEM_ALERT_WINDOW, foreground service, spring physics, theming, and TalkBack accessibility.
Changelog #
2.0.0 #
Released as part of the floaty_chatheads 2.0 line. See the main package CHANGELOG for the full migration guide.
⚙ Toolchain (BREAKING) #
- Android
minSdkraised to 24 (was 23). compileSdkbumped to 35 (Android 15).- Plugin Java/Kotlin JVM target raised to 11 (was 1.8).
- Dart SDK floor
^3.0.0, Flutter floor>=3.10.0— the bare minimum the Dart code requires (final class,sealed class, records, pattern matching). The Kotlin Gradle setup stays on the legacyapply plugin: 'kotlin-android'+kotlinOptions { ... }pattern so it works on every Flutter version with Kotlin support. - Pigeon constraint normalized to
^26.3.3. - Depends on
floaty_chatheads_platform_interface: ^2.0.0.
ℹ Built-in Kotlin migration deferred #
android/build.gradle keeps the legacy pattern:
plugins {
id "com.android.library"
id "kotlin-android"
}
android {
// ...
kotlinOptions {
jvmTarget = '11'
}
}
Switching to Flutter's Built-in Kotlin pattern (top-level
kotlin { compilerOptions { … } } and conditional KGP application)
would require Kotlin Gradle Plugin 2.0+, which Flutter only ships
starting at 3.27. Adopting it would lock out every consumer on
Flutter 3.10–3.26 just to silence one warning.
On Flutter 3.44+ you will see:
WARNING: Your app uses the following plugins that apply Kotlin Gradle Plugin (KGP): floaty_chatheads_android, …
That's intentional. When Flutter promotes the warning to a hard error, this plugin will migrate to Built-in Kotlin in a major release; until then, compatibility with the 3.10–3.43 install base is the priority. See https://docs.flutter.dev/release/breaking-changes/migrate-to-built-in-kotlin/for-plugin-authors for the migration path.
♻ Internals #
showChatHeadnow delegates default-value resolution toChatHeadConfigResolverinfloaty_chatheads_platform_interface, eliminating duplication with the iOS Dart shim. Pigeon enum/message construction stays in this package.
1.1.0 #
✨ Enhancements #
- Widget-based chathead icons. The chathead bubble icon can now be
any Flutter widget (rendered to an image via the Dart offscreen
pipeline). Supports static widgets and animated widgets with
per-frame RGBA updates through the new
updateChatHeadIconPigeon method. Bitmap creation from RGBA bytes runs onDispatchers.Defaultto keep the main thread free. - Widget-based close icons. The close target icon and background can also be Flutter widgets. Widget-rendered close icons are scaled to the full close-target size (64 dp) instead of the 28 dp default, so the widget design controls the visual appearance.
- Added
closeIconIsWidget/closeBackgroundIsWidgetflags toOverlayConfigfor size-aware scaling inClose.kt.
📦 Dependencies #
- Bumped
floaty_chatheads_platform_interfaceto^1.0.5.
1.0.7 #
✨ Enhancements #
- Added
autoLaunchOnBackgroundsupport. The plugin registersApplication.ActivityLifecycleCallbacksto detect when all activities leave the foreground. When enabled, the chathead is shown automatically on background and dismissed on foreground. - Added
persistOnAppClosesupport. Controls whether the foreground service returnsSTART_STICKY(survives app death) orSTART_NOT_STICKY(stops on main app disconnect). When disabled, the service callscloseWindow(true)as soon as the main app disconnects. - Both new flags are persisted to SharedPreferences for recovery
after a
START_STICKYrestart.
⚡ Performance #
- Migrated from
ExecutorServiceto Kotlin Coroutines. All icon I/O (asset, network, byte-array decoding) now runs onDispatchers.IOvia structuredasync/await, replacing the previousExecutorService+Callableapproach. The main thread is never blocked — each icon load has an individualwithTimeoutOrNullguard. - Added
CoroutineScopelifecycle management. ASupervisorJob-backed scope (pluginScope) is created inonAttachedToEngineand cancelled inonDetachedFromEngine, ensuring all in-flight coroutines are cleaned up when the plugin is detached.
🐛 Bug Fixes #
- Fixed chathead freeze caused by async race condition.
showChatHeadandaddChatHeadare now@asyncPigeon methods. The DartFutureresolves only after the overlay window is fully created, preventing the half-initialized state that caused the overlay to appear frozen.
📦 Dependencies #
- Added
kotlinx-coroutines-android:1.7.3.
1.0.6 #
🐛 Bug Fixes #
- Fixed
CompletableFuturecrash on Android 6.0 (API 23).CompletableFuture.supplyAsyncrequires API 24+, but the module'sminSdkVersionis 23. Replaced withExecutorService+Callable(available since API 1) for parallel icon loading. - Fixed resource leak in
loadBitmapFromNetwork.InputStreamandHttpURLConnectionare now released viause { }and afinallyblock, ensuring cleanup even ifBitmapFactory.decodeStreamthrows.
1.0.5 #
🐛 Bug Fixes #
- Fixed chathead close crash when GPS streaming is active. Removing
the
FlutterViewfrom its parent during the drag-to-close gesture while the overlay engine was still processing GPS data caused a 300ms window of orphaned rendering. The redundantcontent.removeAllViews()call was removed —closeWindow(true)already handles cleanup viadetachEngine(). - Fixed foreground service not stopping after chathead close. The
destroyEngine()call threw an exception (self-destructing engine from Pigeon handler), preventingstopSelf()from being reached. Reordered service teardown sostopForeground()andstopSelf()execute beforedestroyEngine(), with the latter wrapped in a try/catch. - Fixed NPE in
hideChatHeadsdelayed callback. ReplacedFloatyContentJobService.instance!!force-unwrap with safe call?.to handle cases where the service is already destroyed.
✨ Enhancements #
- Deferred connection signal on app restart.
onAttachedToEngineno longer sendsconnected:trueto the overlay immediately when an existing service is detected. Instead it sets up the message relay viaonMainAppRelay()and defers the connection signal untilisChatHeadActive()is called from the Dart side — acting as an implicit "ready" signal that guarantees channel handlers are registered before the overlay flushes its action queue. - Native close notification to main app. When the chathead is
closed via drag-to-close or the overlay's close button, the native
layer now sends a system envelope message to the main Dart isolate
so
FloatyChatheads.onClosedfires reliably. - Extracted magic delay constants. Replaced inline delay numbers
with named companion-object constants (
CLOSE_DELAY_MS,HIDE_DELAY_MS,EXPAND_CONTENT_DELAY_MS). - Improved null safety in
onSpringUpdate. Replaced ~10topChatHead!!force-unwraps with a safe local binding. - DRY: consolidated
hideChatHeads(). Merged two near-identical branches into a single method with anisClosedparameter. - DRY: extracted
notifyOverlay()helper. Consolidated 5 repeated Pigeon notification methods into a single inline function. - Added
NotificationConfig.descriptionsupport. The foreground notification now shows a custom title and body text whendescriptionis provided.
1.0.4 #
🐛 Bug Fixes #
- Fixed overlay ↔ main app communication completely broken. When
FlutterEngineGroup.createAndRunEngine()creates the overlay engine, it auto-registers all plugins — includingFloatyChatheadsPlugin. This secondonAttachedToEnginecall overwrote the companion-objectactiveInstanceandmainMessengerwith the overlay engine's instances, causing all messages from the overlay to loop back to the overlay instead of reaching the main Dart isolate. Added anactiveInstance != nullguard inonAttachedToEngineto skip setup on the overlay engine, and a matchingisMainEnginePluginguard inonDetachedFromEngineto prevent the overlay engine from tearing down the main engine's state.
📦 Metadata #
- Shortened pubspec description to meet pub.dev 60–180 character guideline.
- Added
example/example.mdfor the pub.dev example tab.
1.0.3 #
✨ Enhancements #
- Upgraded Pigeon to 26.2.3. Regenerated all Dart and Kotlin Pigeon bindings. No API surface changes — the upgrade picks up codec and code-generation improvements from the latest Pigeon release.
1.0.2 #
✨ Enhancements #
- Debug logs are now optional and silent by default. All native
Log.d/w/eoutput is gated behindManagment.debugMode. Developers enable verbose logging by settingdebugMode: trueinChatHeadConfig; production builds produce zero log noise. Three convenience helpers (Managment.logD,logW,logE) replace every rawLog.*call acrossFloatyContentJobService,FlutterContentPanel, andChatHeads.
🐛 Bug Fixes #
- Fixed content panel rendering fullscreen on subsequent launches.
The root cause was a two-stage data loss: when the service had not
started yet,
showChatHead()only persisted the entry point toSharedPreferences, omitting content dimensions and all other config. When the service'sonCreate()later calledrestoreConfig(), it overwrote the in-memoryManagmentvalues withnull, causingcreateWindow()to skipsetContentSize()and fall back toMATCH_PARENT. The fix saves the full config to SharedPreferences in the plugin's else branch and adds a defensive guard inonCreate()to skiprestoreConfig()whenManagmentis already populated. - Fixed content panel dimensions and touch interaction leaking between
chathead sessions. The plugin now explicitly tears down stale windows
and calls
createWindow()directly with freshManagmentvalues instead of deferring toonStartCommand().
1.0.1 #
- Documentation and metadata updates.
1.0.0 #
🎉 Initial Release #
- Android implementation of
floaty_chatheadsusingSYSTEM_ALERT_WINDOW. - Pigeon-generated type-safe Dart ↔ Kotlin communication.
- Facebook Rebound spring physics for bubble drag and snap animations.
- Foreground service with configurable notification.
- Separate
FlutterEnginefor overlay content panels. - Theming support: badge colors, bubble border, shadow, close tint.
- Overlay palette delivery to Flutter overlay isolate.
- Size preset resolution with half-screen and full-screen sentinels.
- Debug overlay view with bounds, spring HUD, FPS counter, and Pigeon message log.
- Full TalkBack accessibility: content descriptions, state announcements, focus management, and custom accessibility actions.
- Snap-to-edge with configurable margin and position persistence.
- Entrance animations: slide-in and fade-in variants.
- Badge counter updates from both main app and overlay.
- Programmatic expand / collapse.