2

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)
}
Richard Barraclough
  • 2,625
  • 3
  • 36
  • 54

0 Answers0