From ebe6139a64cc54e092165e4c5cb2f712d215c675 Mon Sep 17 00:00:00 2001 From: Branden Archer Date: Tue, 19 Sep 2017 12:56:35 -0400 Subject: [PATCH] Add widget for directly opening specific card --- 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, 257 insertions(+), 1 deletion(-) create mode 100644 app/src/main/java/protect/card_locker/appwidget/CardAppWidgetConfigure.java create mode 100644 app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java create mode 100644 app/src/main/res/layout/appwidget_provider.xml create 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 e112d6e68..1ee89ad22 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -53,6 +53,20 @@ android:label="" android:configChanges="orientation|screenSize" android:theme="@style/AppTheme.NoActionBar"/> + + + + + + + + + + + + + diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java index 85110ac16..00fb2d45b 100644 --- a/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java +++ b/app/src/main/java/protect/card_locker/LoyaltyCardCursorAdapter.java @@ -8,7 +8,7 @@ import android.view.ViewGroup; import android.widget.CursorAdapter; import android.widget.TextView; -class LoyaltyCardCursorAdapter extends CursorAdapter +public class LoyaltyCardCursorAdapter extends CursorAdapter { public LoyaltyCardCursorAdapter(Context context, Cursor cursor) { diff --git a/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetConfigure.java b/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetConfigure.java new file mode 100644 index 000000000..1f611876f --- /dev/null +++ b/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetConfigure.java @@ -0,0 +1,130 @@ +package protect.card_locker.appwidget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.Bundle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.Toolbar; +import android.util.Log; +import android.view.View; +import android.widget.AdapterView; +import android.widget.ListView; + +import protect.card_locker.DBHelper; +import protect.card_locker.LoyaltyCard; +import protect.card_locker.LoyaltyCardCursorAdapter; +import protect.card_locker.R; + +/** + * The configuration screen for the CardAppWidgetProvider widget. + */ +public class CardAppWidgetConfigure extends AppCompatActivity +{ + static final String TAG = "LoyaltyCardLocker"; + + private static final String PREFS_NAME + = "protect.card_locker.appwidget.CardAppWidgetProvider"; + private static final String PREF_PREFIX_KEY = "prefix_"; + + int appWidgetId_ = AppWidgetManager.INVALID_APPWIDGET_ID; + + @Override + public void onCreate(Bundle bundle) + { + super.onCreate(bundle); + + // Set the result to CANCELED. This will cause the widget host to cancel + // out of the widget placement if they press the back button. + setResult(RESULT_CANCELED); + + setContentView(R.layout.main_activity); + Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); + toolbar.setVisibility(View.GONE); + + setTitle(R.string.selectCardTitle); + + // Find the widget id from the intent. + Intent intent = getIntent(); + Bundle extras = intent.getExtras(); + if (extras != null) + { + appWidgetId_ = extras.getInt( + AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID); + } + + // If they gave us an intent without the widget id, just bail. + if (appWidgetId_ == AppWidgetManager.INVALID_APPWIDGET_ID) + { + finish(); + } + + final DBHelper db = new DBHelper(this); + + // If there are no cards, bail + if(db.getLoyaltyCardCount() == 0) + { + finish(); + } + + final ListView cardList = (ListView) findViewById(R.id.list); + cardList.setVisibility(View.VISIBLE); + + Cursor cardCursor = db.getLoyaltyCardCursor(); + + final LoyaltyCardCursorAdapter adapter = new LoyaltyCardCursorAdapter(this, cardCursor); + cardList.setAdapter(adapter); + + cardList.setOnItemClickListener(new AdapterView.OnItemClickListener() + { + @Override + public void onItemClick(AdapterView 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 new file mode 100644 index 000000000..162e6ff90 --- /dev/null +++ b/app/src/main/java/protect/card_locker/appwidget/CardAppWidgetProvider.java @@ -0,0 +1,79 @@ +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 new file mode 100644 index 000000000..1c8c550e4 --- /dev/null +++ b/app/src/main/res/layout/appwidget_provider.xml @@ -0,0 +1,23 @@ + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 628aab111..1f6d21eca 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -31,6 +31,7 @@ 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 new file mode 100644 index 000000000..24c3b655d --- /dev/null +++ b/app/src/main/res/xml/appwidget_provider.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file