diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 32749ea0f..7446d69ab 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -112,6 +112,7 @@ dependencies {
implementation("androidx.appcompat:appcompat:1.7.1")
implementation("androidx.constraintlayout:constraintlayout:2.2.1")
implementation("androidx.core:core-ktx:1.16.0")
+ implementation("androidx.core:core-remoteviews:1.1.0")
implementation("androidx.core:core-splashscreen:1.0.1")
implementation("androidx.exifinterface:exifinterface:1.4.1")
implementation("androidx.palette:palette:1.0.0")
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index a65683a29..adb39906a 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -218,9 +218,5 @@
-
-
diff --git a/app/src/main/java/protect/card_locker/CatimaRemoteViewsService.kt b/app/src/main/java/protect/card_locker/CatimaRemoteViewsService.kt
deleted file mode 100644
index d4ca18443..000000000
--- a/app/src/main/java/protect/card_locker/CatimaRemoteViewsService.kt
+++ /dev/null
@@ -1,110 +0,0 @@
-package protect.card_locker
-
-import android.content.Context
-import android.content.Intent
-import android.database.sqlite.SQLiteDatabase
-import android.graphics.Color
-import android.graphics.drawable.Icon
-import android.os.Build
-import android.view.View
-import android.widget.RemoteViews
-import android.widget.RemoteViewsService
-import protect.card_locker.DBHelper.LoyaltyCardArchiveFilter
-import kotlin.math.max
-
-class CatimaWidgetRemoteViewsFactory(private var context: Context) :
- RemoteViewsService.RemoteViewsFactory {
-
- private var mDatabase: SQLiteDatabase = DBHelper(context).readableDatabase
-
- override fun onCreate() {
- onDataSetChanged()
- }
-
- private var mCards: ArrayList = ArrayList()
-
- override fun onDataSetChanged() {
- val mOrder = Utils.getLoyaltyCardOrder(context);
- val mOrderDirection = Utils.getLoyaltyCardOrderDirection(context);
-
- val cur = DBHelper.getLoyaltyCardCursor(
- mDatabase,
- "",
- null,
- mOrder,
- mOrderDirection,
- LoyaltyCardArchiveFilter.Unarchived
- )
-
- mCards.clear()
- if (cur.moveToFirst()) {
- do {
- val item = LoyaltyCard.fromCursor(context, cur)
- mCards.add(item)
- } while (cur.moveToNext())
- }
- }
-
- override fun onDestroy() {}
-
- override fun getCount(): Int {
- return max(1, mCards.count())
- }
-
- private fun createRemoteView(item: LoyaltyCard): RemoteViews
- {
- val rv = RemoteViews(context.packageName, R.layout.catima_widget_item).apply {
- val headerColor = Utils.getHeaderColor(context, item)
- val foreground = if (Utils.needsDarkForeground(headerColor)) Color.BLACK else Color.WHITE
- setInt(R.id.item_container, "setBackgroundColor", headerColor)
- val icon = item.getImageThumbnail(context)
- // setImageViewIcon is not supported on Android 5, so force Android 5 down the text path
- if (icon != null && Build.VERSION.SDK_INT >= 23) {
- setInt(R.id.item_container, "setBackgroundColor", foreground)
- setImageViewIcon(R.id.item_image, Icon.createWithBitmap(icon))
- setViewVisibility(R.id.item_text, View.INVISIBLE)
- setViewVisibility(R.id.item_image, View.VISIBLE)
- } else {
- setImageViewBitmap(R.id.item_image, null)
- setTextViewText(R.id.item_text, item.store)
- setViewVisibility(R.id.item_text, View.VISIBLE)
- setViewVisibility(R.id.item_image, View.INVISIBLE)
- setTextColor(
- R.id.item_text,
- foreground
- )
- }
-
- val fillInIntent = Intent().apply {
- putExtra(LoyaltyCardViewActivity.BUNDLE_ID, item.id)
- }
-
- setOnClickFillInIntent(R.id.item_container, fillInIntent)
- }
-
- return rv
- }
-
- override fun getViewAt(position: Int): RemoteViews {
- if (mCards.isEmpty()) {
- return RemoteViews(context.packageName, R.layout.catima_widget_empty)
- }
-
- val item = mCards[position]
- return createRemoteView(item)
- }
-
- override fun getLoadingView(): RemoteViews? = null
-
- override fun getViewTypeCount(): Int = 1
-
- override fun getItemId(position: Int): Long = position.toLong()
-
- override fun hasStableIds(): Boolean = true
-}
-
-class CatimaRemoteViewsService : RemoteViewsService() {
- override fun onGetViewFactory(intent: Intent?): RemoteViewsFactory {
- return CatimaWidgetRemoteViewsFactory(applicationContext)
- }
-}
\ No newline at end of file
diff --git a/app/src/main/java/protect/card_locker/CatimaWidget.kt b/app/src/main/java/protect/card_locker/CatimaWidget.kt
index 86b6c6070..d5984ecfa 100644
--- a/app/src/main/java/protect/card_locker/CatimaWidget.kt
+++ b/app/src/main/java/protect/card_locker/CatimaWidget.kt
@@ -3,22 +3,36 @@ package protect.card_locker
import android.app.PendingIntent
import android.appwidget.AppWidgetManager
import android.appwidget.AppWidgetProvider
+import android.content.ComponentName
import android.content.Context
import android.content.Intent
+import android.graphics.Color
+import android.graphics.drawable.Icon
+import android.os.Build
+import android.view.View
import android.widget.RemoteViews
+import androidx.core.widget.RemoteViewsCompat
+import protect.card_locker.DBHelper.LoyaltyCardArchiveFilter
class CatimaWidget : AppWidgetProvider() {
+ fun updateAll(context: Context) {
+ val appWidgetManager = AppWidgetManager.getInstance(context)
+ val componentName = ComponentName(context, CatimaWidget::class.java)
+ onUpdate(
+ context,
+ appWidgetManager,
+ appWidgetManager.getAppWidgetIds(componentName)
+ )
+ }
+
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
for (appWidgetId in appWidgetIds) {
+ // Prepare generic widget
val views = RemoteViews(context.packageName, R.layout.catima_widget)
- val intent = Intent(context, CatimaRemoteViewsService::class.java)
- intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
- views.setRemoteAdapter(R.id.grid_view, intent)
-
val templateIntent = Intent(context, LoyaltyCardViewActivity::class.java)
val pendingIntent = PendingIntent.getActivity(
context,
@@ -26,9 +40,75 @@ class CatimaWidget : AppWidgetProvider() {
templateIntent,
PendingIntent.FLAG_MUTABLE or PendingIntent.FLAG_UPDATE_CURRENT
)
-
views.setPendingIntentTemplate(R.id.grid_view, pendingIntent)
+
+ // Get cards
+ val order = Utils.getLoyaltyCardOrder(context);
+ val orderDirection = Utils.getLoyaltyCardOrderDirection(context);
+ val database = DBHelper(context).readableDatabase
+
+ val loyaltyCardCursor = DBHelper.getLoyaltyCardCursor(
+ database,
+ "",
+ null,
+ order,
+ orderDirection,
+ LoyaltyCardArchiveFilter.Unarchived
+ )
+
+ // Bind every card to cell in the grid
+ val remoteCollectionItemsBuilder = RemoteViewsCompat.RemoteCollectionItems.Builder()
+ if (loyaltyCardCursor.moveToFirst()) {
+ do {
+ val loyaltyCard = LoyaltyCard.fromCursor(context, loyaltyCardCursor)
+ remoteCollectionItemsBuilder.addItem(
+ loyaltyCard.id.toLong(),
+ createRemoteViews(
+ context, loyaltyCard
+ )
+ )
+ } while (loyaltyCardCursor.moveToNext())
+ }
+ RemoteViewsCompat.setRemoteAdapter(context, views, appWidgetId, R.id.grid_view, remoteCollectionItemsBuilder.build())
+
+ // Let Android know the widget is ready for display
appWidgetManager.updateAppWidget(appWidgetId, views)
}
}
+
+ private fun createRemoteViews(context: Context, loyaltyCard: LoyaltyCard): RemoteViews {
+ // Create a single cell for the grid view, bind it to open in the LoyaltyCardViewActivity
+ // Note: Android 5 will not use bitmaps
+ val remoteViews = RemoteViews(context.packageName, R.layout.catima_widget_item).apply {
+ val headerColor = Utils.getHeaderColor(context, loyaltyCard)
+ val foreground = if (Utils.needsDarkForeground(headerColor)) Color.BLACK else Color.WHITE
+ setInt(R.id.item_container, "setBackgroundColor", headerColor)
+ val icon = loyaltyCard.getImageThumbnail(context)
+ // setImageViewIcon is not supported on Android 5, so force Android 5 down the text path
+ if (icon != null && Build.VERSION.SDK_INT >= 23) {
+ setInt(R.id.item_container, "setBackgroundColor", foreground)
+ setImageViewIcon(R.id.item_image, Icon.createWithBitmap(icon))
+ setViewVisibility(R.id.item_text, View.INVISIBLE)
+ setViewVisibility(R.id.item_image, View.VISIBLE)
+ } else {
+ setImageViewBitmap(R.id.item_image, null)
+ setTextViewText(R.id.item_text, loyaltyCard.store)
+ setViewVisibility(R.id.item_text, View.VISIBLE)
+ setViewVisibility(R.id.item_image, View.INVISIBLE)
+ setTextColor(
+ R.id.item_text,
+ foreground
+ )
+ }
+
+ // Add the card ID to the intent template
+ val fillInIntent = Intent().apply {
+ putExtra(LoyaltyCardViewActivity.BUNDLE_ID, loyaltyCard.id)
+ }
+
+ setOnClickFillInIntent(R.id.item_container, fillInIntent)
+ }
+
+ return remoteViews
+ }
}
\ No newline at end of file
diff --git a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
index eeb9383ba..4317c4f11 100644
--- a/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
+++ b/app/src/main/java/protect/card_locker/LoyaltyCardViewActivity.java
@@ -880,6 +880,8 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
} else if (id == R.id.action_star_unstar) {
DBHelper.updateLoyaltyCardStarStatus(database, loyaltyCardId, loyaltyCard.starStatus == 0 ? 1 : 0);
+ new CatimaWidget().updateAll(LoyaltyCardViewActivity.this);
+
// Re-init loyaltyCard with new data from DB
onResume();
invalidateOptionsMenu();
@@ -890,6 +892,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
Toast.makeText(LoyaltyCardViewActivity.this, R.string.archived, Toast.LENGTH_LONG).show();
ShortcutHelper.removeShortcut(LoyaltyCardViewActivity.this, loyaltyCardId);
+ new CatimaWidget().updateAll(LoyaltyCardViewActivity.this);
// Re-init loyaltyCard with new data from DB
onResume();
@@ -915,6 +918,7 @@ public class LoyaltyCardViewActivity extends CatimaAppCompatActivity implements
DBHelper.deleteLoyaltyCard(database, LoyaltyCardViewActivity.this, loyaltyCardId);
ShortcutHelper.removeShortcut(LoyaltyCardViewActivity.this, loyaltyCardId);
+ new CatimaWidget().updateAll(LoyaltyCardViewActivity.this);
finish();
dialog.dismiss();
diff --git a/app/src/main/java/protect/card_locker/MainActivity.java b/app/src/main/java/protect/card_locker/MainActivity.java
index 9adc8ee10..70f49638b 100644
--- a/app/src/main/java/protect/card_locker/MainActivity.java
+++ b/app/src/main/java/protect/card_locker/MainActivity.java
@@ -431,13 +431,7 @@ public class MainActivity extends CatimaAppCompatActivity implements LoyaltyCard
mCurrentActionMode.finish();
}
- updateWidget(mAdapter.mContext);
- }
-
- private void updateWidget(Context context) {
- AppWidgetManager manager = AppWidgetManager.getInstance(context);
- int[] ids = manager.getAppWidgetIds(new ComponentName(context, CatimaWidget.class));
- manager.notifyAppWidgetViewDataChanged(ids, R.id.grid_view);
+ new CatimaWidget().updateAll(mAdapter.mContext);
}
private void processParseResultList(List parseResultList, String group, boolean closeAppOnNoBarcode) {