将 TimerTask 和 Timer 与 Widget AppWidgetProvider 一起使用
Using TimerTask and Timer with Widget AppWidgetProvider
我正在使用 Android 创建时钟小部件。我测试了时钟,逻辑似乎没问题,但我需要让它每分钟更新一次。
我在 XML 中将 updatePeriodMillis 设置为 60000,但 Android 将其限制为 30 分钟,因此它每半小时更新一次。
我做了一些研究,一个 Service 或 AlarmManager 可能已经工作,除了我调用的方法需要一个 AppWidgetManager 和 AppWidgetId,它们是通过 onUpdate() 方法传递给它的。
我已经尝试了两种(类似的)方法来使分钟更新正常工作:
static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
final Handler mHandler = new Handler();
TimerTask minuteTask = new TimerTask() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
//Do Stuff
});
}
};
timer = new Timer();
// schedule the task to run starting now and then every minute
timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60);
}
和:
static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
TimerTask minuteTask = new TimerTask() {
@Override
public void run() {
//Do stuff
}
};
timer = new Timer();
// schedule the task to run starting now and then every minute
timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60);
}
非常感谢任何帮助。
谢谢。
编辑:在我调试和制作这个 post 的过程中,我最终让应用程序安装了半个小时。第一次调用 onUpdate() 时,定时器似乎在半小时后开始,但在最初的 30 分钟内它仍然不起作用。
I did some research and a Service or AlarmManager might have worked except the method that I'm calling requires an AppWidgetManager and AppWidgetId that are passed to it via the onUpdate() method.
将应用小部件 ID 保存在文件中。或者,使用采用 ComponentName
而不是应用程序小部件 ID 作为第一个参数的 updateAppWidget()
的风格,将您的应用程序小部件的所有实例更新为相同的 RemoteViews
。
您可以从您的 IntentService
using getInstance()
中获取您的 AppWidgetManager
。
I've tried two (similar) methods to get the minute update working
这是没有意义的,因为它只会在您的进程为 运行。
时起作用
好的,终于搞定了(有考试,因此帖子之间的间隔很长)。
我最终使用了服务、未决意图和警报管理器来满足我的需求。
ClockWidget.class:
private static final String TAG = ClockWidget.class.getSimpleName();
@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName componentName = new ComponentName(context, ClockWidget.class);
onUpdate(context, appWidgetManager, appWidgetManager.getAppWidgetIds(componentName));
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(TAG, "onUpdate");
ComponentName componentName = new ComponentName(context, ClockWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(componentName);
Intent intent = new Intent(context.getApplicationContext(), UpdateService.class);
intent.setAction(UpdateService.ACTION_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
m.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent);
}
UpdateService.class:
private static final String TAG = UpdateService.class.getSimpleName();
public static final String ACTION_UPDATE = "uk.co.thebillington.laxe.ACTION_UPDATE";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
return super.onStartCommand(null, flags, startId);
}
String action = intent.getAction();
if (action == null) {
return super.onStartCommand(intent, flags, startId);
}
Log.d(TAG, String.format("onStartCommand: %s", action));
if (action.equals(ACTION_UPDATE)) {
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
for (int widgetId : allWidgetIds) {
updateWidget(widgetId);
}
}
return super.onStartCommand(intent, flags, startId);
}
private void updateWidget(int widgetId) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.clock);
//Do stuff
appWidgetManager.updateAppWidget(widgetId, views);
}
我正在使用 Android 创建时钟小部件。我测试了时钟,逻辑似乎没问题,但我需要让它每分钟更新一次。
我在 XML 中将 updatePeriodMillis 设置为 60000,但 Android 将其限制为 30 分钟,因此它每半小时更新一次。
我做了一些研究,一个 Service 或 AlarmManager 可能已经工作,除了我调用的方法需要一个 AppWidgetManager 和 AppWidgetId,它们是通过 onUpdate() 方法传递给它的。
我已经尝试了两种(类似的)方法来使分钟更新正常工作:
static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
final Handler mHandler = new Handler();
TimerTask minuteTask = new TimerTask() {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
//Do Stuff
});
}
};
timer = new Timer();
// schedule the task to run starting now and then every minute
timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60);
}
和:
static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager,
final int appWidgetId) {
TimerTask minuteTask = new TimerTask() {
@Override
public void run() {
//Do stuff
}
};
timer = new Timer();
// schedule the task to run starting now and then every minute
timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60);
}
非常感谢任何帮助。
谢谢。
编辑:在我调试和制作这个 post 的过程中,我最终让应用程序安装了半个小时。第一次调用 onUpdate() 时,定时器似乎在半小时后开始,但在最初的 30 分钟内它仍然不起作用。
I did some research and a Service or AlarmManager might have worked except the method that I'm calling requires an AppWidgetManager and AppWidgetId that are passed to it via the onUpdate() method.
将应用小部件 ID 保存在文件中。或者,使用采用 ComponentName
而不是应用程序小部件 ID 作为第一个参数的 updateAppWidget()
的风格,将您的应用程序小部件的所有实例更新为相同的 RemoteViews
。
您可以从您的 IntentService
using getInstance()
中获取您的 AppWidgetManager
。
I've tried two (similar) methods to get the minute update working
这是没有意义的,因为它只会在您的进程为 运行。
时起作用好的,终于搞定了(有考试,因此帖子之间的间隔很长)。
我最终使用了服务、未决意图和警报管理器来满足我的需求。
ClockWidget.class:
private static final String TAG = ClockWidget.class.getSimpleName();
@Override
public void onReceive(@NonNull Context context, @NonNull Intent intent) {
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName componentName = new ComponentName(context, ClockWidget.class);
onUpdate(context, appWidgetManager, appWidgetManager.getAppWidgetIds(componentName));
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.d(TAG, "onUpdate");
ComponentName componentName = new ComponentName(context, ClockWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(componentName);
Intent intent = new Intent(context.getApplicationContext(), UpdateService.class);
intent.setAction(UpdateService.ACTION_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
m.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent);
}
UpdateService.class:
private static final String TAG = UpdateService.class.getSimpleName();
public static final String ACTION_UPDATE = "uk.co.thebillington.laxe.ACTION_UPDATE";
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent == null) {
return super.onStartCommand(null, flags, startId);
}
String action = intent.getAction();
if (action == null) {
return super.onStartCommand(intent, flags, startId);
}
Log.d(TAG, String.format("onStartCommand: %s", action));
if (action.equals(ACTION_UPDATE)) {
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
for (int widgetId : allWidgetIds) {
updateWidget(widgetId);
}
}
return super.onStartCommand(intent, flags, startId);
}
private void updateWidget(int widgetId) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.clock);
//Do stuff
appWidgetManager.updateAppWidget(widgetId, views);
}