如何在午夜更新应用小部件?

Posted

技术标签:

【中文标题】如何在午夜更新应用小部件?【英文标题】:How to update an app widget on midnight? 【发布时间】:2012-02-03 19:27:21 【问题描述】:

我的应用有一个显示今天日期的小部件,需要在午夜更新。小部件在清单中定义为

<manifest>
    ...
    <application>
        ...
        <receiver
            android:name=".MyWidgetProviderClass"
            android:label="MyLabel" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_icon_info" />
        </receiver>
    </application>
</manifest>

小部件信息文件是

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/my_layout"
    android:minHeight="40dp"
    android:minWidth="294dp"
    android:updatePeriodMillis="3600000" >
</appwidget-provider>

这会导致小部件在午夜和下午 1 点之间的任何时间更新,但我想在接近午夜时更新,所以我在应用中添加了一个意图接收器

<receiver
     android:name=".MyWidgetUpdaterClass"
     android:enabled="true" >
     <intent-filter>
         <action android:name="MyAction" />
      </intent-filter>
</receiver>

还有一个静态方法

public static void setMidngintAlarms(Context context) 
    Intent intent = new Intent("MyAction");
    PendingIntent pendingIntent = 
        PendingIntent.getBroadcast(context, 0, intent, 0);              
    long interval = 24*60*60*1000;        
    long firstTime = SystemClock.elapsedRealtime() + 
        millisecondsToNextMidnight();
    AlarmManager am = (AlarmManager)context.getSystemService(
        Context.ALARM_SERVICE);
    am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                    firstTime, interval, pendingIntent);

(由于警报管理器请求以相同的意图相互覆盖,因此多次调用 setMidngintAlarms 没有害处。

我尝试从几个地方(从应用程序的主要活动、从 AppWidgetProvider 的 onUpdate() 等)调用 setMidnightAlarms()。一切正常,警报管理器意图被接收,小部件被更新,但只要应用程序运行。如果我终止了该应用程序,小部件将在午夜停止更新。

知道如何让小部件在午夜更新吗?我需要添加服务吗?如果有怎么办?有什么例子吗?

让这个基本功能发挥作用的重要性让我有点惊讶。

【问题讨论】:

小部件仍应更新,因为您正在为其设置警报。因此,应用程序是否正在运行并不重要。如果设备重新启动并且您没有从一开始就注册警报,这确实很重要。 设置重复警报并且从未明确取消时。 android系统在什么情况下取消它,如果有的话?我找不到相关信息。例如,它是与发送它的活动或服务相关联,还是永远独立存在? 【参考方案1】:

我通过以下方式解决了这个问题:

    启动一个服务来监听 Intent.ACTION_TIME_TICK 消息。 如果 Time TICKED,则向小部件发送广播。 (每分钟)。

    在小部件中接收广播并通过以下方式判断天气是午夜:

代码:

   if (MyWidget.BROADCAST_TIME_TICK.equals(action)) 
        //If it's midnight, then update.
        int hour = Calendar.getInstance().get(Calendar.HOUR);
        int minute = Calendar.getInstance().get(Calendar.MINUTE);
        Utils.log(TAG, "time is : " + hour+":" + minute);
        if (!(hour == 0 && minute == 0))   //Only update at midnight's time tick.
            return;
         else 
            //Do the midnight stuff.
        
    

【讨论】:

【参考方案2】:

将此广告添加到您的清单小部件接收器

 <intent-filter>
            <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
            <action android:name="android.intent.action.DATE_CHANGED" />...

日期更改将触发您的 onReceive() 以“android.intent.action.DATE_CHANGED”操作触发

【讨论】:

以上是关于如何在午夜更新应用小部件?的主要内容,如果未能解决你的问题,请参考以下文章

如何在通知中心频繁更新今日小部件?

如何在另一个小部件更新qt中的相同内容后更新小部件内容

如何创建具有配置活动的应用小部件,并首次对其进行更新?

如何在BOOT_COMPLETED更新第三方小部件?

如何在不重建所有 RemoteView 的情况下部分更新应用小部件中的视图

如何每分钟更新一个 Android 应用小部件