13

我有一个带有简单按钮实现的小部件,每当我们单击一个按钮时,它都会翻转一组给定的图像。现在,如果我想在不单击按钮的情况下每 5 秒翻转一次,我该如何继续?

4

4 回答 4

14

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

您可以在 appwidget-provider 中使用android:updatePeriodMillis属性。
看看在Android 开发者网站上添加 AppWidgetProviderInfo 元数据。
问题是,为了保护电池,您不能将周期设置为 30 分钟(1800000 毫秒)以下。

设置好所需的更新周期后,您只需在 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.
于 2013-06-04T07:10:43.800 回答
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 秒,实在是太快了。它会很快耗尽您的电池电量,具体取决于您在后台可能执行的其他操作。请考虑减少更新频率。

于 2013-06-11T07:14:51.263 回答
1
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
    public void run() {
        runOnUiThread(new Runnable() {
            public void run() {
                imageView.setImageBitmap(bitmap);
            }
        });
    }
}, 5000, 5000);

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

于 2013-05-31T23:52:16.133 回答
0

在 Kotlin 中使用 Handler 你可以做这样的事情:

在您的活动或片段中

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

    }
}

这里要注意的重要一点是,如果您在上述方法中不触发 //Apply Update,您的 UI 更改将不会反映在小部件上。希望能帮助到你。

于 2019-06-24T10:25:57.160 回答