From 0207e12aed0aa373a37568bb24ce8603353b29e5 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Fri, 24 Nov 2017 21:38:10 -0500 Subject: [PATCH 1/8] Revert "Only let one card viewing activity exist at a time" This prevented the editing of cards, as the same activity was used for viewing and editing, but the viewing "instance" was calling finish(). It is simpler to remove the singleTop option. This reverts commit 4e02252b75b68e794466b143370b5d3ea10651f2. --- app/src/main/AndroidManifest.xml | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index a93a40cf7..4b04a84ca 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -36,7 +36,6 @@ android:name=".LoyaltyCardViewActivity" android:theme="@style/AppTheme.NoActionBar" android:configChanges="orientation|screenSize" - android:launchMode="singleTop" android:windowSoftInputMode="stateHidden"/> Date: Fri, 24 Nov 2017 21:39:30 -0500 Subject: [PATCH 2/8] Let insertLoyaltyCard return the new ID Card IDs for new cards will soon need to be known once they are created. This change updates this call to return the new id. --- app/src/main/java/protect/card_locker/DBHelper.java | 4 ++-- .../test/java/protect/card_locker/DatabaseTest.java | 12 ++++++++---- .../java/protect/card_locker/ImportExportTest.java | 3 ++- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/protect/card_locker/DBHelper.java b/app/src/main/java/protect/card_locker/DBHelper.java index 1538a88fb..034cbea81 100644 --- a/app/src/main/java/protect/card_locker/DBHelper.java +++ b/app/src/main/java/protect/card_locker/DBHelper.java @@ -51,7 +51,7 @@ public class DBHelper extends SQLiteOpenHelper } } - public boolean insertLoyaltyCard(final String store, final String note, final String cardId, + public long insertLoyaltyCard(final String store, final String note, final String cardId, final String barcodeType) { SQLiteDatabase db = getWritableDatabase(); @@ -61,7 +61,7 @@ public class DBHelper extends SQLiteOpenHelper contentValues.put(LoyaltyCardDbIds.CARD_ID, cardId); contentValues.put(LoyaltyCardDbIds.BARCODE_TYPE, barcodeType); final long newId = db.insert(LoyaltyCardDbIds.TABLE, null, contentValues); - return (newId != -1); + return newId; } public boolean insertLoyaltyCard(final SQLiteDatabase db, final int id, diff --git a/app/src/test/java/protect/card_locker/DatabaseTest.java b/app/src/test/java/protect/card_locker/DatabaseTest.java index 7eab1444d..7d577469e 100644 --- a/app/src/test/java/protect/card_locker/DatabaseTest.java +++ b/app/src/test/java/protect/card_locker/DatabaseTest.java @@ -36,7 +36,8 @@ public class DatabaseTest public void addRemoveOneGiftCard() { assertEquals(0, db.getLoyaltyCardCount()); - boolean result = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString()); + long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString()); + boolean result = (id != -1); assertTrue(result); assertEquals(1, db.getLoyaltyCardCount()); @@ -56,7 +57,8 @@ public class DatabaseTest @Test public void updateGiftCard() { - boolean result = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString()); + long id = db.insertLoyaltyCard("store", "note", "cardId", BarcodeFormat.UPC_A.toString()); + boolean result = (id != -1); assertTrue(result); assertEquals(1, db.getLoyaltyCardCount()); @@ -86,7 +88,8 @@ public class DatabaseTest @Test public void emptyGiftCardValues() { - boolean result = db.insertLoyaltyCard("", "", "", ""); + long id = db.insertLoyaltyCard("", "", "", ""); + boolean result = (id != -1); assertTrue(result); assertEquals(1, db.getLoyaltyCardCount()); @@ -107,8 +110,9 @@ public class DatabaseTest // that they are sorted for(int index = CARDS_TO_ADD-1; index >= 0; index--) { - boolean result = db.insertLoyaltyCard("store" + index, "note" + index, "cardId" + index, + long id = db.insertLoyaltyCard("store" + index, "note" + index, "cardId" + index, BarcodeFormat.UPC_A.toString()); + boolean result = (id != -1); assertTrue(result); } diff --git a/app/src/test/java/protect/card_locker/ImportExportTest.java b/app/src/test/java/protect/card_locker/ImportExportTest.java index 7f96e5519..858e37145 100644 --- a/app/src/test/java/protect/card_locker/ImportExportTest.java +++ b/app/src/test/java/protect/card_locker/ImportExportTest.java @@ -65,7 +65,8 @@ public class ImportExportTest { String storeName = String.format("store, \"%4d", index); String note = String.format("note, \"%4d", index); - boolean result = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE); + long id = db.insertLoyaltyCard(storeName, note, BARCODE_DATA, BARCODE_TYPE); + boolean result = (id != -1); assertTrue(result); } From 23178d969404c945d12f745e5c236e872f4540aa Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 00:09:42 -0500 Subject: [PATCH 3/8] Optionally add shortcut when creating/editing a card When a card is being added or created, a checkbox will now be presented asking if a shortcut should be made. If selected, when saving a shortcut will be added to the home screen. The shortcut will directly launch the given card in view mode. --- app/src/main/AndroidManifest.xml | 5 +- .../card_locker/LoyaltyCardViewActivity.java | 40 ++++++++++++- .../res/layout/loyalty_card_view_activity.xml | 49 +++++++++++++++ app/src/main/res/values/strings.xml | 2 + .../LoyaltyCardViewActivityTest.java | 59 ++++++++++++++++++- .../card_locker/ShortcutAddedReceiver.java | 39 ++++++++++++ 6 files changed, 191 insertions(+), 3 deletions(-) create mode 100644 app/src/test/java/protect/card_locker/ShortcutAddedReceiver.java diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4b04a84ca..4b7089152 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -8,6 +8,8 @@ android:name="android.permission.READ_EXTERNAL_STORAGE"/> + + android:windowSoftInputMode="stateHidden" + android:exported="true"/> 0 && barcodeTypeField.getText().length() > 0) { String formatString = barcodeTypeField.getText().toString(); @@ -274,6 +284,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity { String store = storeFieldEdit.getText().toString(); String note = noteFieldEdit.getText().toString(); + boolean shouldAddShortcut = shortcutCheckbox.isChecked(); String cardId = cardIdFieldView.getText().toString(); String barcodeType = barcodeTypeField.getText().toString(); @@ -296,12 +307,39 @@ public class LoyaltyCardViewActivity extends AppCompatActivity } else { - db.insertLoyaltyCard(store, note, cardId, barcodeType); + loyaltyCardId = (int)db.insertLoyaltyCard(store, note, cardId, barcodeType); + } + + if(shouldAddShortcut) + { + addShortcut(loyaltyCardId, store); } finish(); } + private void addShortcut(int id, String name) + { + Intent shortcutIntent = new Intent(this, LoyaltyCardViewActivity.class); + shortcutIntent.setAction(Intent.ACTION_MAIN); + Bundle bundle = new Bundle(); + bundle.putInt("id", id); + bundle.putBoolean("view", true); + shortcutIntent.putExtras(bundle); + + Intent intent = new Intent(); + intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); + intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, name); + intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource + .fromContext(this, R.mipmap.ic_launcher)); + intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT"); + // Do not duplicate the shortcut if it is already there + intent.putExtra("duplicate", false); + getApplicationContext().sendBroadcast(intent); + + Toast.makeText(this, R.string.addedShortcut, Toast.LENGTH_LONG).show(); + } + @Override public boolean onCreateOptionsMenu(Menu menu) { diff --git a/app/src/main/res/layout/loyalty_card_view_activity.xml b/app/src/main/res/layout/loyalty_card_view_activity.xml index 8e2a6da93..940a869d7 100644 --- a/app/src/main/res/layout/loyalty_card_view_activity.xml +++ b/app/src/main/res/layout/loyalty_card_view_activity.xml @@ -146,6 +146,55 @@ android:background="@color/inputBorder" /> + + + + + + + + + + + + + + + Store Note + Add Shortcut Card ID Barcode Type @@ -26,6 +27,7 @@ OK Copy ID to clipboard Send… + Added shortcut Edit Loyalty Card Add Loyalty Card diff --git a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java index 81320604c..6f7b56731 100644 --- a/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java +++ b/app/src/test/java/protect/card_locker/LoyaltyCardViewActivityTest.java @@ -9,6 +9,7 @@ import android.os.Bundle; import android.view.Menu; import android.view.View; import android.widget.Button; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.TextView; @@ -29,6 +30,7 @@ import org.robolectric.android.controller.ActivityController; import java.io.IOException; +import static junit.framework.Assert.assertNull; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; @@ -87,6 +89,7 @@ public class LoyaltyCardViewActivityTest */ private void saveLoyaltyCardWithArguments(final Activity activity, final String store, final String note, + final boolean addShortcut, final String cardId, final String barcodeType, boolean creatingNewCard) @@ -103,18 +106,25 @@ public class LoyaltyCardViewActivityTest final EditText storeField = (EditText) activity.findViewById(R.id.storeNameEdit); final EditText noteField = (EditText) activity.findViewById(R.id.noteEdit); + final CheckBox shortcutCheckbox = (CheckBox) activity.findViewById(R.id.shortcutCheckbox); final TextView cardIdField = (TextView) activity.findViewById(R.id.cardIdView); final TextView barcodeTypeField = (TextView) activity.findViewById(R.id.barcodeType); storeField.setText(store); noteField.setText(note); + shortcutCheckbox.setChecked(addShortcut); cardIdField.setText(cardId); barcodeTypeField.setText(barcodeType); + ShortcutAddedReceiver shortcutAddedReceiver = new ShortcutAddedReceiver(); + shortcutAddedReceiver.registerReceiver(activity); + assertEquals(false, activity.isFinishing()); shadowOf(activity).clickMenuItem(R.id.action_save); assertEquals(true, activity.isFinishing()); + shortcutAddedReceiver.unregisterReceiver(activity); + assertEquals(1, db.getLoyaltyCardCount()); LoyaltyCard card = db.getLoyaltyCard(1); @@ -122,6 +132,28 @@ public class LoyaltyCardViewActivityTest assertEquals(note, card.note); assertEquals(cardId, card.cardId); assertEquals(barcodeType, card.barcodeType); + + Intent shortcutRequest = shortcutAddedReceiver.lastRequest(); + + if(addShortcut) + { + assertNotNull(shortcutRequest); + + String name = shortcutRequest.getStringExtra(Intent.EXTRA_SHORTCUT_NAME); + assertEquals(card.store, name); + + Intent startIntent = shortcutRequest.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT); + assertNotNull(startIntent); + Bundle startBundle = startIntent.getExtras(); + assertNotNull(startBundle); + + assertEquals(card.id, startBundle.getInt("id", -1)); + assertEquals(true, startBundle.getBoolean("view", false)); + } + else + { + assertNull(shortcutRequest); + } } /** @@ -184,6 +216,8 @@ public class LoyaltyCardViewActivityTest checkFieldProperties(activity, R.id.storeNameEdit, editVisibility, store); checkFieldProperties(activity, R.id.storeNameView, viewVisibility, store); checkFieldProperties(activity, R.id.noteEdit, editVisibility, note); + checkFieldProperties(activity, R.id.shortcutBorder, editVisibility, null); + checkFieldProperties(activity, R.id.shortcutTablerow, editVisibility, null); checkFieldProperties(activity, R.id.noteView, viewVisibility, note); checkFieldProperties(activity, R.id.cardIdView, View.VISIBLE, cardId); checkFieldProperties(activity, R.id.cardIdDivider, cardId.isEmpty() ? View.GONE : View.VISIBLE, null); @@ -274,7 +308,30 @@ public class LoyaltyCardViewActivityTest checkAllFields(activity, ViewMode.ADD_CARD, "", "", BARCODE_DATA, BARCODE_TYPE); // Save and check the gift card - saveLoyaltyCardWithArguments(activity, "store", "note", BARCODE_DATA, BARCODE_TYPE, true); + saveLoyaltyCardWithArguments(activity, "store", "note", false, BARCODE_DATA, BARCODE_TYPE, true); + } + + @Test + public void startWithoutParametersCaptureBarcodeCreateLoyaltyCardSaveShortcut() throws IOException + { + registerMediaStoreIntentHandler(); + + ActivityController activityController = Robolectric.buildActivity(LoyaltyCardViewActivity.class).create(); + activityController.start(); + activityController.visible(); + activityController.resume(); + + Activity activity = (Activity)activityController.get(); + + checkAllFields(activity, ViewMode.ADD_CARD, "", "", "", ""); + + // Complete barcode capture successfully + captureBarcodeWithResult(activity, R.id.captureButton, true); + + checkAllFields(activity, ViewMode.ADD_CARD, "", "", BARCODE_DATA, BARCODE_TYPE); + + // Save and check the gift card + saveLoyaltyCardWithArguments(activity, "store", "note", true, BARCODE_DATA, BARCODE_TYPE, true); } @Test diff --git a/app/src/test/java/protect/card_locker/ShortcutAddedReceiver.java b/app/src/test/java/protect/card_locker/ShortcutAddedReceiver.java new file mode 100644 index 000000000..d29c17eac --- /dev/null +++ b/app/src/test/java/protect/card_locker/ShortcutAddedReceiver.java @@ -0,0 +1,39 @@ +package protect.card_locker; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; + +public class ShortcutAddedReceiver extends BroadcastReceiver +{ + public static final String SHORTCUT_ADD_REQUEST = "com.android.launcher.action.INSTALL_SHORTCUT"; + + private Intent _request = null; + + @Override + public void onReceive(Context context, Intent intent) + { + _request = intent; + } + + public void registerReceiver(Context context) + { + context.registerReceiver(this, new IntentFilter(SHORTCUT_ADD_REQUEST)); + } + + public void unregisterReceiver(Context context) + { + context.unregisterReceiver(this); + } + + public Intent lastRequest() + { + return _request; + } + + public void reset() + { + _request = null; + } +} From 0df411ee963350065402221bbd3b4e535122a405 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 00:13:55 -0500 Subject: [PATCH 4/8] Revert "Add widget for directly opening specific card" This is largely unneeded, as shortcuts are directly supported now, and the widget was a hacky replacement for shortcuts. This reverts commit ebe6139a64cc54e092165e4c5cb2f712d215c675. --- app/src/main/AndroidManifest.xml | 14 -- .../card_locker/LoyaltyCardCursorAdapter.java | 2 +- .../appwidget/CardAppWidgetConfigure.java | 130 ------------------ .../appwidget/CardAppWidgetProvider.java | 79 ----------- .../main/res/layout/appwidget_provider.xml | 23 ---- app/src/main/res/values/strings.xml | 1 - app/src/main/res/xml/appwidget_provider.xml | 9 -- 7 files changed, 1 insertion(+), 257 deletions(-) delete mode 100644 app/src/main/java/protect/card_locker/appwidget/CardAppWidgetConfigure.java delete mode 100644 app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java delete mode 100644 app/src/main/res/layout/appwidget_provider.xml delete mode 100644 app/src/main/res/xml/appwidget_provider.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4b7089152..f9c1e7a43 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -56,20 +56,6 @@ android:label="" android:configChanges="orientation|screenSize" android:theme="@style/AppTheme.NoActionBar"/> - - - - - - - - - - - - - parent, View view, int position, long id) - { - Context context = CardAppWidgetConfigure.this; - Cursor selected = (Cursor) parent.getItemAtPosition(position); - LoyaltyCard loyaltyCard = LoyaltyCard.toLoyaltyCard(selected); - - Log.d(TAG, "Saving card " + loyaltyCard.store + "," + loyaltyCard.id + " at " + appWidgetId_); - - // Save the association of the card to the widget - saveIdPref(context, appWidgetId_, loyaltyCard.id); - - // Push widget update to surface with newly set association - AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); - CardAppWidgetProvider.updateAppWidget(context, appWidgetManager, appWidgetId_); - - // Make sure we pass back the original appWidgetId - Intent resultValue = new Intent(); - resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId_); - setResult(RESULT_OK, resultValue); - finish(); - } - }); - } - - // Write the prefix to the SharedPreferences object for this widget - static void saveIdPref(Context context, int appWidgetId, int id) - { - SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit(); - prefs.putInt(PREF_PREFIX_KEY + appWidgetId, id); - prefs.commit(); - } - - // Read the prefix from the SharedPreferences object for this widget. - // If there is no preference saved, get the default from a resource - static Integer loadIdPref(Context context, int appWidgetId) - { - SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0); - int id = prefs.getInt(PREF_PREFIX_KEY + appWidgetId, -1); - if(id >= 0) - { - return id; - } - else - { - return null; - } - } -} diff --git a/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java b/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java deleted file mode 100644 index 162e6ff90..000000000 --- a/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java +++ /dev/null @@ -1,79 +0,0 @@ -package protect.card_locker.appwidget; - -import android.app.PendingIntent; -import android.appwidget.AppWidgetManager; -import android.appwidget.AppWidgetProvider; -import android.content.Context; -import android.content.Intent; - -import android.os.Bundle; -import android.util.Log; -import android.widget.RemoteViews; - -import protect.card_locker.DBHelper; -import protect.card_locker.LoyaltyCard; -import protect.card_locker.LoyaltyCardViewActivity; -import protect.card_locker.R; - -public class CardAppWidgetProvider extends AppWidgetProvider -{ - private static final String TAG = "LoyaltyCardLocker"; - - @Override - public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) - { - Log.d(TAG, "CardAppWidgetProvider onUpdate"); - // For each widget that needs an update, get the text that we should display: - // - Create a RemoteViews object for it - // - Set the text in the RemoteViews object - // - Tell the AppWidgetManager to show that views object for the widget. - for (int appWidgetId : appWidgetIds) - { - updateAppWidget(context, appWidgetManager, appWidgetId); - } - } - - static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) - { - Log.d(TAG, "updateAppWidget appWidgetId=" + appWidgetId); - - LoyaltyCard card = null; - DBHelper db = new DBHelper(context); - - Integer id = CardAppWidgetConfigure.loadIdPref(context, appWidgetId); - if(id != null) - { - Log.d(TAG, "updateAppWidget Retrieved id " + id); - card = db.getLoyaltyCard(id); - } - - if(card != null) - { - Log.d(TAG, "updateAppWidget Updating widget " + appWidgetId + " to load " + card.store); - - // Construct the RemoteViews object. It takes the package name (in our case, it's our - // package, but it needs this because on the other side it's the widget host inflating - // the layout from our package). - RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider); - views.setTextViewText(R.id.title, card.store); - - // Launch the view activity when clicked - Intent intent = new Intent(context, LoyaltyCardViewActivity.class); - Bundle extras = new Bundle(); - extras.putInt("id", id); - extras.putBoolean("view", true); - intent.putExtras(extras); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); - views.setOnClickPendingIntent(R.id.widget, pendingIntent); - - // Tell the widget manager - appWidgetManager.updateAppWidget(appWidgetId, views); - } - else - { - Log.d(TAG, "updateAppWidget, no card ID associated with widget " + appWidgetId - + ", ignoring update"); - } - } -} diff --git a/app/src/main/res/layout/appwidget_provider.xml b/app/src/main/res/layout/appwidget_provider.xml deleted file mode 100644 index 1c8c550e4..000000000 --- a/app/src/main/res/layout/appwidget_provider.xml +++ /dev/null @@ -1,23 +0,0 @@ - - - - - - diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 9f5e1d29f..62c7039c2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,7 +33,6 @@ Add Loyalty Card View Loyalty Card Scan Card\'s Barcode - Select Card Image of card\'s barcode diff --git a/app/src/main/res/xml/appwidget_provider.xml b/app/src/main/res/xml/appwidget_provider.xml deleted file mode 100644 index 24c3b655d..000000000 --- a/app/src/main/res/xml/appwidget_provider.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - \ No newline at end of file From 1fc7baa5a0de839a5cb82bb307e665d2de04e992 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 14:20:41 -0500 Subject: [PATCH 5/8] Capture view items in onCreate Some of these will need to be accessed prior to onResume() --- .../card_locker/LoyaltyCardViewActivity.java | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index 519ae9857..b1288df3f 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -89,6 +89,24 @@ public class LoyaltyCardViewActivity extends AppCompatActivity + ", viewLoyaltyCard=" + Boolean.toString(viewLoyaltyCard)); db = new DBHelper(this); + + storeFieldEdit = (EditText) findViewById(R.id.storeNameEdit); + storeFieldView = (TextView) findViewById(R.id.storeNameView); + noteFieldEdit = (EditText) findViewById(R.id.noteEdit); + noteFieldView = (TextView) findViewById(R.id.noteView); + shortcutCheckbox = (CheckBox) findViewById(R.id.shortcutCheckbox); + shortcutBorder = findViewById(R.id.shortcutBorder); + shortcutTablerow = findViewById(R.id.shortcutTablerow); + cardIdFieldView = (TextView) findViewById(R.id.cardIdView); + cardIdDivider = findViewById(R.id.cardIdDivider); + cardIdTableRow = findViewById(R.id.cardIdTableRow); + barcodeTypeField = (TextView) findViewById(R.id.barcodeType); + barcodeImage = (ImageView) findViewById(R.id.barcode); + barcodeImageLayout = findViewById(R.id.barcodeLayout); + barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout); + + captureButton = (Button) findViewById(R.id.captureButton); + enterButton = (Button) findViewById(R.id.enterButton); } @Override @@ -112,24 +130,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity } } - storeFieldEdit = (EditText) findViewById(R.id.storeNameEdit); - storeFieldView = (TextView) findViewById(R.id.storeNameView); - noteFieldEdit = (EditText) findViewById(R.id.noteEdit); - noteFieldView = (TextView) findViewById(R.id.noteView); - shortcutCheckbox = (CheckBox) findViewById(R.id.shortcutCheckbox); - shortcutBorder = findViewById(R.id.shortcutBorder); - shortcutTablerow = findViewById(R.id.shortcutTablerow); - cardIdFieldView = (TextView) findViewById(R.id.cardIdView); - cardIdDivider = findViewById(R.id.cardIdDivider); - cardIdTableRow = findViewById(R.id.cardIdTableRow); - barcodeTypeField = (TextView) findViewById(R.id.barcodeType); - barcodeImage = (ImageView) findViewById(R.id.barcode); - barcodeImageLayout = findViewById(R.id.barcodeLayout); - barcodeCaptureLayout = findViewById(R.id.barcodeCaptureLayout); - - captureButton = (Button) findViewById(R.id.captureButton); - enterButton = (Button) findViewById(R.id.enterButton); - if(updateLoyaltyCard || viewLoyaltyCard) { final LoyaltyCard loyaltyCard = db.getLoyaltyCard(loyaltyCardId); From ec17255a430b36e543bd4845a8868a765993a0f9 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 14:21:29 -0500 Subject: [PATCH 6/8] Remove unneeded local variables The global variables have the same information; no need to look up the information again. --- .../java/protect/card_locker/LoyaltyCardViewActivity.java | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index b1288df3f..a1fb19957 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -343,10 +343,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity @Override public boolean onCreateOptionsMenu(Menu menu) { - final Bundle b = getIntent().getExtras(); - final boolean updateLoyaltyCard = b != null && b.getBoolean("update", false); - final boolean viewLoyaltyCard = b != null && b.getBoolean("view", false); - if(viewLoyaltyCard) { getMenuInflater().inflate(R.menu.card_view_menu, menu); @@ -370,9 +366,6 @@ public class LoyaltyCardViewActivity extends AppCompatActivity { int id = item.getItemId(); - final Bundle b = getIntent().getExtras(); - final int loyaltyCardId = b != null ? b.getInt("id") : 0; - switch(id) { case android.R.id.home: From c733a6c3b9275c29de1660c045cc113d190acded Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 14:22:42 -0500 Subject: [PATCH 7/8] Start shortcuts with singleTop, but not all launches This will prevent shortcuts from creating many views, and causing them to leak. However, do not use singleTop for all launches of the view activity, else the edit mode cannot be entered. --- .../java/protect/card_locker/LoyaltyCardViewActivity.java | 3 +++ app/src/main/java/protect/card_locker/ShortcutHelper.java | 8 +++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index a1fb19957..e594f375e 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -322,6 +322,9 @@ public class LoyaltyCardViewActivity extends AppCompatActivity { Intent shortcutIntent = new Intent(this, LoyaltyCardViewActivity.class); shortcutIntent.setAction(Intent.ACTION_MAIN); + // Prevent instances of the view activity from piling up; if one exists let this + // one replace it. + shortcutIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP); Bundle bundle = new Bundle(); bundle.putInt("id", id); bundle.putBoolean("view", true); diff --git a/app/src/main/java/protect/card_locker/ShortcutHelper.java b/app/src/main/java/protect/card_locker/ShortcutHelper.java index 0b9dbc137..5773e5432 100644 --- a/app/src/main/java/protect/card_locker/ShortcutHelper.java +++ b/app/src/main/java/protect/card_locker/ShortcutHelper.java @@ -103,10 +103,16 @@ class ShortcutHelper { ShortcutInfo prevShortcut = list.get(index); + Intent shortcutIntent = prevShortcut.getIntent(); + + // Prevent instances of the view activity from piling up; if one exists let this + // one replace it. + shortcutIntent.setFlags(shortcutIntent.getFlags() | Intent.FLAG_ACTIVITY_SINGLE_TOP); + ShortcutInfo updatedShortcut = new ShortcutInfo.Builder(context, prevShortcut.getId()) .setShortLabel(prevShortcut.getShortLabel()) .setLongLabel(prevShortcut.getLongLabel()) - .setIntent(prevShortcut.getIntent()) + .setIntent(shortcutIntent) .setIcon(Icon.createWithResource(context, R.drawable.circle)) .setRank(index) .build(); From e0915578ba296d50af8936e284f045f9562ce664 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Sat, 25 Nov 2017 14:23:37 -0500 Subject: [PATCH 8/8] Redraw card info when launched by a shortcut When a shortcut launches the view activity, if the activity already exists it will get onNewIntent() called. This needs to clear out the view items so the next card will be redrawn. --- .../card_locker/LoyaltyCardViewActivity.java | 34 ++++++++++++++----- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java index e594f375e..66e5b4da0 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java @@ -65,6 +65,18 @@ public class LoyaltyCardViewActivity extends AppCompatActivity DBHelper db; + private void extractIntentFields(Intent intent) + { + final Bundle b = intent.getExtras(); + loyaltyCardId = b != null ? b.getInt("id") : 0; + updateLoyaltyCard = b != null && b.getBoolean("update", false); + viewLoyaltyCard = b != null && b.getBoolean("view", false); + + Log.d(TAG, "View activity: id=" + loyaltyCardId + + ", updateLoyaltyCard=" + Boolean.toString(updateLoyaltyCard) + + ", viewLoyaltyCard=" + Boolean.toString(viewLoyaltyCard)); + } + @Override protected void onCreate(Bundle savedInstanceState) { @@ -79,14 +91,7 @@ public class LoyaltyCardViewActivity extends AppCompatActivity actionBar.setDisplayHomeAsUpEnabled(true); } - final Bundle b = getIntent().getExtras(); - loyaltyCardId = b != null ? b.getInt("id") : 0; - updateLoyaltyCard = b != null && b.getBoolean("update", false); - viewLoyaltyCard = b != null && b.getBoolean("view", false); - - Log.d(TAG, "View activity: id=" + loyaltyCardId - + ", updateLoyaltyCard=" + Boolean.toString(updateLoyaltyCard) - + ", viewLoyaltyCard=" + Boolean.toString(viewLoyaltyCard)); + extractIntentFields(getIntent()); db = new DBHelper(this); @@ -109,6 +114,19 @@ public class LoyaltyCardViewActivity extends AppCompatActivity enterButton = (Button) findViewById(R.id.enterButton); } + @Override + public void onNewIntent(Intent intent) + { + Log.i(TAG, "Received new intent"); + extractIntentFields(intent); + + // Reset these fields, so they are re-populated in onResume(). + storeFieldEdit.setText(""); + noteFieldEdit.setText(""); + cardIdFieldView.setText(""); + barcodeTypeField.setText(""); + } + @Override public void onResume() {