Вопрос

I am currently developing a widget which counts down to when school starts. I have tested it and it all works apart from one thing; the text in the widget does not change

Here is my code (BGSWidgetProvider.java):

package com.bordengrammar.bordengrammarapp;

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

import com.bordengrammar.bordengrammarapp.utils.ut;

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

public class BGSWidgetProvider 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;       

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

        @Override
        public void run() {
            remoteViews.setTextViewText(R.id.hours, hour());
            remoteViews.setTextViewText(R.id.minutes, minutes());
            ut.logIt(minutes());
            ut.logIt(hour());
            appWidgetManager.updateAppWidget(thisWidget, remoteViews);
        }




        public String hour() {
            /*
            * Work out whether tommorow is right day, (Right meaning mon-fri)
            * If it is work out the amount of hours and minutes until 8.30am tommorow
            * Else work out how many days, hours and minutes until monday 8.30am
            *
             */
            String result;
            Calendar now = Calendar.getInstance();
            int currentDay = now.get(Calendar.DAY_OF_WEEK);

            Calendar school = Calendar.getInstance();
            school.add(Calendar.DAY_OF_YEAR, 1);
            if (currentDay == Calendar.SATURDAY)
            {
                school.add(Calendar.DAY_OF_YEAR, 1);
            }
            else if (currentDay == Calendar.FRIDAY)
            {
                school.add(Calendar.DAY_OF_YEAR, 2);
            }

            school.set(Calendar.HOUR_OF_DAY, 8);
            school.set(Calendar.MINUTE, 30);
            long millisLeft = school.getTimeInMillis() - now.getTimeInMillis();
            long hoursLeft = millisLeft / (60 * 60 * 1000); 
            String hours = Long.toString(hoursLeft);        
            return hours;


        }
        public String minutes() {
            /*
            * Work out whether tommorow is right day, (Right meaning mon-fri)
            * If it is work out the amount of hours and minutes until 8.30am tommorow
            * Else work out how many days, hours and minutes until monday 8.30am
            *
             */         
            Calendar now = Calendar.getInstance();
            int currentDay = now.get(Calendar.DAY_OF_WEEK);

            Calendar school = Calendar.getInstance();
            school.add(Calendar.DAY_OF_YEAR, 1);
            if (currentDay == Calendar.SATURDAY)
            {
                school.add(Calendar.DAY_OF_YEAR, 1);
            }
            else if (currentDay == Calendar.FRIDAY)
            {
                school.add(Calendar.DAY_OF_YEAR, 2);
            }

            school.set(Calendar.HOUR_OF_DAY, 8);
            school.set(Calendar.MINUTE, 30);

            long millisLeft = school.getTimeInMillis() - now.getTimeInMillis();         
            long minutesLeft =  (millisLeft % (60 * 60 * 1000)) / (60 * 1000);          
            String minutes = Long.toString(minutesLeft);


            return minutes;


        }



    }

My layout (widget_layout.xml):

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:id="@+id/layout"
              android:orientation="horizontal"
              android:layout_width="250dp"
              android:layout_height="72dp"
              android:background="@color/bordenpurple">


    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="10"
        android:textSize="60dp"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:textColor="@color/bordenyellow"
        android:typeface="sans"
        android:id="@+id/hours"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Hours"
        android:id="@+id/textView"
        android:textColor="@color/bordenyellow"
        android:padding="5dp"
        android:layout_marginLeft="-10dp"
        />

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="10"
        android:textSize="60dp"
        android:paddingTop="5dp"
        android:paddingLeft="5dp"
        android:paddingRight="5dp"
        android:textColor="@color/bordenyellow"
        android:typeface="sans"
        android:id="@+id/minutes"/>

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:textAppearance="?android:attr/textAppearanceSmall"
        android:text="Minutes"
        android:id="@+id/textView3"
        android:textColor="@color/bordenyellow"
        android:padding="5dp"
        android:layout_marginLeft="-7dp"
        />

</LinearLayout>

As you can see, i put a log statment in the run method to test my code out and it works, here is my logcat:

05-03 18:24:30.874    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:31.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:31.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:32.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:32.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:33.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:33.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:34.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:34.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:35.874    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:35.874    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38
05-03 18:24:36.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 6
05-03 18:24:36.878    8011-8029/com.bordengrammar.bordengrammarapp E/Logger﹕ 38

I have no idea how to fix this and any help would be appreciated!

Это было полезно?

Решение

Never use a Timer in a widget. An AppWidgetProvider is a BroadcastReceiver, it's meant to remain active only for a short amount of time to handle the Broadcast Intent it received, then it can be destroyed at any moment after the broadcast has been handled and the onUpdate() method returns (but the widget will remain visible of course).

Android will normally call your widget update code every 30 minutes so you should not worry about refreshing it manually and just move your display code (currently in run()) to onUpdate().

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top