Jump to content

Archived

This topic is now archived and is closed to further replies.

chkeff

Problème: mettre à jour mes widgets

Recommended Posts

Bonjour à tous !

Voilà comme le titre l'indique j'ai un problème avec le widget que je veux intégrer à mon application !

Son but et d'afficher des infos, il est susceptible d'être placé plusieurs fois par l'utilisateur et là où ça coince c'est pour la mise à jour !

En regardant plusieurs codes sur internet j'arive à ce résultat:

Mon provider:

public class WidgetProvider extends AppWidgetProvider {

// **************************************************************

// **************************************************************

// **************************************************************

@Override

public void onReceive(Context c, Intent intent) {

if (intent.getAction() == null)

c.startService(new Intent(c, WidgetService.class));

else

super.onReceive(c, intent);

}

// **************************************************************

@Override

public void onUpdate(Context c, AppWidgetManager appWidgetManager, int[] appWidgetIds) {

c.startService(new Intent(c, WidgetService.class));

}

// **************************************************************

@Override

public void onDeleted(Context c, int[] appWidgetIds) {

super.onDeleted(c, appWidgetIds);

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences©;

Editor editor = prefs.edit();

for(int id: appWidgetIds) {

editor.remove("widgetId=" + id);

}

editor.commit();

}

}

je fait la mise à jour via un service (apparemment conseillé quand la mise à jour peut prendre du temps).

public class WidgetService extends IntentService {

// **************************************************************

// **************************************************************

private SharedPreferences prefs;

private ComponentName me;

private AppWidgetManager mgr;

private int[] allWidgetIds;

// **************************************************************

public WidgetService() {

super("MSSWidgetUpdateService");

}

@Override

public void onCreate() {

super.onCreate();

this.prefs = PreferenceManager.getDefaultSharedPreferences(this);

}

// **************************************************************

@Override

protected void onHandleIntent(Intent intent) {

this.me = new ComponentName(this, WidgetProvider.class);

this.mgr = AppWidgetManager.getInstance(this);

this.allWidgetIds = mgr.getAppWidgetIds(me);

for(int widgetId: allWidgetIds) {

long id = this.prefs.getLong("widgetId=" + widgetId, -1);

if(id == -1)

continue;

final Item item = manager.loaditem(id);

update(item);

}

manager.close();

}

// **************************************************************

// **************************************************************

private void update(Item item) {

RemoteViews v = new RemoteViews(this.getPackageName(), R.layout.widget);

/**

....

*/

mgr.updateAppWidget(me, v);

}

// **************************************************************

}

Et pour mon Activity de configuration, l'utilisateur choisit l'item qu'il veut voir affiché dans le widget dans une liste, une fois selectionné je fait ceci:

Item item = (Item) itemsList.getAdapter().getItem(position);

SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());

Editor editor = prefs.edit();

String key = "widgetId=" + widgetId;

editor.putLong(key, server.getId());

editor.commit();

//declenche la mise à jour

Intent i = new Intent(getApplicationContext(), WidgetService.class);

i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);

startService(i);

Intent resultValue = new Intent();

resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);

setResult(RESULT_OK, resultValue);

finish();

Voilà je pense avoir bien suivit les tutos mais ça coince ! Quand je place 2 widgets, la mise à jour se déclenche et les 2 widgets prennent les infos du dernier widget placé !

quelqu'un aurait une idée pour résoudre mon problème ?

Merci d'avance !

Share this post


Link to post
Share on other sites

Je ne suis pas un spécialiste des widgets, je ne suis pas sûr de pouvoir t'aider. Néanmoins, j'ai noté 2-3 petits points dans ton code (d'ailleurs, si tu pouvais utiliser les balises [ code ], cela rendrait ton post plus lisible. merci)

- dans ton activity de configuration, tu utilises un Intent pour démarrer ton service, en passant un extra, extra qui n'est jamais utilisé dans le service

- dans le service, tu fais la mise à jour systématique de tous les widgets (cf ci-dessus extra non utilisé)

- dans le service, tu fais référence à un 'manager' que je ne vois déclaré nulle part

Share this post


Link to post
Share on other sites

J'ai réussit à m'en sortir mais avant je vais répondre aux points que tu as relevé:

- Désormais dans mon service je ne mets à jour que le widget dont l'id est passé dans l'intent

- l'id passé depuis l'activity de config à donc une utilité maintenant.

- La manager de mon service est une classe à moi pour mon appli ça n'a pas de rapport avec les Widgets !

Donc pour résoudre mon problème j'ai retiré la boucle dans mon service, je mets à jour seulement le widget passé dans l'intent !

Par contre j'ai un second problème dans le même ordre:

Je voudrais mettre à jour mon widget avec un intervalle récupéré dans les préférences. Voici mon code:

boolean update = this.prefs.getBoolean("auto_update", false);

	if(update) {
		String strDelay = this.prefs.getString("update_delay", "120"); 
		int delay = Integer.parseInt(strDelay);;
		delay *= 60; //convert to seconds
		delay *= 1000; // convert to ms

		delay = 10000; //juste pour tester avec un intervalle court !

		final AlarmManager m = (AlarmManager) this.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(this, WidgetService.class);
		i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widget);
        PendingIntent service = PendingIntent.getService(this, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);  
        m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), delay, service);  
	}

Le problème de ce code c'est que mon widget s'actualise sans délai, encore et encore en boucle !

Vous avez des idées ?

Share this post


Link to post
Share on other sites

Le problème vient sans doute de l'enregistrement de l'alarme. Tu l'enregistres pour un premier déclenchement dans le passé (tu as réinitialisé les champs heure/minutes/secondes du Calendar à 0, soit minuit de la journée en cours). Donc l'alarme se déclenche dès que tu l'enregistres, puisque minuit est déjà passé, puis minuit et 10 secondes, puis minuit et 20 secondes, etc...

J'enregistrerai plutôt l'alarme de cette façon

Calendar time = Calendar.getInstance();
time.add(Calendar.MILLISECOND, delay); // on avance le calendar de x ms dans le temps

...

m.setRepeating(AlarmManager.RTC, time.getTime().getTime(), delay, service);

Le premier déclenchement se fera dans x millisecondes, puis toutes les x millisecondes

Share this post


Link to post
Share on other sites





×
×
  • Create New...