Modifier le contenu sur un Widget Android

Pour l'IUT j'ai dût créer un widget Android qui affiche une phrase choisie dans une liste prédéfinie. Si vous ne savez pas comment ajouter un Widget à votre application, le mieux est de se perdre un peu sur des tutoriels et sur la documentation Android.
Mais si, comme moi, vous utilisez Android Studio voici un raccourci TRÈS pratique :

Clic droit > New > Widget > App Widget

New App Widget on Android Studio

Dans la classe du Widget une fonction onUpdate est appelée quand le Widget est ajouté à l'écran d’accueil.
Bien sûr vous pouvez modifier le contenu du Widget dans les autres classes.

Modifier un élément du Widget

Voici une fonction pour modifier notre Widget. Dans le code qui suit nous modifions le texte d'un label lbl_wdgt_hello dans un widget appelé app_widget implémenté par la classe AppWidget.

protected void updateHello(String helloText) {
    Context context = this;
    AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
    ComponentName thisWidget = new ComponentName(context, AppWidget.class);

    remoteViews.setTextViewText(R.id.lbl_wdgt_hello, helloText);
    appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}

Il suffit ensuite d'appeler la fonction pour modifier le texte de lbl_wdgt_hello.

updateHello("Hello World");

Explications

Context context = this;
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

Nous avons besoin du contexte pour accéder à des ressources et des classes spécifiques aux applications, comme les WidgetApp, cette classe est fournie par le système Android La classe AppWidgetManager permet d’interagir avec les WidgetApp, comme mettre à jour leur état.

RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.app_widget);
ComponentName thisWidget = new ComponentName(context, AppWidget.class);

La première ligne instancie une vue dans remoteViews, cette vue est celle dont l'ID est app_widget.
La deuxième ligne fait pareil mais pour la classe du widget, dont la classe est AppWidget.

remoteViews.setTextViewText(R.id.lbl_wdgt_hello, helloText);

Voici l'instruction principale de notre fonction, celle-ci modifie la vue remoteViews. Le texte de l'élement dont l'ID est lbl_wdgt_hello prend la valeur de helloText grâce à la méthode setTextViewText().
Mais ceci ne suffit pas, les widgets utilisent encore la vue déclarée dans res/layout/, il faut demander au widget d'utiliser la vue modifiée.

appWidgetManager.updateAppWidget(thisWidget, remoteViews);

C'est pourquoi nous demandons au widget thisWidget d'utiliser la vue remoteViews.

Exemple : Injecter du contenu prédéfini

Si vous voulez injecter aléatoirement un mot avec le code vu ci-dessus il suffit de stocker une liste de String dans les ressources (/res/values/strings.xml).

<string-array name="loremipsum_array">
    <item>Lorem</item>
    <item>Ipsum</item>
    <item>Sit</item>
</string-array>

Cette fonction permet d'en sélectionner un aléatoirement :

protected String getRandomWord() {
    Resources res = getResources();
    String[] words = res.getStringArray(R.array.loremipsum_array);

    int word_id = (int) (Math.random() * words.length - 1);

    return word[word_id];
}

Et d'appeler notre fonction updateHello ainsi :

updateHello(getRandomWord());
Resources res = getResources();
String[] words = res.getStringArray(R.array.loremipsum_array);

Permet de créer un tableau avec les valeurs stockées dans les ressources.

Math.random() * words.length - 1

Permet d'avoir un nombre entre 0 et l'index maximum du tableau words.

Conclusion

Je n'ai que quelques notions en Java et en développement Android, c'est pourquoi je ne voulais pas faire un tutoriel. Considérez ceci plutôt comme un petit coup de pouce pour novice.