2015-05-17 1 views
1

Я создаю виджет часов с Android. Я проверил часы, и логика кажется прекрасной, но мне нужно обновить ее каждую минуту.Использование TimerTask и Timer с Widget AppWidgetProvider

Я установил updatePeriodMillis на 60000 в свой XML, но Android ограничивает это до 30 минут, поэтому он обновляется каждые полчаса.

Я провел некоторое исследование, и служба или AlarmManager, возможно, сработали, за исключением метода, который я вызываю, требуется AppWidgetManager и AppWidgetId, которые передаются ему с помощью метода onUpdate().

Я попробовал два (подобные) методы, чтобы получить рабочую минуту обновления:

static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, 
          final int appWidgetId) { 

    final Handler mHandler = new Handler(); 
    TimerTask minuteTask = new TimerTask() { 

     @Override 
     public void run() { 
      mHandler.post(new Runnable() { 
       @Override 
       public void run() { 

        //Do Stuff 
      }); 
     } 
    }; 

    timer = new Timer(); 

    // schedule the task to run starting now and then every minute 
    timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60); 

} 

и:

static void updateAppWidget(final Context context, final AppWidgetManager appWidgetManager, 
          final int appWidgetId) { 

    TimerTask minuteTask = new TimerTask() { 

     @Override 
     public void run() { 

      //Do stuff 
     } 
    }; 

    timer = new Timer(); 

    // schedule the task to run starting now and then every minute 
    timer.scheduleAtFixedRate(minuteTask, 0l, 1000 * 60); 

} 

Любая помощь очень высоко ценится.

Спасибо.

EDIT: В то время, когда мне приходилось отлаживать и делать это сообщение, я в конечном итоге оставил приложение установленным на полчаса. Казалось бы, таймер запустился через полчаса, когда сначала был вызван onUpdate(), но он по-прежнему не работает в течение первых 30 минут.

ответ

1

Хорошо, наконец, получил эту работу (имел экзамены, следовательно, длительный промежуток между сообщениями).

В результате я воспользовался службой, ожидающей намерения и диспетчера аварийных сигналов, чтобы удовлетворить мои потребности.

ClockWidget.class:

private static final String TAG = ClockWidget.class.getSimpleName(); 

@Override 
public void onReceive(@NonNull Context context, @NonNull Intent intent) { 
    super.onReceive(context, intent); 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context); 
    ComponentName componentName = new ComponentName(context, ClockWidget.class); 
    onUpdate(context, appWidgetManager, appWidgetManager.getAppWidgetIds(componentName)); 
} 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
    Log.d(TAG, "onUpdate"); 

    ComponentName componentName = new ComponentName(context, ClockWidget.class); 
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(componentName); 

    Intent intent = new Intent(context.getApplicationContext(), UpdateService.class); 
    intent.setAction(UpdateService.ACTION_UPDATE); 
    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds); 
    context.startService(intent); 

    PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

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

    m.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 1000 * 60, pendingIntent); 
} 

UpdateService.class:

private static final String TAG = UpdateService.class.getSimpleName(); 

public static final String ACTION_UPDATE = "uk.co.thebillington.laxe.ACTION_UPDATE"; 

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

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 
    if (intent == null) { 
     return super.onStartCommand(null, flags, startId); 
    } 

    String action = intent.getAction(); 
    if (action == null) { 
     return super.onStartCommand(intent, flags, startId); 
    } 

    Log.d(TAG, String.format("onStartCommand: %s", action)); 

    if (action.equals(ACTION_UPDATE)) { 
     int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS); 
     for (int widgetId : allWidgetIds) { 
      updateWidget(widgetId); 
     } 
    } 

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

private void updateWidget(int widgetId) { 
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext()); 

    RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.clock); 

    //Do stuff 

    appWidgetManager.updateAppWidget(widgetId, views); 
} 
0

Я сделал некоторые исследования и служба или AlarmManager могли бы работать, кроме метода, который я звоню требует AppWidgetManager и AppWidgetId, которые передаются ему через() метод OnUpdate.

Сохраните идентификаторы виджета приложения в файле. Или используйте аромат updateAppWidget(), который принимает ComponentName, а не идентификатор виджета приложения, в качестве первого параметра, чтобы обновить все экземпляры виджета приложения, чтобы они были одинаковыми RemoteViews.

Вы можете получить AppWidgetManager от IntentServiceusing getInstance().

Я попробовал два (подобные) методы, чтобы получить обновление минут рабочего

Это бессмысленно, так как он будет работать только в то время как ваш процесс запущен.

+0

спасибо за подсказку. Теперь я создал метод, который добавляет все идентификаторы виджетов приложений в общие настройки, и я установил повторяющийся сигнал тревоги в свой метод onEnabled. Затем у меня есть служба Intent, которая извлекает идентификаторы из общих настроек, а AppWidgetManager с getInstance() выполняет вызов updateAppWidget (это appWidgetManager, id), но приложение по-прежнему не обновляется. Я думаю, что это может быть потому, что мое обслуживание не начинается правильно. Есть ли способ проверить, работает ли моя служба? – thebillington