Modernize build environment and fix stability issues for Android API 24+#227
Open
Dehumanizer77 wants to merge 8 commits intotomboy-notes:masterfrom
Open
Modernize build environment and fix stability issues for Android API 24+#227Dehumanizer77 wants to merge 8 commits intotomboy-notes:masterfrom
Dehumanizer77 wants to merge 8 commits intotomboy-notes:masterfrom
Conversation
- Replace all managedQuery/startManagingCursor with ContentResolver.query() to eliminate cursor lifecycle race condition that caused random sync crashes when the user navigated away mid-sync (Activity.onStop deactivated cursors while the background thread was still reading them) - Add null guards after getNoteByGuid() calls in SyncService to prevent NPE when a note is unexpectedly absent from the database during sync - Fix null cursor NPEs throughout NoteManager (cursor.close() on null cursor) - Fix Html.fromHtml() deprecation for API 24+ - Replace Apache HttpClient with legacy library support (useLibrary + uses-library in manifest) so web sync works on Android 9+ (API 28+) - Fix FileUriExposedException in Send.java: replace Uri.fromFile() and MODE_WORLD_READABLE with FileProvider + FLAG_GRANT_READ_URI_PERMISSION - Add runtime WRITE_EXTERNAL_STORAGE permission request before SD card sync on API 23-28, with automatic sync resume on grant - Update build: AGP 0.5 -> 7.4.2, Gradle 1.6 -> 7.6.4, compileSdk/targetSdk raised to 34/33, add AndroidX Core 1.9.0, add settings.gradle - Add android:requestLegacyExternalStorage for Android 10 compatibility - Add android:exported attributes (required on API 31+) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Drop compileSdk from 34 to 33 to match AGP 7.4.2 tested range
- Add gradle.properties enabling android.useAndroidX and android.enableJetifier,
required since we now depend on androidx.core (for FileProvider)
- Add .gitignore for build/, .gradle/, local.properties and APK artifacts
- Fix AAPT2-rejected style parent refs: style/Foo -> @style/Foo in styles.xml
- Fix malformed ListView IDs rejected by AAPT2:
file_picker_content_view.xml: @+id/android:list -> @android:id/list
shortcuts_list.xml: @android:id/android:list -> @android:id/list
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- onResume: move super.onResume() to top and add null guard for getCurrentService() - onCreateDialog/onPrepareDialog: null-safe getCurrentService().getDescription() - startSyncing: early return if no sync service configured (null getCurrentService) - SyncMessageHandler: replace showDialog() with safeShowDialog() to guard against BadTokenException when activity window is not attached; null-safe currentService - Add safeShowDialog() helper that checks isFinishing/isDestroyed before showing - onActivityResult: null check before calling resolvedConflict() - onCreateContextMenu: null check on dialogNote before accessing getTags() - SyncManager.cancel(): null check on service field to prevent NPE on destroy - ActionBarHelperHoneycomb/ICS.onPostCreate(): null check on getActionBar() to prevent NPE when theme does not provide a native ActionBar Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On Samsung Android builds the framework registers the list adapter's cursor in Activity.mManagedCursors via internal paths that bypass startManagingCursor() overrides. When the user navigates back from a note (triggering onRestart()), performRestart() tries to requery() the cursor after it has been closed and throws IllegalStateException. Fix strategy (belt-and-suspenders): - Override startManagingCursor() as a no-op to block direct registration - Override onStop() to clear mManagedCursors via reflection after the framework has already stopped the activity; performRestart() then finds an empty list and skips the requery loop entirely - Properly close the list adapter cursor in updateNotesList() and onDestroy() so leaked cursors don't accumulate - Close localGuids cursor in SyncService.prepareSyncableNotes() which was never closed after the loop (cursor leak on every sync) - Close ShortcutActivity adapter cursor in onDestroy() Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…crash Fix crash in performRestart() caused by closed managed cursor
* Apply Codex suggested fixes * Fix potential NPE in SnowySyncService finally block ContentResolver.query() can return null, so newLocalNotes must be null-checked before calling close() in the finally block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* Apply Codex suggested fixes * Fix potential NPE in SnowySyncService finally block ContentResolver.query() can return null, so newLocalNotes must be null-checked before calling close() in the finally block. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Member
|
As I said, in #224. I'm willing to accept this, I reviewed it for obvious backdoors and didn't find anything but I'm not cutting a release for the play store. I mean I haven't worked on this project for years... |
* Prepare release 0.8.0-dehumanizer77 Update versionName to 0.8.0-dehumanizer77, add release signing config (password supplied via -P gradle properties at build time), and add keystore files to .gitignore. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * Fix sync conflict resolution and harden push error handling - Fix pushNotes() to check for null/empty server responses before JSON parsing - Reset syncProgress to 100 on all error paths to prevent sync from getting stuck - Guard against null tags from database in NoteManager and SyncService - Fix cursor null check in SyncService.prepareSyncableNotes (same pattern as #4) - Fix "chose remote" in differentNotes conflict to push delete command for local note to server, preventing the conflict from reappearing on next sync Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Author
|
I have added one more fix, I have noticed errors after a conflict appeared, the last commit fixes it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This captures:
This is my very first real use of Claude, sorry if I missed anything. I also made Codex to review the code.