Added
- Open File Server Button in System Tiles — Added an "Open File Server" action card at the top of the File Server System Tiles screen (Mobile) allowing instant access to launch the main File Server activity (
ServerHostActivity). - APK/XAPK Installation Result Notices & Dialogs — Added clear visual feedback when installing or updating applications from local, network, or remote sources. Displays a Glassmorphic Material dialog (
bg_dialog_glass) upon installation completion on both mobile and Android TV. On success, provides an "Open" button to launch the installed app directly alongside an "OK / Dismiss" button. On failure, displays specific error descriptions (such as signature mismatches from sideloaded APKMirror packages, incompatible device architecture, low storage space, corrupt package, or security block) to explain why the installation failed instead of failing silently. Also posts a status bar notification that opens the detailed result dialog when tapped. - Archive Tools FAB — Replicated the storage Tools FAB experience for ZIP, 7Z, and supported archive viewers. Selecting archive entries (via long-press or icon-tap) activates selection mode and displays a dedicated Tools FAB. Tapping the FAB opens a new
ArchiveToolsBottomSheetwith options to extract ("Extract to..."), move out ("Move out of archive"), or delete ("Delete from archive") single or multiple selected items. On Android TV, pressing the top "Options" button opens the same tools menu for the focused entry. - In-archive preview — tap a file inside a ZIP, 7z, TAR, RAR, or other supported archive to preview it in the built-in viewer without extracting the whole archive. The selected entry is extracted on-demand to a session cache and opened in the existing viewer (images, text, PDF, Office, EPUB, audio, video); long-press (mobile) or the new "Options" button (TV) keeps the extract/move/delete dialog reachable. The preview cache is purged when the archive is closed or the app is backgrounded, and orphaned preview files from a crash are swept on next launch. Works for local, network, and cloud archives.
- "Invert Selection" action in the FAB → Tools menu (mobile): with a selection active, it deselects the current selection and selects everything else in the visible folder, staying in selection mode. Toggleable under Settings → Long Press Icons (mobile only) and works across local, network, and cloud listings.
- Playback speed control (0.5x–3.0x) via long-press on the player screen (mobile).
- Configurable skip length (3s/5s/10s/20s/30s/Disable) in Settings.
- Forward/back skip buttons on the main player, with toast feedback on all player controls.
Changed
- File and folder listings now use natural alpha-numeric sorting (so
file2sorts beforefile10) across local, network (SMB/NFS/FTP/SSH/WebDAV/DLNA) and cloud (Drive/Dropbox/OneDrive/S3/RClone) storage, as well as search results, the SAF folder picker, and archive/slideshow/spreadsheet viewers. Folders-first and pinned-first grouping, and size/date/type sorting, are unchanged. - Redesigned the batch-rename preview into a clearer per-file card with labeled "Current name" / "New name" sections, a sequence number in a bubble, and character-level highlighting of exactly what changes in each name (unchanged names are greyed out); long filenames scroll horizontally so they can be read in full. Added live conflict detection that flags duplicate names, invalid names, and collisions with existing files — blocking the rename for duplicates/invalid names and warning for collisions. The preview and execution order now follow the source listing order, and the mobile dialog is now full-window with a larger preview area. Works on mobile and TV.
Fixed
- Standardized FAB text and icon color (
?attr/colorOnPrimary) across SMB network browser layouts to match local storage browser. - Fixed file/folder selection being cleared whenever the app was backgrounded (Home, Recent Apps/app-switch, or screen lock). Selection now survives backgrounding and is re-applied by path when the folder re-lists, silently dropping items that were deleted or became unreachable; navigating to a different folder or running an operation (create/paste/rename/delete) still clears selection as before.
- Fixed Storage Indexer search returning no results for filenames containing special characters (e.g. a hyphen like
my-file.pdf). Indexed drives now match special-character terms with a literal, case-insensitive filename substring instead of the FTS4 full-text query, so results mirror non-indexed (folder-walk) search; plain alphanumeric searches keep the fast full-text path. - Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread at the entry of the framework's
ViewPropertyAnimatoranimation-end chaining — the creation of the iterator over the running-animators map insideanimatePropertyBy— e.g. top framejava.util.HashMap$KeySet.iterator(the iterator creationanimatePropertyByperforms onmAnimatorMap.keySet()to cancel a running animation on the property before starting the next) underandroid.view.ViewPropertyAnimator.animatePropertyBy→animateProperty→ViewPropertyAnimator.alpha, called by the app's animation-end listener (lh6.run, an R8-obfuscated non-platform frame) dispatched fromViewPropertyAnimator$AnimatorEventListener.onAnimationEndafter aValueAnimator.endAnimation, reached fromAnimationHandler.doAnimationFrame/AnimationHandler$1.doFrameunder aChoreographer.doFramevsync dispatch (Choreographer$FrameDisplayEventReceiver.rununderHandler.handleCallback) — reported from a TCL Smart TV Pro, SDK 31, app 1.8.0-GOOGLE. This is the same family as the already-filteredViewPropertyAnimatoranimation-end chaining report (filter 41, OPPO CPH1937), sampled one frame EARLIER: the currently executing work is a single tiny iterator object allocation that cannot by itself occupy the main thread for 5 s, and the main looper is demonstrably processing a freshly dispatched vsync frame callback at sample time, which a thread parked inside a >5 s block cannot do — so the >5 s block is device-side slowness / CPU starvation on the low-end TV or a post-stall sample. TheAnrWatchdogThreadanimation-end-chaining filter now also treats a main-thread stack whose top frame isjava.util.HashMap$KeySet.iteratordirectly aboveViewPropertyAnimator.animatePropertyBy(with the rest of the animation-end chain below, a non-platform listener directly below thealphacall, and no framework blocking primitive anywhere on the stack) as a false positive and resets its heartbeat instead of writing a report. Genuine freezes keep the main thread parked inside a blocking primitive (a lock, file/network/database I/O or binder frame), or run the animation-end listener's body doing blocking work, and are still reported. - Fixed a false-positive ANR (App Freeze) report when the ANR watchdog samples the main thread reading a compiled XML drawable asset from the APK while a main-looper Runnable inflates a layout whose plain framework view constructor loads its background drawable — e.g. top frame
android.content.res.AssetManager.nativeOpenXmlAsset(the native compiled-XML asset open), underopenXmlBlockAsset→ResourcesImpl.loadXmlResourceParser→loadXmlDrawable→loadDrawableForCookie→loadDrawable→Resources.loadDrawable, reached fromTypedArray.getDrawableForDensity/getDrawable(the view constructor reading itsbackgroundattribute) underandroid.view.View.<init>→ViewGroup.<init>→android.widget.FrameLayout.<init>, created via the frameworkLayoutInflater(createView/createViewFromTag/rInflate/inflate), invoked from an R8-obfuscated non-platformrun()(so3.run, a Runnable dispatched to the main looper) sitting directly onandroid.os.Handler.handleCallback→dispatchMessage→Looper.loopOnce→ActivityThread.main— reported from a SkyworthDigital UHD Google TV STB, SDK 34, app 1.8.1-GOOGLE. This is the main-looper-Runnable layout-inflation counterpart of the already-filtered RecyclerView-checkbox row-inflation read (filter 40): instead ofResources.getXmlreached from anAppCompatCheckBox.<init>under aRecyclerView.onLayoutframe-draw traversal, the read here is aloadXmlDrawableparse of a small compiled XML drawable (a plain FrameLayout's themed background) reached from aTypedArray.getDrawablein a framework view constructor, under aLayoutInflaterinflation the app posted to the main looper as a Runnable. The work is a single bounded native asset read of a small compiled XML drawable that a view constructor runs while the framework inflates the layout — it cannot by itself occupy the main thread for 5 s, and the main looper is demonstrably processing a freshly dispatched message (Handler.handleCallbackdirectly below the Runnable'srun()), which a thread parked inside a >5 s block cannot do, so the >5 s block is device-side slowness / CPU starvation on the low-end TV (the report's ownDlnaSsdpListener,NanoHttpd Main Listener,sshd-SshServer,DefaultDispatcher-worker-*andarch_disk_io_*threads are all RUNNABLE) or a post-stall sample. TheAnrWatchdogThreadnow treats a main-thread stack whose top frame isAssetManager.nativeOpenXmlAsset/openXmlBlockAsset, with aResourcesImpl.loadXmlDrawableframe, aTypedArray.getDrawable/getDrawableForDensityframe, aView.<init>/ViewGroup.<init>/FrameLayout.<init>view-construction frame, aLayoutInflaterframe, a non-platformrun()sitting directly onHandler.handleCallback, and no framework blocking primitive anywhere on the stack, as a false positive and resets its heartbeat instead of writing a report. Genuine freezes keep the main thread parked inside a blocking primitive (a lock, file/network/database I/O, or binder frame), reach the asset read from a bitmap-decode path (ResourcesImpl.loadBitmapDrawable/BitmapFactory/Bitmap.createBitmap— heavy decoding, not a bounded XML parse), or inflate from a frame-draw traversal rather than a main-looper Runnable (the RecyclerView/Choreographer shape, filter 40) — and are still reported. - Fixed an ANR (App Freeze) when the main thread is blocked inside
java.io.File.isDirectory()— the nativegetBooleanAttributes0stat syscall — while the file-list RecyclerView lays out and binds its visible rows during a normal frame-draw traversal — reported from a TCL Smart TV, SDK 34, app 1.8.1-GOOGLE.FileAdapter.FileViewHolder.bind()ranfile.isDirectory()(up to three times),file.lastModified()(up to twice) andfile.length()(up to twice) synchronously on the main thread for every visible row; on slow TV storage with concurrent background file I/O (the report's ownDefaultDispatcher-worker-4is RUNNABLE insideFile.listFiles(),DefaultDispatcher-worker-8is RUNNABLE insideFile.isDirectory()in a sort comparator, andDlnaSsdpListener/NanoHttpd Main Listenerare RUNNABLE), those per-framestatsyscalls accumulated past the 5 s ANR threshold and froze the file browser. The adapter now snapshots each listed file's metadata (isDirectory / size / lastModified) once when the list is submitted (submitList) or appended (appendList), reusing the same snapshot for the folders-first/date-group ordering, and the bind path readsisDirectoryCached()/lengthCached()/lastModifiedCached()from that cache instead of re-runningFile.stat()per row — so a RecyclerView layout no longer performs any filesystem I/O on the main thread. Folder icons, folders-first ordering, child counts, folder/file sizes, dates, thumbnails, selection and click handling are unchanged — only the per-row stat moved off the main thread.