Fixed
- Fixed Android MediaStore not indexing newly added images, videos, and media files copied, moved, or downloaded from local storage, SMB/NAS network shares, and online cloud storage services. Integrated
MediaScannerNotifieracrossTransferConflictHelper, local/network paste operations, and archive extractions so media files appear immediately in system gallery apps (Google Photos, OnePlus Gallery, TV galleries). - Fixed Android TV screensavers and mobile screen timeouts triggering during internal media playback. Added
FLAG_KEEP_SCREEN_ONandkeepScreenOnview flag management toUFMPlayerActivity,SlideShowActivity, andTwinWindowPlayerFragmentso the screen stays awake while video or audio is playing and allows normal dimming when paused. - Fixed an integer overflow error when opening media files larger than 5 GB in the internal player (
UFMPlayerActivity). The datasource calculated remaining byte size using a 32-bitIntcast ((fileLength - streamPosition).toInt()), which wrapped to a negative integer for files >4.29 GB, triggering a premature EOF and ExoPlayerSource error. Reads now use 64-bitLongarithmetic before capping chunk sizes. - Fixed SMB connections dropping when streaming video/audio files to external players (e.g. VLC, MX Player). Fixed duplicate share path resolution in
SmbShareClient.splitSharePath, increased SMB session pool timeouts, and bound external media streaming toTransferServiceas an active foreground service so Android OS does not suspend background process threads or kill TCP sockets. - Fixed a crash (NullPointerException in
PdfViewerActivity.onCreate) when opening PDF files on Android TV devices. The TV layout has noHorizontalScrollViewwrapper, sofindViewById(R.id.pdfHScrollView)returned null and the non-null assignment crashed. The view is now treated as nullable and all horizontal-scroll operations are guarded, so the TV PDF viewer opens and scrolls correctly. - Fixed an ANR (App Freeze) at
HardwareRenderer.nSetStoppedduring activity stop traversals by removing explicit hardware layer types on RecyclerView containers during transitions and automatically canceling view animators on window detachment. - Fixed an ANR (App Freeze) during view animation end callbacks (
AnimatorListener.onAnimationEnd) by offloading adapter list updates, layout transition scheduling, and text scrolling steps to the main thread message queue. - Fixed a false-positive ANR (App Freeze) report when the main thread is blocked on a synchronous binder call to the Android system server with no app frames on the stack (e.g.
ActivityThread.createBaseContextForActivity→ActivityClient.getDisplayIdduring activity launch). TheAnrWatchdogThreadnow treats a pure-framework stack whose top frame isBinderProxy.transact/transactNativeas a system-side wait and resets its heartbeat instead of writing a report, in addition to the existing idle-looper (nativePollOnce) filter. - Extended the
AnrWatchdogThreadfalse-positive filter to cover any main-thread stack made up entirely of Android platform / Java runtime frames with no app or bundled-library frames, not just the two previously-known shapes. This stops false-positive ANR reports for additional system-side waits during activity launch that don't surface asBinderProxy.transact— e.g.ActivityThread.createBaseContextForActivity→SystemProperties.get(native_getinto the property service) on slow or busy Android TV devices. Platform frames are detected by class-name prefix (R8 obfuscates app/library classes to short names that never match), so genuine freezes that have app code on the stack are still reported. - Fixed an ANR (App Freeze) on low-end Android TV devices (e.g. Google Chromecast) caused by unbounded concurrent native FFmpeg video-thumbnail frame extractions saturating all CPU cores while browsing a video-heavy local folder. A fast fling scroll through
FileAdapterspawned oneFFmpegThumbnailHelperdecode per video, and several simultaneous native decodes starved the main thread's item-view drawable loading (AssetManager.nativeOpenXmlAssetduring view-holder inflation) past the 5s watchdog threshold.FFmpegThumbnailHelpernow caps native FFmpeg frame extraction to 2 concurrent decodes with a global semaphore, matching the throttle already applied to network thumbnail generation. - Fixed an ANR (App Freeze) on low-end Android TV devices (e.g. onn 4K Pro) caused by the Firebase Analytics Measurement component blocking the main thread for over 5 seconds. UFM initialised Firebase on the main thread at startup, and the Measurement library's internal runnable (
com.google.android.gms.measurement.internal.*, R8-merged into the Play Billing class) stalled the main looper with no app frames on the stack. Firebase Analytics is now initialized on a dedicated background thread — never on the main thread — so the Measurement component cannot stall startup on slow devices while standard analytics events (first_open, session_start, etc.) are still collected on Google builds. And is included in settings backup/restore. - Fixed external players (e.g. VLC, MX Player) hanging or closing when seeking while streaming videos from network shares (SMB, SFTP/SCP, WebDAV, NFS, cloud). The local HTTP streaming proxy opened each range request on a pooled SMB connection with a 2-second socket timeout; a slow seek read exceeded it, aborting the response mid-stream after
Content-Lengthwas already sent, so the player received a truncated body. The proxy now pins one dedicated connection per session (no pooled timeout, no per-seek handshake), serializes chunk reads with a per-session lock, and retries transient read failures on a fresh handle before failing cleanly. Seeking after an idle pause no longer reconnects, and connections are released on session eviction, unregister, or shutdown. - Fixed a false-positive ANR (App Freeze) report when the main thread is blocked reading a compiled layout XML from the APK while showing a dialog — e.g.
Dialog.show()→AlertDialog.onCreate→setContentView→LayoutInflater.inflate/parseInclude→Resources.getLayout→AssetManager.nativeOpenXmlAsset— on slow or busy Android TV devices (e.g. NVIDIA SHIELD). This is a framework disk/I/O resource read (cold resource cache, slow storage) with no app business-logic frame executing and no CPU saturation from other threads, so theAnrWatchdogThreadnow treats a dialog layout-resource-load stall (top frameAssetManager.nativeOpenXmlAsset/openXmlBlockAsset, plusDialog.showandResources.getLayoutframes) as a system-side wait and resets its heartbeat instead of writing a report. Genuine freezes that surface inside the same native asset read — e.g. unbounded FFmpeg thumbnail decoding, which reaches it viaResources.loadDrawableduring RecyclerView adapter inflation — have noDialog.show/Resources.getLayoutframes and are still reported. - Fixed a false-positive ANR (App Freeze) report when the main thread is blocked inside Google Play's injected licensing library —
com.pairip.licensecheck.LicenseClient.retryOrThrow, reached from the framework bound-service disconnect handler (LoadedApk$ServiceDispatcher.doDeath→RunConnection.run) — on Android TV devices. The main-thread stack has zero UFM frames; the wait is entirely inside Google Play infrastructure (PairIP licensing) that the app cannot act on. TheAnrWatchdogThreadpure-framework filter now also treats Google Play's protected libraries (com.google.*,com.pairip.*), which keep their full class names in release builds, as system-side and resets its heartbeat instead of writing a report. Genuine freezes still report because app frames (obfuscated to short names by R8) never match these prefixes. - Fixed a false-positive ANR (App Freeze) report caused by the ANR watchdog sampling its own heartbeat ticker. The watchdog keeps a self-reposting 1-second
Runnableon the main looper to measure responsiveness; when the main looper is stalled for >5 s and then becomes responsive again, the first message it dispatches is the overdue ticker, so the sampled main-thread stack showsMessage.obtain→Handler.postDelayed→ the ticker (R8-merged into a synthetic class such asjf0) — the watchdog's own heartbeat, not app business logic, andMessage.obtain/postDelayedcannot themselves freeze the thread for 5 s. TheAnrWatchdogThreadnow treats a stack whose top frame isMessage.obtainunder aHandler.postDelayed, withlastTickTimestampupdated within the last second (the ticker just ran), as a self-sample and resets its heartbeat instead of writing a report. Genuine busy loops that starve the ticker keeplastTickTimestampstale and are still reported. - Fixed a false-positive ANR (App Freeze) report when the system starts WorkManager's
SystemJobService(JobScheduler) on a low-end Android TV and the bundled library's static class initializer (SystemJobService.<clinit>) takes more than 5 s while the service is being created on the main thread. Service creation is framework-driven (ActivityThread.handleCreateService→AppComponentFactory.instantiateService→Class.newInstance), so the main-thread stack has zero app frames and the block is a library class-loading / static-init cost the app cannot act on. TheAnrWatchdogThreadnow treats a main-thread stack whose top frame is a bundled-library<clinit>during framework service instantiation, with noza.kilowatch.ultimatefilemanagerframes, as a system-side wait and resets its heartbeat instead of writing a report. Genuine freezes that originate in app code keep an app frame on the stack and are still reported. - Extended the watchdog-heartbeat self-sample fix to cover any sampling point inside the ticker's re-post, not just the
Message.obtain-top shape. The watchdog's 1-second heartbeat ticker re-posts itself viamainHandler.postDelayed(this, 1_000L); after the main looper recovers from a >5 s stall, the first dispatched message is the overdue ticker, and a sample can catch that re-post atMessage.obtain, atHandler.postDelayeditself, or anywhere in between (reported from a Samsung Galaxy S25 Ultra, SDK 36).AnrWatchdogThreadnow detects the self-sample structurally — aHandler.postDelayedframe whose direct caller is arun()method dispatched fromHandler.handleCallback, withlastTickTimestampupdated within the last second — instead of requiring the exactMessage.obtaintop frame. Genuine busy loops that starve the ticker keeplastTickTimestampstale and are still reported. - Extended the watchdog-heartbeat self-sample fix to also cover the bare
run()-top shape, where the sample catches the ticker just before it re-posts itself or just after the re-post returned. When the main looper is stalled for >5 s and then becomes responsive again, the overdue ticker runs and a sample can catch its ownrun()directly onHandler.handleCallbackwith noHandler.postDelayedframe on the stack at all (reported from an onn 4K Pro Streaming Device, SDK 34, app 1.7.6).AnrWatchdogThreadnow treats a non-platformrun()frame that is the top of the main-thread stack, dispatched directly byHandler.handleCallback, with nopostDelayedframe, as a self-sample whenlastTickTimestampwas updated within the last second, and resets its heartbeat instead of writing a report. Genuine busy loops that starve the ticker keeplastTickTimestampstale and are still reported. - Fixed a false-positive ANR (App Freeze) report caused by the ANR watchdog sampling the main thread after it recovered from a stall, while it was draining its message backlog. When the main looper is blocked for >5 s and then becomes responsive again, the watchdog can compute
blockedDurationfrom a stale heartbeat timestamp and then sample the thread mid-backlog — catching fast post-stall work with app frames on the stack, such as constructing a CoilImageRequestwhile a Storage Analyzer category list is filled (top framekotlin.collections.EmptyMap.size, a single-instruction getter that cannot hold the thread for 5 s; reported from a Vestel Cosmos TV, app 1.7.7).AnrWatchdogThreadnow treats any sample taken within one second of its own heartbeat ticker running (tickerJustRan) as a false positive and resets its heartbeat instead of writing a report — if the ticker ran, the main looper was demonstrably responsive at sample time, so the sampled stack cannot represent a >5 s block. This generalizes the earlier heartbeat self-sample fix (which matched only two specific stack shapes) to any post-recovery sample. Genuine freezes keep the ticker starved, sotickerJustRanstays false and they are still reported.
Changed
- The Settings "Usage Analytics" toggle now also signals your consent choice to Google's systems via the Firebase Consent API (
setConsentwithanalytics_storageGRANTED/DENIED), in addition to controlling collection. This aligns the analytics opt-out with Google's EU User Consent Policy. The toggle stays enabled by default and no new prompts or dialogs are added — the user experience is unchanged. The Privacy Policy and toggle subtitles were updated to present the toggle as the consent control, and the policy "Last Updated" date advanced to August 2026. - Added a dedicated "Crash & ANR Reporting (Diagnostics)" section to the in-app Privacy Policy covering what diagnostic data is captured when the app crashes or freezes (app version, Android version, device model and manufacturer, exception type/message, and stack trace), that nothing is sent automatically — a prompt asks before each report is sent to KiloWatch — and that the feature can be disabled via Settings → Crash & ANR Reporting. Removed the misleading "crash reports" reference from the Firebase analytics data table so crash reporting is no longer implied to flow through Google. The in-app Privacy Policy, the website Privacy Policy and Terms pages (including their August 2026 "Last Updated" date) were updated to match.