diff options
6 files changed, 89 insertions, 49 deletions
diff --git a/app/build.gradle b/app/build.gradle index a5a12781..15b7fa6c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,8 +13,8 @@ android { applicationId "it.niedermann.owncloud.notes" minSdkVersion 14 targetSdkVersion 29 - versionCode 2011001 - versionName "2.11.1" + versionCode 2011002 + versionName "2.11.2" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { diff --git a/app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/NoteListWidgetFactory.java b/app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/NoteListWidgetFactory.java index d1cd82d2..7ec936de 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/NoteListWidgetFactory.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/android/appwidget/NoteListWidgetFactory.java @@ -7,6 +7,7 @@ import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.preference.PreferenceManager; +import android.util.Log; import android.widget.RemoteViews; import android.widget.RemoteViewsService; @@ -22,6 +23,8 @@ import it.niedermann.owncloud.notes.util.Notes; import static it.niedermann.owncloud.notes.android.appwidget.NoteListWidget.DARK_THEME_KEY; public class NoteListWidgetFactory implements RemoteViewsService.RemoteViewsFactory { + private static final String TAG = NoteListWidgetFactory.class.getCanonicalName(); + private final Context context; private final int displayMode; private final boolean darkTheme; @@ -82,14 +85,15 @@ public class NoteListWidgetFactory implements RemoteViewsService.RemoteViewsFact } @Override - public RemoteViews getViewAt(int i) { + public RemoteViews getViewAt(int position) { RemoteViews note_content; - if (dbNotes == null || dbNotes.get(i) == null) { + if (dbNotes == null || position > dbNotes.size() - 1 || dbNotes.get(position) == null) { + Log.e(TAG, "Could not find position \"" + position + "\" in dbNotes list."); return null; } - DBNote note = dbNotes.get(i); + DBNote note = dbNotes.get(position); final Intent fillInIntent = new Intent(); final Bundle extras = new Bundle(); @@ -102,22 +106,16 @@ public class NoteListWidgetFactory implements RemoteViewsService.RemoteViewsFact note_content = new RemoteViews(context.getPackageName(), R.layout.widget_entry_dark); note_content.setOnClickFillInIntent(R.id.widget_note_list_entry_dark, fillInIntent); note_content.setTextViewText(R.id.widget_entry_content_tv_dark, note.getTitle()); - - if (note.isFavorite()) { - note_content.setImageViewResource(R.id.widget_entry_fav_icon_dark, R.drawable.ic_star_yellow_24dp); - } else { - note_content.setImageViewResource(R.id.widget_entry_fav_icon_dark, R.drawable.ic_star_grey_ccc_24dp); - } + note_content.setImageViewResource(R.id.widget_entry_fav_icon_dark, note.isFavorite() + ? R.drawable.ic_star_yellow_24dp + : R.drawable.ic_star_grey_ccc_24dp); } else { note_content = new RemoteViews(context.getPackageName(), R.layout.widget_entry); note_content.setOnClickFillInIntent(R.id.widget_note_list_entry, fillInIntent); note_content.setTextViewText(R.id.widget_entry_content_tv, note.getTitle()); - - if (note.isFavorite()) { - note_content.setImageViewResource(R.id.widget_entry_fav_icon, R.drawable.ic_star_yellow_24dp); - } else { - note_content.setImageViewResource(R.id.widget_entry_fav_icon, R.drawable.ic_star_grey_ccc_24dp); - } + note_content.setImageViewResource(R.id.widget_entry_fav_icon, note.isFavorite() + ? R.drawable.ic_star_yellow_24dp + : R.drawable.ic_star_grey_ccc_24dp); } return note_content; diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java index 2c16df9c..8ae8e8f6 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NoteServerSyncHelper.java @@ -1,5 +1,6 @@ package it.niedermann.owncloud.notes.persistence; +import android.accounts.NetworkErrorException; import android.content.BroadcastReceiver; import android.content.ClipData; import android.content.ClipboardManager; @@ -225,10 +226,15 @@ public class NoteServerSyncHelper { if (syncActive.get(ssoAccount.name) == null) { syncActive.put(ssoAccount.name, false); } - Log.d(TAG, "Sync requested (" + (onlyLocalChanges ? "onlyLocalChanges" : "full") + "; " + (syncActive.get(ssoAccount.name) ? "sync active" : "sync NOT active") + ") ..."); - if (isSyncPossible() && (!syncActive.get(ssoAccount.name) || onlyLocalChanges)) { + Log.d(TAG, "Sync requested (" + (onlyLocalChanges ? "onlyLocalChanges" : "full") + "; " + (Boolean.valueOf(true).equals(syncActive.get(ssoAccount.name)) ? "sync active" : "sync NOT active") + ") ..."); + if (isSyncPossible() && (!Boolean.valueOf(true).equals(syncActive.get(ssoAccount.name)) || onlyLocalChanges)) { Log.d(TAG, "... starting now"); - SyncTask syncTask = new SyncTask(db.getLocalAccountByAccountName(ssoAccount.name), ssoAccount, onlyLocalChanges); + final LocalAccount account = db.getLocalAccountByAccountName(ssoAccount.name); + if(account == null) { + Log.e(TAG, "LocalAccount for ssoAccount \"" + ssoAccount.name + "\" is null. Cannot synchronize.", new IllegalStateException()); + return; + } + SyncTask syncTask = new SyncTask(account, ssoAccount, onlyLocalChanges); syncTask.addCallbacks(ssoAccount, callbacksPush.get(ssoAccount.name)); callbacksPush.put(ssoAccount.name, new ArrayList<>()); if (!onlyLocalChanges) { @@ -240,15 +246,25 @@ public class NoteServerSyncHelper { Log.d(TAG, "... scheduled"); syncScheduled.put(ssoAccount.name, true); if (callbacksPush.containsKey(ssoAccount.name) && callbacksPush.get(ssoAccount.name) != null) { - for (ISyncCallback callback : callbacksPush.get(ssoAccount.name)) { - callback.onScheduled(); + final List<ISyncCallback> callbacks = callbacksPush.get(ssoAccount.name); + if (callbacks != null) { + for (ISyncCallback callback : callbacks) { + callback.onScheduled(); + } + } else { + Log.w(TAG, "List of push-callbacks was set for account \"" + ssoAccount.name + "\" but it was null"); } } } else { Log.d(TAG, "... do nothing"); if (callbacksPush.containsKey(ssoAccount.name) && callbacksPush.get(ssoAccount.name) != null) { - for (ISyncCallback callback : callbacksPush.get(ssoAccount.name)) { - callback.onScheduled(); + final List<ISyncCallback> callbacks = callbacksPush.get(ssoAccount.name); + if (callbacks != null) { + for (ISyncCallback callback : callbacks) { + callback.onScheduled(); + } + } else { + Log.w(TAG, "List of push-callbacks was set for account \"" + ssoAccount.name + "\" but it was null"); } } } @@ -256,25 +272,44 @@ public class NoteServerSyncHelper { } private void updateNetworkStatus() { - ConnectivityManager connMgr = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); - NetworkInfo activeInfo = connMgr.getActiveNetworkInfo(); - - if (activeInfo != null && activeInfo.isConnected()) { - networkConnected = true; - isSyncPossible = - !syncOnlyOnWifi || ((ConnectivityManager) context.getApplicationContext() - .getSystemService(Context.CONNECTIVITY_SERVICE)) - .getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected(); - - if (isSyncPossible) { - Log.d(TAG, "Network connection established."); + try { + ConnectivityManager connMgr = (ConnectivityManager) context.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE); + + if (connMgr == null) { + throw new NetworkErrorException("ConnectivityManager is null"); + } + + NetworkInfo activeInfo = connMgr.getActiveNetworkInfo(); + + if (activeInfo == null) { + throw new NetworkErrorException("NetworkInfo is null"); + } + + if (activeInfo.isConnected()) { + networkConnected = true; + + NetworkInfo networkInfo = connMgr.getNetworkInfo((ConnectivityManager.TYPE_WIFI)); + + if (networkInfo == null) { + throw new NetworkErrorException("connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI) is null"); + } + + isSyncPossible = !syncOnlyOnWifi || networkInfo.isConnected(); + + if (isSyncPossible) { + Log.d(TAG, "Network connection established."); + } else { + Log.d(TAG, "Network connected, but not used because only synced on wifi."); + } } else { - Log.d(TAG, "Network connected, but not used because only synced on wifi."); + networkConnected = false; + isSyncPossible = false; + Log.d(TAG, "No network connection."); } - } else { + } catch (NetworkErrorException e) { + e.printStackTrace(); networkConnected = false; isSyncPossible = false; - Log.d(TAG, "No network connection."); } } @@ -286,8 +321,10 @@ public class NoteServerSyncHelper { private final LocalAccount localAccount; private final SingleSignOnAccount ssoAccount; private final boolean onlyLocalChanges; - @NonNull private final Map<String, List<ISyncCallback>> callbacks = new HashMap<>(); - @NonNull private final List<Throwable> exceptions = new ArrayList<>(); + @NonNull + private final Map<String, List<ISyncCallback>> callbacks = new HashMap<>(); + @NonNull + private final List<Throwable> exceptions = new ArrayList<>(); SyncTask(@NonNull LocalAccount localAccount, @NonNull SingleSignOnAccount ssoAccount, boolean onlyLocalChanges) { this.localAccount = localAccount; @@ -305,7 +342,7 @@ public class NoteServerSyncHelper { if (!syncScheduled.containsKey(ssoAccount.name) || syncScheduled.get(ssoAccount.name) == null) { syncScheduled.put(ssoAccount.name, false); } - if (!onlyLocalChanges && syncScheduled.get(ssoAccount.name)) { + if (!onlyLocalChanges && Boolean.valueOf(true).equals(syncScheduled.get(ssoAccount.name))) { syncScheduled.put(ssoAccount.name, false); } syncActive.put(ssoAccount.name, true); @@ -366,8 +403,8 @@ public class NoteServerSyncHelper { Log.v(TAG, " ...delete (from server and local)"); try { notesClient.deleteNote(ssoAccount, note.getRemoteId()); - } catch(NextcloudHttpRequestFailedException e) { - if(e.getStatusCode() == HTTP_NOT_FOUND) { + } catch (NextcloudHttpRequestFailedException e) { + if (e.getStatusCode() == HTTP_NOT_FOUND) { Log.v(TAG, " ...delete (note has already been deleted remotely)"); } else { throw e; @@ -422,7 +459,12 @@ public class NoteServerSyncHelper { Log.v(TAG, " ... unchanged"); } else if (idMap.containsKey(remoteNote.getRemoteId())) { Log.v(TAG, " ... found -> Update"); - db.updateNote(idMap.get(remoteNote.getRemoteId()), remoteNote, null); + Long remoteId = idMap.get(remoteNote.getRemoteId()); + if (remoteId != null) { + db.updateNote(remoteId, remoteNote, null); + } else { + Log.e(TAG, "Tried to update note from server, but remoteId of note is null. " + remoteNote); + } } else { Log.v(TAG, " ... create"); db.addNote(localAccount.getId(), remoteNote); @@ -519,7 +561,7 @@ public class NoteServerSyncHelper { db.notifyNotesChanged(); db.updateDynamicShortcuts(localAccount.getId()); // start next sync if scheduled meanwhile - if (syncScheduled.containsKey(ssoAccount.name) && syncScheduled.get(ssoAccount.name) != null && syncScheduled.get(ssoAccount.name)) { + if (syncScheduled.containsKey(ssoAccount.name) && syncScheduled.get(ssoAccount.name) != null && Boolean.valueOf(true).equals(syncScheduled.get(ssoAccount.name))) { scheduleSync(ssoAccount, false); } } diff --git a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java index 9ad8995e..6406711f 100644 --- a/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java +++ b/app/src/main/java/it/niedermann/owncloud/notes/persistence/NotesDatabase.java @@ -316,7 +316,7 @@ public class NotesDatabase extends AbstractNotesDatabase { } /** - * Returns a list of all Notes in the Database with were modified locally + * Returns a list of all Notes in the Database which were modified locally * * @return List<Note> */ diff --git a/fastlane/metadata/android/en-US/changelogs/2011001.txt b/fastlane/metadata/android/en-US/changelogs/2011001.txt index 3c6a387a..a9bc4d50 100644 --- a/fastlane/metadata/android/en-US/changelogs/2011001.txt +++ b/fastlane/metadata/android/en-US/changelogs/2011001.txt @@ -1,2 +1 @@ -- 🔒 Password protection (#354) - special thanks to @beatbrot -- 🗨️ Remove toasts (#749)
\ No newline at end of file +- 🐞 Fix exception on startup
\ No newline at end of file diff --git a/fastlane/metadata/android/en-US/changelogs/2011002.txt b/fastlane/metadata/android/en-US/changelogs/2011002.txt new file mode 100644 index 00000000..e7382f8e --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/2011002.txt @@ -0,0 +1 @@ +- 🐞 Stability improvements and bugfixes for synchronization and list widget
\ No newline at end of file |