【问题标题】:not onUpdate in AppWidgetProvider不是 AppWidgetProvider 中的 onUpdate
【发布时间】:2014-02-20 14:00:55
【问题描述】:

我的 Android 小部件没有更新日期。

这是一个只有日期的小部件,没有更多。

package com.android.widget;

import java.util.Timer;
import java.util.TimerTask;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.widget.RemoteViews;

public class MyCalendarWidget extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new MyTime(context, appWidgetManager), 1,
                1000);
    }

    private class MyTime extends TimerTask {
        RemoteViews remoteViews;
        AppWidgetManager appWidgetManager;
        ComponentName thisWidget;
        Fecha fec = new Fecha();

        public MyTime(Context context, AppWidgetManager appWidgetManager) {
            this.appWidgetManager = appWidgetManager;
            remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
            thisWidget = new ComponentName(context, MyCalendarWidget.class);
        }

        @Override
        public void run() {
            remoteViews.setTextViewText(R.id.widget_textview, fec.DiaActual(false)+"\r\n"
                                                             +fec.DiaActual(true) +" de "
                                                             +fec.MesActual(false)+" de "
                                                             +fec.AñoActualNumerico());
            appWidgetManager.updateAppWidget(thisWidget, remoteViews);
        }
    }
}

【问题讨论】:

    标签: java android-widget


    【解决方案1】:

    请先阅读文档AppWidget GuideAppWidgetProvider。这说明:

    • 您的 onUpdate() 方法需要通过 updateAppWidget() 向小部件发送 RemoteViews。
    • 每秒唤醒一次会耗尽电池电量。您当然不想在手机处于睡眠状态时更新小部件。
    • 每次调用 remoteViews.setTextViewText() 都会将更多数据附加到 RemoteViews 对象。这将在内存中积累过多的数据并使小部件变慢。相反,每次都获取一个新的 RemoteViews 实例。

    我对您的更新没有发生的假设是,当提供程序完成对 Intent 的响应时,操作系统会停止您的小部件提供程序的组件。您可以通过 Log.d() 检验该假设。

    您可以注册ACTION_TIME_TICK 广播,该广播会告诉您时间何时更改,每分钟一次。测试手机休眠时它不会运行(例如,记录通话次数)并随时在此处报告。

    [已添加] 在实践中显示日期(每天更新一次)比日期+时间(每分钟更新一次)要容易得多;您的问题代码试图更新它每秒一次),并且在不消耗太多电池电量的情况下执行此操作。

    • 设置updatePeriodMillis="0"
    • <action android:name="android.intent.action.DATE_CHANGED"/> 添加到AndroidManifest.xml 中小部件提供程序的<intent-filter>
    • 在 AppWidgetProvider 中,覆盖

      public void onReceive(Context context, Intent intent) {
          super.onReceive(context, intent);
          if (Intent.ACTION_DATE_CHANGED.equals(intent.getAction())) { updateAllMyWidgets(context); }
      }
      
    • 使用DateUtils.formatDateTime() 格式化日期。

    是的,如果时钟向后调整,就会出现错误code.google.com/p/android/issues/detail?id=2880

    【讨论】:

    • 谢谢先生非常友好。请想知道是否可以将调试用于此项目。当我尝试时它没有工作。谢谢,但尽管它对我有很大帮助,因为我是 Android 新手,但他的解释非常广泛。如果您可以向我发送有关 ACTION_TIME_TICK 此类示例的链接。我将永远感激不尽。
    • 调试器应该在这个项目上工作。如果您在设备上运行,请记住使用设置来启用开发功能,包括调试。您可能希望从一个仅使用活动的更简单的项目开始。该项目需要学习 Widgets、Intents、Receivers、Services 等。
    • 网络搜索会找到使用 ACTION_TIME_TICK 的示例 [尽管其中一些设计不佳] 例如 kfb-android.blogspot.com/2009/04/… : registerReceiver(new DemoReceiver(), new IntentFilter(Intent.ACTION_TIME_TICK)); 它需要在服务中才能继续在后台运行。该页面还讨论了设备重新启动时的重新注册以及停止服务的需要。我认为清单在意图过滤器中不需要<action android:name="android.intent.action.TIME_TICK"/>
    • 更好的主意:只有在屏幕打开并且时钟小部件实例存在时才收听 ACTION_TIME_TICK 会节省电池电量、CPU 和内存。为此,请在清单中为 ACTION_SCREEN_ON 和 ACTION_SCREEN_OFF 定义一个广播接收器。在 ACTION_SCREEN_ON 上,如果 widgetIds 数组不为空,则启动服务。该服务将注册 ACTION_TIME_TICK。当它收到一个滴答声时,服务将更新小部件,或者,如果 widgetIds 数组为空,则停止自身。同样在 ACTION_SCREEN_OFF 上,停止服务。
    • 谢谢,我肯定是在和来自另一个星系的人交谈 :) 我真的很感激,但如果你解释得好,我不会跟着你,对不起。我想过这个。因为 onUpdate 每 30 分钟更新一次。为什么不只看一天中的时间,如果是 00:00:01,我会更新 textview 并准备好。我想这不会损害电池消耗或使用 cpu 作为最短更新时间。你不觉得吗?。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-03-29
    • 2018-10-09
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多