android - 在午夜更新 Android Widget

标签 android widget

如何每天午夜更新Android小部件??以下解决方案是通过查看堆栈溢出中与此主题相关的其他问题而形成的。

1) 在扩展 AppWidgetProvider 的 Activity 中创建小部件时调用 schedule(context)

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        schedule(context);
    super.onUpdate(context, appWidgetManager, appWidgetIds);

}

2) Schedule 方法应该设置一个计时器和闹钟,以便小部件在每天午夜更新。然而,这不起作用。

protected void schedule(Context context) {
    final Intent i = new Intent(context, CalendarWidget.class);
    service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);

    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(System.currentTimeMillis());
    calendar.set(Calendar.SECOND, 0);
    calendar.set(Calendar.MINUTE, 0);
    calendar.set(Calendar.HOUR, 0);
    calendar.set(Calendar.AM_PM, Calendar.AM);
    calendar.add(Calendar.DAY_OF_MONTH, 1); 

    AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);

//This doesn't work
       // alarmManager.set(AlarmManager.RTC, calendar.getTimeInMillis(), service);
//This doesn't work either.
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, service);
    }

该解决方案不起作用;而且很难测试,因为它每天只能在午夜测试;因此,赏金。我会将它奖励给第一个让它发挥作用的人。

最佳答案

denvercoder9's answer有效(有点),但可以简化。 AppWidgetProvider 已经是一个 BroadcastReceiver,所以我们实际上可以将 Intent 返回给 AppWidgetProvider,并覆盖 onReceive 来处理它。

在扩展AppWidgetProvider 的类中:

private static final String ACTION_SCHEDULED_UPDATE = "your.package.name.SCHEDULED_UPDATE";

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(ACTION_SCHEDULED_UPDATE)) {
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        int[] ids = manager.getAppWidgetIds(new ComponentName(context, AppWidget.class));
        onUpdate(context, manager, ids);
    }

    super.onReceive(context, intent);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    // Do your updates...

    _scheduleNextUpdate(context);
}

private static void _scheduleNextUpdate(Context context) {
    AlarmManager alarmManager =
            (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    // Substitute AppWidget for whatever you named your AppWidgetProvider subclass
    Intent intent = new Intent(context, AppWidget.class);
    intent.setAction(ACTION_SCHEDULED_UPDATE);
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

    // Get a calendar instance for midnight tomorrow.
    Calendar midnight = Calendar.getInstance();
    midnight.set(Calendar.HOUR_OF_DAY, 0);
    midnight.set(Calendar.MINUTE, 0);
    // Schedule one second after midnight, to be sure we are in the right day next time this 
    // method is called.  Otherwise, we risk calling onUpdate multiple times within a few 
    // milliseconds
    midnight.set(Calendar.SECOND, 1);
    midnight.set(Calendar.MILLISECOND, 0);
    midnight.add(Calendar.DAY_OF_YEAR, 1);

    // For API 19 and later, set may fire the intent a little later to save battery,
    // setExact ensures the intent goes off exactly at midnight.
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {
        alarmManager.set(AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis(), pendingIntent);
    } else {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, midnight.getTimeInMillis(), pendingIntent);
    }
}

我们需要自定义 intent 操作,因为 AppWidgetManager.ACTION_APPWIDGET_UPDATE 不会更新所有小部件,即使您在 AppWidgetManager.EXTRA_APPWIDGET_IDS。它只是更新创建的第一个小部件。

Here is a project I'm working on实现与此类似的计划小部件更新。

关于android - 在午夜更新 Android Widget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27422007/

相关文章:

android - Appcenter Android 版本无法安装在设备中

android - 即使包含 Ndef 数据,也不会为 ACTION_NDEF_DISCOVERED 操作发现 NFC 标签

widget - Flutter - 将焦点转移到特定的小部件

java - Android Widget 同一个小部件的多个实例冲突

Python tkinter 禁用按钮,直到所有字段都被填满

安卓导航 Controller : How to open same fragment with same action

java - 从Android应用程序中的其他模块引用公共(public)模块

Docker容器中的Android开发环境I

c++ - Qt Designer(创建者)小部件框,如小部件

QT:两个布局添加相同的小部件