安卓小部件更新

6
根据 this tutorial,我创建了一个小部件,应该显示时间。Java方式可行,但服务方式不行。

HelloWidget.java:

public class HelloWidget extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

        Intent intent = new Intent(context, UpdateService.class);
        context.startService(intent);
    }
}

UpdateService.java:

public final class UpdateService extends Service {
    @Override
    public void onStart(Intent intent, int startId) {
        RemoteViews updateViews = new RemoteViews(this.getPackageName(), R.layout.main);

        Date date = new Date();
        java.text.DateFormat format = SimpleDateFormat.getTimeInstance(
                SimpleDateFormat.MEDIUM, Locale.getDefault());
                updateViews.setTextViewText(R.id.widget_textview, "Current Time " + format.format(date));

        ComponentName thisWidget = new ComponentName(this, HelloWidget.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(this);
        manager.updateAppWidget(thisWidget, updateViews);
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }
}

问题:

小部件显示当前时间,但不更新(使用java的方式可以更新)。

我的主要目标是在每天18:56更新小部件。 我不知道这是否是正确的方法,但我尝试修改onUpdate方法如下,但它与ALARM_SERVICE存在问题:无法将ALARM_SERVICE解析为变量。

hello_widget_provider.xml文件包含以下行:android:updatePeriodMillis="1000"

public class HelloWidget extends AppWidgetProvider {

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

        AlarmManager alarmManager;
        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
          intent, PendingIntent.FLAG_UPDATE_CURRENT);
        alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.HOUR_OF_DAY, 18);
        cal.set(Calendar.MINUTE, 56);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 86400, pendingIntent);
   }
}

任何帮助都受到赞赏。
2个回答

17

回顾我提问的那个时候,我意识到自己在过去的1.5年中学到了很多东西。

由于我最近两周一直在使用一个小部件,并且刚刚发现了这个未被回答的问题,因此我决定解决它。希望这能帮助其他人。

AppWidgetProvider 应该像这样:

public class MyWidget extends AppWidgetProvider {

    public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
    public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
    private PendingIntent service = null;  

       @Override
       public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {


           final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

           final Calendar TIME = Calendar.getInstance();
           TIME.set(Calendar.MINUTE, 0);
           TIME.set(Calendar.SECOND, 0);
           TIME.set(Calendar.MILLISECOND, 0);

           final Intent i = new Intent(context, MyService.class);

           if (service == null)
           {
               service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
           }

           m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 1, service);

    }

      @Override
       public void onDeleted(Context context, int[] appWidgetIds) {
               super.onDeleted(context, appWidgetIds);
       }

       @Override
       public void onDisabled(Context context) {
               super.onDisabled(context);

               final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);  
               if (service != null)
               {
                   m.cancel(service);
               }
       }

       @Override
       public void onEnabled(Context context) {
               super.onEnabled(context);
       }

       @Override
       public void onReceive(Context context, Intent intent) {

         super.onReceive(context, intent);

       }

}

这项服务:

public class MyService extends Service
{
    @Override
    public void onCreate()
    {
        super.onCreate();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId)
    {
        buildUpdate();

        return super.onStartCommand(intent, flags, startId);
    }

    private void buildUpdate()
    {
        String lastUpdated = DateFormat.format("hh:mm:ss", new Date()).toString();

        RemoteViews view = new RemoteViews(getPackageName(), R.layout.widget_layout);
        view.setTextViewText(R.id.btn_widget, lastUpdated);

        ComponentName thisWidget = new ComponentName(this, MyWidget.class);
        AppWidgetManager manager = AppWidgetManager.getInstance(this);
        manager.updateAppWidget(thisWidget, view);
    }

    @Override
    public IBinder onBind(Intent intent)
    {
        return null;
    }
}

此外,在清单文件中注册提供程序和服务:

<receiver android:name="MyWidget" android:label="Tutorial_Widget 1x1">
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
                <action android:name="com.something.MyWidget.ACTION_WIDGET_RECEIVER"/>
            </intent-filter>    
            <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info"/>
        </receiver>

         <service android:enabled="true" android:name=".MyService" />

抱歉,您在哪里设置确定重复间隔的时间? - Rikki Tikki Tavi
1
m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 1, service); - erdomester
是的,谢谢。我会用这个的。我还想知道如何设置特定的时间进行更新。 - Rikki Tikki Tavi
你可以在AlarmManager中设置时间,然后每24小时调用一次服务。 - erdomester
这里有一个错误:onDisable从不同的实例调用,因此'service'将始终为null。使用此代码将永远无法取消闹钟。 - Bob bobbington
有没有办法让这个时钟每秒更新一次?从目前我所找到的资料来看,最小的更新时间似乎是每30分钟一次(这是安卓为了节省电池电量而采取的措施...)。 - user5864910

3

ALARM_SERVICE是Context类的静态字段。因此,请输入Context.ALARM_SERVICE或使用静态导入。

请记住,当您设置updatePeriodMillis属性值时,并不能保证您的onUpdate方法会按照该时间间隔准确调用。


到目前为止,我从未遇到过这个问题。当我按照你说的方式输入时,getSystemService 函数出现了问题:"HelloWidget 类型未定义 getSystemService(String) 函数"。 - erdomester
2
getSystemService(String) 是 Context 类的一个方法。但是小部件提供程序不是上下文。它们是广播接收器,使用其方法中的参数检索上下文。因此,在 HelloWidget 代码中,您应该键入 context.getSystemService(Context.ALARM_SERVICE)。 - Roman Mazur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接