Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update a widget periodically, say after every 5 seconds

I have a widget with simple button implementation, that whenever we click on a button it flips through a given set of images. Now if I want to flip it every 5 seconds without the button being clicked, how may I proceed?

like image 838
Atihska Avatar asked May 31 '13 23:05

Atihska


2 Answers

Using Handler in Kotlin you can do something like this:

In your activity or fragment

 //update interval for widget
val UPDATE_INTERVAL = 1000L

//Handler to repeat update
private val updateWidgetHandler = Handler()

//runnable to update widget
private var updateWidgetRunnable: Runnable = Runnable {
    run {

        //Update Widget
        sendUpdateBroadcast()

        // Re-run it after the update interval
        updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
    }
}

private fun sendUpdateBroadcast() {
    val updateWidgetIntent = Intent(this, YourWidget::class.java)
    updateWidgetIntent.action = ACTION_APPWIDGET_UPDATE
    val ids = AppWidgetManager.getInstance(application)
        .getAppWidgetIds(ComponentName(application, YourWidget::class.java))
    updateWidgetIntent.putExtra(EXTRA_APPWIDGET_IDS, ids)
    sendBroadcast(updateWidgetIntent)
}



// START updating in foreground
override fun onResume() {
    super.onResume()
    updateWidgetHandler.postDelayed(updateWidgetRunnable, UPDATE_INTERVAL)
}


// REMOVE callback if app in background
override fun onPause() {
    super.onPause()
    // uncomment to pause updating widget when app is in Background
    // updateWidgetHandler.removeCallbacks(updateWidgetRunnable);
}

Than in your Widget Provider call override onReceive method like this:

override fun onReceive(context: Context, intent: Intent) {

    if (ACTION_APPWIDGET_UPDATE == intent.action) {

        // Update your widget here.
        val remoteViews =
            RemoteViews(
                context.packageName,
                R.layout.your_widget
            )

        // Update Text and images
       updateViews(remoteViews)

        //Apply Update
        AppWidgetManager.getInstance(context).updateAppWidget(
            ComponentName(context, ComWidget::class.java)
            , remoteViews)

    }
}

Important thing to note here is if you dont trigger //Apply Update in above method your UI changes will not reflected on widget. Hope it helps.

like image 50
Hitesh Sahu Avatar answered Oct 11 '22 14:10

Hitesh Sahu


First, I would strongly recommend you not to update a widget every 5 seconds. It would kill your battery in no time.

You can use android:updatePeriodMillis attribute in the appwidget-provider.
Take a look at Adding the AppWidgetProviderInfo Metadata on Android developer website.
The thing is, to preserve battery, you can not set a period under 30 min (1800000ms).

After setting up the update period you want, you just have to define the behavior in the onReceive() method of your AppWidgetProvider. To do this, you have to catch ACTION_APPWIDGET_UPDATE event.

@Override
public void onReceive(Context context, Intent intent) {

    final String action = intent.getAction();

    if (ACTION_APPWIDGET_UPDATE.equals(action)) {
        // Update your widget here.
    }
}

If you really want to perform a task every 5 seconds, you can use Timer and TimerTask class :

final Handler handler = new Handler();
Timer timer = new Timer();

TimerTask task = new TimerTask() {

    @Override
    public void run() {
        handler.post(new Runnable() {
            public void run() {  
                // send a broadcast to the widget.
            }
        });
    }
};
timer.scheduleAtFixedRate(task, 0, 5000); // Executes the task every 5 seconds.
like image 38
Cyril Leroux Avatar answered Oct 11 '22 14:10

Cyril Leroux