Lots of answers, none of which work.
Should you use a service or an alarm or a timer? All of the answers seem to just be a random guess.
In this example in onDisable
what is the point of creating a new instance of AppWidgetAlarm
and then calling stopAlarm()
-- isn't the alarm still running on the long since lost instance that was created in onEnabled
.
The alarm is started in onEnabled
which is called only when a new widget is created. Therefore after a reboot the alarm will not be started -- a user would have to delete and re-create the widget.
package com.example.thisisnotawidget
import android.app.AlarmManager
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.widget.RemoteViews
import java.util.*
val ACTION_AUTO_UPDATE = "doodah"
// https://stackoverflow.com/questions/5476867/updating-app-widget-using-alarmmanager/14319020#14319020
class AppWidgetAlarm(private val context: Context) {
private val ALARM_ID = 0
private val INTERVAL_MILLIS = 500
fun startAlarm() {
val calendar = Calendar.getInstance()
calendar.add(Calendar.MILLISECOND, INTERVAL_MILLIS)
val alarmIntent = Intent(context, ThisIsTheWidget::class.java)
alarmIntent.action = ACTION_AUTO_UPDATE
val pendingIntent = PendingIntent.getBroadcast(
context,
ALARM_ID,
alarmIntent,
PendingIntent.FLAG_CANCEL_CURRENT
)
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
// RTC does not wake the device up
alarmManager.setRepeating(
AlarmManager.RTC,
calendar.timeInMillis,
INTERVAL_MILLIS.toLong(),
pendingIntent
)
}
fun stopAlarm() {
val alarmIntent = Intent(ACTION_AUTO_UPDATE)
val pendingIntent = PendingIntent.getBroadcast(
context,
ALARM_ID,
alarmIntent,
PendingIntent.FLAG_CANCEL_CURRENT
)
val alarmManager =
context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.cancel(pendingIntent)
}
}
/**
* Implementation of App Widget functionality.
*/
class ThisIsTheWidget : AppWidgetProvider() {
override fun onUpdate(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetIds: IntArray
) {
// Do the updating.
val thisWidget = ComponentName(context, ThisIsTheWidget::class.java)
val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
for (widgetId in allWidgetIds) {
updateAppWidget(context, appWidgetManager, widgetId)
}
}
override fun onEnabled(context: Context) {
// Enter relevant functionality for when the first widget is created
// start alarm
val appWidgetAlarm = AppWidgetAlarm(context.applicationContext)
appWidgetAlarm.startAlarm()
}
override fun onDisabled(context: Context) {
// Enter relevant functionality for when the last widget is disabled
// stop alarm only if all widgets have been disabled
val appWidgetManager = AppWidgetManager.getInstance(context);
val thisWidget = ComponentName(context, ThisIsTheWidget::class.java)
val allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget)
if (allWidgetIds.count() == 0) {
// stop alarm
val appWidgetAlarm = AppWidgetAlarm(context.getApplicationContext());
appWidgetAlarm.stopAlarm();
}
}
}
internal fun updateAppWidget(
context: Context,
appWidgetManager: AppWidgetManager,
appWidgetId: Int
) {
val prefs = context.getSharedPreferences("W", 0)
val n:Int = prefs.getInt("W_" + appWidgetId.toString(), 0) + 1
val e = prefs.edit()
e.putInt("W_" + appWidgetId.toString(), n)
e.apply()
e.commit()
// Construct the RemoteViews object
val views = RemoteViews(context.packageName, R.layout.this_is_the_widget)
views.setTextViewText(R.id.appwidget_text, n.toString())
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views)
}