Skip to content

MainActivity: auto-refresh on system contact changes (ContentObserver)#555

Open
dsremo wants to merge 1 commit into
FossifyOrg:mainfrom
dsremo:dsremo/contentobserver-auto-refresh
Open

MainActivity: auto-refresh on system contact changes (ContentObserver)#555
dsremo wants to merge 1 commit into
FossifyOrg:mainfrom
dsremo:dsremo/contentobserver-auto-refresh

Conversation

@dsremo
Copy link
Copy Markdown

@dsremo dsremo commented May 13, 2026

Problem

When a contact is added, edited, or deleted by another app — system contact picker, a sync adapter (Google/Nextcloud/etc.), CSV importer, or any third-party tool that writes to ContactsContract.Contacts — Fossify Contacts currently only re-reads the contact list on the next onResume(). If the user is already on the contact list while the change happens, the stale list stays on screen until they manually navigate away and back.

Fix

Register a ContentObserver on ContactsContract.Contacts.CONTENT_URI in onResume(), unregister in onPause(). When the observer fires, call refreshContacts(ALL_TABS_MASK) debounced by 500 ms so a bulk row-by-row update (e.g., a sync of 200 contacts) coalesces into a single refresh rather than firing 200 times.

Files touched

  • app/src/main/kotlin/org/fossify/contacts/activities/MainActivity.kt (+38)

Lifecycle correctness

  • Observer is registered only while the activity is in the resumed state.
  • onPause() always unregisters before the activity becomes paused — no observer leaks across configuration changes or process death.
  • runCatching wraps both register and unregister to swallow the rare IllegalStateException from the framework when the resolver state is invalid (Android 11 occasionally throws on rapid pause/resume cycles).
  • 500 ms debounce uses the existing main-thread handler — no new threads.

Tested

Manual: open Fossify Contacts → keep it foreground → from a separate app (adb shell content insert) add and delete contacts → list refreshes within ~500 ms each time without user input.

Notes

If you'd prefer a different debounce window or want this gated behind a preference, happy to adjust.

When a contact is added/edited/deleted by another app (e.g., system
contact picker, sync adapter, contact-import tools), Fossify Contacts
currently only re-reads the contact list on next onResume(). If the
user is already on the contact list when the change happens, the stale
list stays on screen until they navigate away and back.

This registers a ContentObserver on ContactsContract.Contacts.CONTENT_URI
in onResume() and unregisters in onPause(). When the observer fires,
refreshContacts(ALL_TABS_MASK) is debounced by 500ms (to coalesce
multi-row bulk operations) and executed on the main thread handler.

Behaviour outside of registered visibility (i.e., when the activity is
paused/destroyed) is unchanged - no work happens off-screen. The observer
runs only while the activity is visible.
@dsremo dsremo requested a review from naveensingh as a code owner May 13, 2026 09:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

1 participant