2015-05-17 26 views
1

我使用Android創建時鐘窗口小部件。我測試過時鐘和邏輯似乎很好,但我需要每分鐘更新一次。通過Widget AppWidgetProvider使用TimerTask和Timer

我在我的XML中將updatePeriodMillis設置爲60000,但Android限制爲30分鐘,因此它每半小時更新一次。

我做了一些研究,服務或AlarmManager可能已經工作,但我調用的方法需要通過onUpdate()方法傳遞給它的AppWidgetManager和AppWidgetId。

我已經試過兩(類似)的方法來獲取分鐘更新工作:

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

} 

任何幫助是非常讚賞。

謝謝。

編輯:在我花時間調試和發佈這篇文章的時候,我結束了應用程序的安裝半個小時。當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

我做了一些研究,除了我調用的方法需要通過onUpdate()方法傳遞給它的AppWidgetManager和AppWidgetId之外,Service或AlarmManager可能已經工作。

將應用程序控件ID保存在文件中。或者,使用updateAppWidget()的風格,將ComponentName而不是應用小部件ID作爲第一個參數,以將應用小部件的所有實例更新爲相同的RemoteViews

您可以從您的IntentServiceusing getInstance()中獲得您的AppWidgetManager

我已經試過兩(類似)的方法來獲取分鐘更新工作

這是沒有意義的,因爲它只會工作,而你的進程正在運行。

+0

感謝您的提示。我現在已經創建了一個方法,將所有的應用部件ID添加到共享首選項,並且在我的onEnabled方法中設置了重複警報。 然後我有一個Intent服務從共享首選項中獲取ID,然後AppWidgetManager與getInstance()然後調用updateAppWidget(this,appWidgetManager,id),但應用程序仍然沒有更新。 我想這可能是因爲我的服務沒有正確啓動。有沒有辦法測試我的服務是否正在運行? – thebillington

相關問題