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

发布于 2024-12-25 01:57:07 字数 2122 浏览 4 评论 0原文

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

<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 并没有什么坏处)。

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

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

让我有点惊讶的是,让这个基本功能发挥作用是多么不简单。

My app has a widget that shows today's date and need to be updated on midnight. The widget is defined in the manifest as

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

And the widget info file is

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

This causes the widget to get updated anytime between midnight and 1pm but I want to to get updated closer to midnight so I added to the app an intent receiver

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

and a static method

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);
}

(since alarm manager requests with the same intent overwriting each other there is not harm in calling setMidngintAlarms multiple times).

I tried calling setMidnightAlarms() from few places (from the app's main activity, from the AppWidgetProvider's onUpdate(), etc). Everything works well and the alarm manager intents are received and the widget is updated but only as long as the app runs. If I killed the app, the widgets stops updating on midnight.

Any idea how to cause the widgets to update on midnight? Do I need to add a service? If so how? Any example?

I am a little bit surprised how non trivial it is to get this basic functionality to work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

内心荒芜 2025-01-01 01:57:08

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

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

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

ad this to your manifest widget receiver

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

the change in date will trigger your onReceive() to fire up with the "android.intent.action.DATE_CHANGED" action

羅雙樹 2025-01-01 01:57:07

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

  1. 启动一个服务来监听 Intent.ACTION_TIME_TICK 消息。
    然后,如果时间已到,则向小部件发送广播。 (每分钟一次)。

  2. 在widget中接收广播并判断是否是午夜:

代码:

   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.
        }
    }

I resolve this problem by:

  1. Start a service to listen to Intent.ACTION_TIME_TICK message.
    Then send a broadcast to widget if Time TICKED. (At every minute).

  2. Receive the broadcast in widget and judge weather it is the midnight by:

Code:

   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.
        }
    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文