diff --git a/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewConfigureActivity.java b/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewConfigureActivity.java index a87a1f743..4418ce56f 100644 --- a/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewConfigureActivity.java +++ b/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewConfigureActivity.java @@ -40,18 +40,32 @@ public class NotePreviewConfigureActivity extends ReactActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(null); - Intent intent = getIntent(); - Bundle extras = intent.getExtras(); - int appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID; - if (extras != null) { - appWidgetId = extras.getInt( - AppWidgetManager.EXTRA_APPWIDGET_ID, - AppWidgetManager.INVALID_APPWIDGET_ID); - NotePreviewConfigureActivity.appWidgetId = appWidgetId; - } + activity = this; + readAppWidgetId(getIntent()); + } + + /** + * We launch as singleTask, so configuring a second widget while this screen is still alive + * arrives here rather than in onCreate(). Without this the activity would keep writing to + * whichever widget it happened to be opened for first. + */ + @Override + public void onNewIntent(Intent intent) { + super.onNewIntent(intent); + setIntent(intent); + activity = this; + readAppWidgetId(intent); + } + + private void readAppWidgetId(Intent intent) { + Bundle extras = intent != null ? intent.getExtras() : null; + int appWidgetId = extras != null + ? extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID) + : AppWidgetManager.INVALID_APPWIDGET_ID; + + NotePreviewConfigureActivity.appWidgetId = appWidgetId; Intent resultValue = new Intent().putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); setResult(Activity.RESULT_CANCELED, resultValue); - activity = this; } public static void saveAndFinish(Context context) { diff --git a/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewWidget.java b/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewWidget.java index f153e9f3b..14117db71 100644 --- a/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewWidget.java +++ b/apps/mobile/android/app/src/main/java/com/streetwriters/notesnook/NotePreviewWidget.java @@ -8,6 +8,7 @@ import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; +import android.util.Log; import android.widget.RemoteViews; import com.google.gson.Gson; import com.streetwriters.notesnook.datatypes.Note; @@ -21,12 +22,28 @@ public class NotePreviewWidget extends AppWidgetProvider { static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) { String data = context.getSharedPreferences("appPreview", Context.MODE_PRIVATE).getString(String.valueOf(appWidgetId), ""); - if (data.isEmpty()) { + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.note_widget); + + Note note = null; + if (data != null && !data.isEmpty()) { + try { + note = new Gson().fromJson(data, Note.class); + } catch (Exception e) { + Log.e("NotePreviewWidget", "Could not read the note stored for widget " + appWidgetId, e); + } + } + + if (note == null) { + // Either the widget was never configured, or we lost the note it pointed at (ids + // reassigned, data cleared). Point it back at the picker rather than leaving the user + // with an inert widget they can only fix by deleting and re-adding it. + views.setTextViewText(R.id.widget_title, context.getString(R.string.widget_note_unconfigured_title)); + views.setTextViewText(R.id.widget_body, context.getString(R.string.widget_note_unconfigured_body)); + views.setOnClickPendingIntent(R.id.open_note, getConfigurePendingIntent(context, appWidgetId)); + appWidgetManager.updateAppWidget(appWidgetId, views); return; } - Gson gson = new Gson(); - Note note = gson.fromJson(data, Note.class); - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.note_widget); + views.setTextViewText(R.id.widget_title, note.getTitle()); views.setTextViewText(R.id.widget_body, note.getHeadline()); @@ -41,6 +58,22 @@ public class NotePreviewWidget extends AppWidgetProvider { appWidgetManager.updateAppWidget(appWidgetId, views); } + /** + * Reopens the configure screen for this widget. The launcher's own "reconfigure" gesture is + * hard to discover and not offered by every launcher, so an unconfigured widget needs its own + * way back in. + */ + private static PendingIntent getConfigurePendingIntent(Context context, int appWidgetId) { + Intent intent = new Intent(context, NotePreviewConfigureActivity.class); + intent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + // PendingIntent equality ignores extras, so the widget id has to be the request code for + // each widget to get its own. + return PendingIntent.getActivity(context, appWidgetId, intent, + PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE, + WidgetUtils.getActivityOptionsBundle()); + } + @Override public void onAppWidgetOptionsChanged(Context context, AppWidgetManager appWidgetManager, int appWidgetId, Bundle newOptions) { super.onAppWidgetOptionsChanged(context, appWidgetManager, appWidgetId, newOptions); diff --git a/apps/mobile/android/app/src/main/res/layout/note_widget.xml b/apps/mobile/android/app/src/main/res/layout/note_widget.xml index 8a97ce0d3..2eecacfb2 100644 --- a/apps/mobile/android/app/src/main/res/layout/note_widget.xml +++ b/apps/mobile/android/app/src/main/res/layout/note_widget.xml @@ -25,7 +25,7 @@ android:textColor="@color/text" android:textSize="16sp" android:textStyle="bold" - android:text="Widget unconfigured" /> + android:text="@string/widget_note_unconfigured_title" /> + android:text="@string/widget_note_unconfigured_body" /> \ No newline at end of file diff --git a/apps/mobile/android/app/src/main/res/values/strings.xml b/apps/mobile/android/app/src/main/res/values/strings.xml index a9ab7f599..7a86c8d38 100644 --- a/apps/mobile/android/app/src/main/res/values/strings.xml +++ b/apps/mobile/android/app/src/main/res/values/strings.xml @@ -9,6 +9,8 @@ Note Add a note to home screen Quick note + Tap to choose a note + Pick the note you want shown here. Ongoing Snoozed until %1$s Today, %1$s