我有一个带有简单按钮实现的小部件,每当我们单击一个按钮时,它都会翻转一组给定的图像。现在,如果我想在不单击按钮的情况下每 5 秒翻转一次,我该如何继续?
4 回答
首先,我强烈建议您不要每 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 秒执行一次任务,你可以使用Timer和TimerTask类:
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.
使用 AlarmManager 触发将向接收器发送更新意图的警报。
这是一个很好的链接,它给出了一个例子。
http://www.parallelrealities.co.uk/2011/09/using-alarmmanager-for-updating-android.html
- 小部件激活后,在小部件服务中,设置 5 秒后的下一个警报。
- 警报应该发出一个 PendingIntent,它会在 5 秒后触发您的服务。
- 在您的服务的 onStartCommand 中,触发小部件更新服务。
- 并在 5 秒后再次设置下一个警报。
注意:但是,5 秒,实在是太快了。它会很快耗尽您的电池电量,具体取决于您在后台可能执行的其他操作。请考虑减少更新频率。
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
imageView.setImageBitmap(bitmap);
}
});
}
}, 5000, 5000);
第一次更改将在 5 秒后发生。
在 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 更改将不会反映在小部件上。希望能帮助到你。