Reputation: 2914
I want to update widget with data from my Activity
every second. I have Item which has timers and its updating by onBind
method sending payload to it. Every time it will update data and send new (Strings, Dates, Color resources) to payload, I want to update existing Widget with these data. I should update it every second as timer goes on. (payload is sent every second) Is this possible? Because I can add my data to extras and send Intent to AppWidgetProvider
, but I don't know how to update views in Widget with new data sent into onReceive
. Tried this code in onUpdate function. Which should be called every 1000ms which I set in xml for widget provider - android:updatePeriodMillis="1000"
. What is happening is Grey box on my homescreen with Problem loading widget
text. No crashes or errors were present in logs.
RecyclerView item:
private fun updateWidgetTimer(text: String, color: Int){
val int = Intent(a, WidgetProvider::class.java)
int.apply {
putExtra(WidgetProvider.REM_TIME, text)
putExtra(WidgetProvider.REM_TIME_COLOR, color)
action = AppWidgetManager.ACTION_APPWIDGET_UPDATE
}
}
AppWidgetProvider:
private var time: String = ""
private var color: Int = R.color.colorGreen
override fun onUpdate(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetIds: IntArray?
) {
val remoteViews = RemoteViews(context?.packageName, R.layout.widget_custom_layout)
remoteViews.setTextViewText(R.id.timer, time)
context?.let {
remoteViews.setTextColor(R.id.timer, ContextCompat.getColor(context, color))
}
}
override fun onReceive(context: Context?, intent: Intent?) {
super.onReceive(context, intent)
val extras = intent?.extras
extras?.let {
time = extras.getString(REM_TIME)?:""
color = extras.getInt(REM_TIME_COLOR)
}
}
UPDATE: Payload is successfully send to onReceive, but as onUpdate is called, none of my widgets are updated with new data.
Example of my updated onUpdate function:
override fun onUpdate(
context: Context?,
appWidgetManager: AppWidgetManager?,
appWidgetIds: IntArray?
) {
context?.let {
val currWidgetInstanceName = ComponentName(context, WidgetProvider::class.java)
val widgetManager = AppWidgetManager.getInstance(context)
val widgetIds = widgetManager.getAppWidgetIds(currWidgetInstanceName)
widgetIds?.forEach {wId->
val remoteViews = RemoteViews(context.packageName, R.layout.widget_layout)
remoteViews.apply {
//set info title
setTextViewText(R.id.title, title)
//set subtitle
setTextViewText(R.id.subT, subt)
//set info
setTextViewText(R.id.info, info)
//set rem timer
setTextViewText(R.id.outTimer, remTime)
setTextColor(R.id.outTimer, ContextCompat.getColor(context, remTimeColor))
}
widgetManager?.updateAppWidget(currWidgetInstanceName, remoteViews)
}
}
}
Upvotes: 1
Views: 2910
Reputation: 1410
AppWidgetProvider.onUpdate
is called by AppWidgetProvider.onReceive
. Call super.onReceive(context, intent)
at the end of onReceive
method. Data will be updated before onUpdate
will be called.
override fun onReceive(context: Context?, intent: Intent?) {
val extras = intent?.extras
extras?.let {
time = extras.getString(REM_TIME)?:""
color = extras.getInt(REM_TIME_COLOR)
}
super.onReceive(context, intent)
}
Upvotes: 2
Reputation: 551
From https://developer.android.com/reference/android/appwidget/AppWidgetProviderInfo
Note: Updates requested with updatePeriodMillis will not be delivered more than once every 30 minutes.
If you want frequent updates, you should use
Use a service and update the widget, example:
Intent intent = new Intent(context, WidgetUpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarm.cancel(pending);
alarm.setRepeating(AlarmManager.ELAPSED_REALTIME,
SystemClock.elapsedRealtime(), 1000, pendingIntent);
Upvotes: 1