如何定期更新窗口小部件,比如每5秒钟后更新一次

时间:2013-05-31 23:37:21

标签: android android-widget

我有一个带有简单按钮实现的小部件,每当我们点击一​​个按钮时,它就会翻转一组给定的图像。现在,如果我想在没有点击按钮的情况下每隔5秒翻一次,我该怎么办?

4 个答案:

答案 0 :(得分:8)

首先,我强烈建议您不要每5秒更新一次小部件。它会立刻杀死你的电池。

您可以在appwidget-provider中使用android:updatePeriodMillis属性 在Android开发者网站上查看Adding the AppWidgetProviderInfo Metadata 问题是,为了节省电池,你不能设置30分钟以下的时间(1800000ms)。

设置所需的更新周期后,您只需在AppWidgetProvider的onReceive()方法中定义行为即可。为此,您必须捕获ACTION_APPWIDGET_UPDATE事件。

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

    final String action = intent.getAction();

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

如果您真的想每5秒执行一次任务,可以使用TimerTimerTask类:

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.

答案 1 :(得分:4)

使用AlarmManager来关闭将向您的接收者发送更新意图的警报。

这是一个很好的链接,给出了一个例子。

http://www.parallelrealities.co.uk/2011/09/using-alarmmanager-for-updating-android.html

  1. 当窗口小部件被激活时,在窗口小部件服务中,在5秒后设置下一个警报。
  2. 警报应发出一个PendingIntent,这将在5秒后触发您的服务。
  3. 在服务的onStartCommand中,触发小部件更新服务。
  4. 再次在5秒后设置下一个警报。
  5. 注意:但是,5秒,真的太快了。它会很快耗尽你的电池,这取决于你在后台可能做的其他事情。请考虑减少更新频率。

答案 2 :(得分:1)

Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    public void run() {
        runOnUiThread(new Runnable() {
            public void run() {
                imageView.setImageBitmap(bitmap);
            }
        });
    }
}, 5000, 5000);

第一次更改将在5秒后发生。

答案 3 :(得分:0)

在Kotlin中使用处理程序,您可以执行以下操作:

在您的活动或片段中

 //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);
}

比您的Widget Provider中的调用覆盖onReceive方法像这样:

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)

    }
}

这里要注意的重要事情是,如果您不触发//应用上述方法中的更新,则您的UI更改将不会反映在小部件上。希望对您有所帮助。