Een widget coderen voor uw Android-app de widget updaten

Toepassingswidgets bieden uw gebruikers eenvoudig toegang tot de meest gebruikte functies van uw toepassing en geven uw app een aanwezigheid op het startscherm van de gebruiker. Door een widget aan uw project toe te voegen, kunt u een betere gebruikerservaring bieden, terwijl u gebruikers aanmoedigt om betrokken te blijven bij uw applicatie, want elke keer dat ze een blik werpen op hun startscherm, zien ze uw widget en worden enkele van de nuttigste en nuttigste apps van uw app weergegeven. interessante inhoud.

In deze driedelige serie bouwen we een applicatiewidget die alle functionaliteit bevat die je in zo'n beetje vindt elk Applicatie-widget voor Android. 

In het eerste bericht hebben we een widget gemaakt die gegevens ophaalt en weergeeft en een unieke actie uitvoert als reactie op bij klikken evenementen. Onze widget mist echter nog steeds een cruciaal stuk functionaliteit: het nooit updates met nieuwe informatie. Een widget die nooit iets nieuws te bieden heeft, is niet zo nuttig, dus we geven onze widget twee verschillende manieren om te updaten. 

Aan het einde van deze serie hebben we onze widget uitgebreid om nieuwe gegevens automatisch op te halen en weer te geven op basis van een planning, en in reactie op gebruikersinteractie.

We gaan verder waar we gebleven waren, dus als je geen kopie hebt van de widget die we in het eerste bericht hebben gemaakt, dan kun je deze downloaden van GitHub.

Uw lay-out bijwerken

De eerste stap is het bijwerken van onze lay-out om enkele gegevens weer te geven die in de loop van de tijd veranderen. Om ons te helpen precies te zien wanneer onze widget elke update ontvangt, ga ik de widget opdracht geven om de huidige tijd op te halen en weer te geven, telkens wanneer een update wordt uitgevoerd. 

Ik ga het volgende toevoegen aan de widgetlay-out: 

  • EEN Tekstweergave dat toont een Laatste update label.
  • EEN Tekstweergave die de tijd van de laatste update toont.

Terwijl we werken aan de new_app_widget.xml bestand, ik ga ook het Tekstweergave waardoor de gebruiker uiteindelijk een update handmatig kan activeren: 

      // Voeg een 'Tap to update' TextView // toe   // Voeg een tekstweergave toe waarop ons label 'Laatste update' wordt weergegeven //  // Voeg de tekstweergave toe waarin de tijd van de laatste update wordt weergegeven //    

Definieer vervolgens de nieuwe tekenreeksbronnen waarnaar we verwijzen in onze lay-out: 

Tik om te updaten Laatste update % 1 $ s

De @ String / tijd ziet er anders uit dan uw standaardstring, omdat het slechts een tijdelijke aanduiding is die tijdens runtime wordt vervangen.

Dit geeft ons de voltooide lay-out:

Uw widget bijwerken op basis van een schema 

Omdat het de gemakkelijkste methode is om te implementeren, begin ik met het automatisch updaten van onze widget, nadat een ingestelde periode is verstreken. 

Bij het maken van dit soort automatische updateschema's is 1800000 milliseconden (30 minuten) het kleinste interval dat u kunt gebruiken. Zelfs als je je project hebt ingesteld updatePeriodMillis tot minder dan 30 minuten, zal je widget dat doen nog steeds update slechts eenmaal per half uur.

Bepalen hoe vaak uw widget moet worden bijgewerkt, is nooit eenvoudig. Regelmatige updates zorgen voor een grotere belasting van de batterij van het apparaat, maar stellen deze updates te ver uit elkaar en uw widget kan de gebruiker ver achter zich laten met aanzienlijk verouderde informatie.

Om een ​​balans te vinden die werkt voor uw specifieke project, moet u uw widget testen op een reeks updatefrequenties en de impact meten die elke frequentie heeft op de levensduur van de batterij, terwijl u controleert of de inhoud van de widget ooit merkbaar verouderd raakt. 

Aangezien hoe vaak-is-te-frequent één van die frustrerende subjectieve vragen is waar er geen "juist" antwoord is, kan het helpen om een ​​second opinion te krijgen door wat gebruikerstesten te regelen. U kunt zelfs A / B-tests instellen om te controleren of bepaalde updatefrequenties positiever worden ontvangen dan andere. 

Open je project AppWidgetProviderInfo het dossier (res / xml / new_app_widget_info.xml) en je zult zien dat het al een standaard update-interval van 86400000 milliseconden (24 uur) definieert. 

android: updatePeriodMillis = "86400000"

Er zijn veel widgets die slechts één keer per 24 uur worden bijgewerkt, bijvoorbeeld een widget die aangeeft dat de weersvoorspelling maar één keer per dag nieuwe informatie hoeft op te halen. Zelfs als uw widget slechts één keer per dag hoeft te worden bijgewerkt, is dit niet ideaal bij het testen van uw app. Niemand wil 24 uur wachten om te zien of zij onUpdate () methode correct triggert, dus u gebruikt meestal het kortst mogelijke interval bij het uitvoeren van de eerste tests en wijzig deze waarde later, indien nodig.

Om het gemakkelijker te maken onze app te testen, ga ik het kleinst mogelijke interval gebruiken: 

android: updatePeriodMillis = "1800000"

De huidige tijd ophalen en weergeven 

De onUpdate () methode is verantwoordelijk voor het bijwerken van uw widget's Keer bekeken met nieuwe informatie. Als u de widgetprovider van uw project opent (java / waarden / NewAppWidget.java) dan zul je zien dat het al de omtrek van een bevat onUpdate () methode: 

 @Override public void onUpdate (Context-context, AppWidgetManager appWidgetManager, int [] appWidgetIds) // Er kunnen meerdere widgets actief zijn, dus update ze allemaal // voor (int appWidgetId: appWidgetIds) updateAppWidget (context, appWidgetManager, appWidgetId) ; 

Ongeacht of uw widget automatisch wordt bijgewerkt of als reactie op gebruikersinteractie, het updateproces is exact hetzelfde: de widgetbeheerder verzendt een uitzendingsintentie met de ACTION_APPWIDGET_UPDATE actie en de klassen van de widget-provider reageren door de onUpdate () methode, die op zijn beurt de updateAppWidget () helper methode. 

Zodra we onze hebben bijgewerkt NewAppWidget.java klasse om de huidige tijd op te halen en weer te geven, zal ons project deze zelfde sectie van de code gebruiken, ongeacht hoe de onUpdate () methode is geactiveerd: 

importeer android.appwidget.AppWidgetManager; importeer android.appwidget.AppWidgetProvider; importeer android.content.Context; import android.widget.RemoteViews; importeer android.app.PendingIntent; importeer android.content.Intent; import android.net.Uri; importeer java.text.DateFormat; importeer java.util.Date; public class NewAppWidget breidt AppWidgetProvider uit static void updateAppWidget (Context-context, app AppWidgetManagerWidgetManager, int appWidgetId) // De tijd ophalen // String timeString = DateFormat.getTimeInstance (DateFormat.SHORT) .format (nieuwe datum ()); // Construeer het RemoteViews-object // RemoteViews-weergaven = nieuwe RemoteViews (context.getPackageName (), R.layout.new_app_widget); views.setTextViewText (R.id.id_value, String.valueOf (appWidgetId)); // Ophalen en weergeven van de tijd // views.setTextViewText (R.id.update_value, context.getResources (). GetString (R.string.time, timeString)); Intent intent = new Intent (Intent.ACTION_VIEW, Uri.parse ("https://code.tutsplus.com/)); PendingIntent pendingIntent = PendingIntent.getActivity (context, 0, intent, 0); views.setOnClickPendingIntent (R.id.launch_url, pendingIntent); appWidgetManager.updateAppWidget (appWidgetId, views);  @Override public void onUpdate (Context-context, AppWidgetManager appWidgetManager, int [] appWidgetIds) // Als er meerdere widgets actief zijn, update ze dan alle // for (int appWidgetId: appWidgetIds) updateAppWidget (context, appWidgetManager, appWidgetId);  

Er is één probleem met de bovenstaande code: als de gebruiker op de Tekstweergave meerdere keren gedurende de tijdspanne van een minuut, is er geen visuele indicatie dat de widget is bijgewerkt, simpelweg omdat er geen nieuwe tijd is om weer te geven. Dit zal waarschijnlijk geen problemen opleveren voor uw eindgebruikers, die daar waarschijnlijk niet zullen zitten, tikken op de Tekstweergave meerdere keren per minuut en zich afvragend waarom de tijd niet is veranderd. Dit kan echter een probleem zijn bij het testen van uw app, omdat het betekent dat u minstens 60 seconden moet wachten tussen het activeren van de app. onUpdate () methode. 

Om er zeker van te zijn dat er altijd een soort visuele bevestiging is dat het onUpdate () methode is succesvol verlopen, ik zal altijd een toast weergeven onUpdate () wordt genoemd: 

import android.widget.Toast; ... @Override public void onUpdate (Context-context, AppWidgetManager appWidgetManager, int [] appWidgetIds) for (int appWidgetId: appWidgetIds) updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, "Widget is bijgewerkt!", Toast.LENGTH_SHORT) .show (); 

Uw widget bijwerken in reactie op gebruikersactie

Onze widget wordt nu elk half uur automatisch geüpdatet, maar hoe zit het met het bijwerken in reactie op gebruikersinteractie? 

We hebben al veel van de basis gelegd door een Tik om te updaten Tekstweergave naar onze lay-out en het uitbreiden van de NewAppWidget.java klasse om de huidige tijd op elk gewenst moment op te halen en weer te geven onUpdate () wordt genoemd.

Het enige wat je hoeft te doen is een maken voornemen met AppWidgetManager.ACTION_APPWIDGET_UPDATE, Dit is een actie die de widget informeert dat het tijd is om te updaten en deze intentie vervolgens oproept als reactie op de interactie tussen de gebruiker en de gebruiker. Tik om te updaten Tekstweergave

Hier is het voltooid NewAppWidget.java klasse:

importeer android.appwidget.AppWidgetManager; importeer android.appwidget.AppWidgetProvider; importeer android.content.Context; import android.widget.RemoteViews; importeer android.app.PendingIntent; importeer android.content.Intent; import android.net.Uri; importeer java.text.DateFormat; importeer java.util.Date; import android.widget.Toast; public class NewAppWidget breidt AppWidgetProvider uit static void updateAppWidget (Context-context, app AppWidgetManagerWidgetManager, int appWidgetId) // De huidige tijd ophalen // String timeString = DateFormat.getTimeInstance (DateFormat.SHORT) .format (new Date ()); RemoteViews-weergaven = nieuwe RemoteViews (context.getPackageName (), R.layout.new_app_widget); views.setTextViewText (R.id.id_value, String.valueOf (appWidgetId)); views.setTextViewText (R.id.update_value, context.getResources (). getString (R.string.time, timeString)); // Maak een intentie met de appWidgetManager.ACTION_APPWIDGET_UPDATE actie // Intent intentUpdate = new Intent (context, NewAppWidget.class); intentUpdate.setAction (AppWidgetManager.ACTION_APPWIDGET_UPDATE); // Werk de huidige widgetinstantie alleen bij door een array te maken met de unieke ID van de widget // int [] idArray = new int [] appWidgetId; intentUpdate.putExtra (AppWidgetManager.EXTRA_APPWIDGET_IDS, idArray); // Wikkel de intentie in als PendingIntent met behulp van PendingIntent.getBroadcast () // PendingIntent pendingUpdate = PendingIntent.getBroadcast (context, appWidgetId, intentUpdate, PendingIntent.FLAG_UPDATE_CURRENT); // Verzend de pending intent in reactie op de gebruiker tikken op de 'Update' TextView // views.setOnClickPendingIntent (R.id.update, pendingUpdate); Intent intent = new Intent (Intent.ACTION_VIEW, Uri.parse ("https://code.tutsplus.com/)); PendingIntent pendingIntent = PendingIntent.getActivity (context, 0, intent, 0); views.setOnClickPendingIntent (R.id.launch_url, pendingIntent); // Verzoek dat AppWidgetManager de toepassingswidget update // appWidgetManager.updateAppWidget (appWidgetId, views);  @Override public void onUpdate (Context-context, AppWidgetManager appWidgetManager, int [] appWidgetIds) for (int appWidgetId: appWidgetIds) updateAppWidget (context, appWidgetManager, appWidgetId); Toast.makeText (context, "Widget is bijgewerkt!", Toast.LENGTH_SHORT) .show (); 

De mogelijkheid om een ​​widget op afroep bij te werken kan van onschatbare waarde zijn bij het testen van uw project, omdat het betekent dat u nooit hoeft te wachten totdat het update-interval verstrijkt. Zelfs als u deze functionaliteit niet in uw voltooide toepassing opneemt, wilt u misschien een tijdelijke toevoegen Tik om te updaten knop, alleen om uw leven gemakkelijker te maken bij het testen van uw project. 

Een voorbeeldafbeelding maken 

Onze widget ziet er nu uit helemaal anders dan de widget die Android Studio automatisch voor ons genereerde, maar op dit moment gebruikt het nog steeds de automatisch gegenereerde voorbeeldafbeelding.

Idealiter zou uw voorbeeldafbeelding gebruikers ertoe moeten aanzetten om uw widget uit de Widget-kiezer te selecteren, maar het zou op zijn minst een nauwkeurige weergave moeten zijn van hoe uw widget eruit ziet! Op dit moment tikt onze voorbeeldafbeelding geen van beide van die vakken, dus we moeten een nieuwe maken. 

De eenvoudigste methode is om de Widget Preview toepassing die is opgenomen in de Android-emulator.

Een Widget Preview maken

Installeer eerst uw project op een Android Virtual Device (AVD). Open vervolgens de app-lade van de AVD en start de toepassing Widget Preview. De AVD toont een lijst met alle apps die op het apparaat zijn geïnstalleerd: selecteer uw app in de lijst. 

Je widget wordt weergegeven op een lege achtergrond. Besteed wat tijd aan het wijzigen en aanpassen van je widget, zodat deze er op zijn best uitziet, en als je tevreden bent met de resultaten, selecteer je Maak snapshot. Het screenshot wordt opgeslagen als een PNG in de AVD's Download map. Om dit bestand op te halen, schakelt u terug naar Android Studio en opent u het Device File Explorer, door selecteren Beeld> Tool Windows> Device File Explorer van de werkbalk. Blader in de weergave Bestandsverkenner naar de sdcard / Download map, waarin u de voorbeeldafbeelding kunt opslaan als: [APP_NAME] _ori_ [oriëntatie] PNG

Sleep deze afbeelding uit Android Studio en plaats deze ergens gemakkelijk toegankelijk, zoals uw bureaublad. Geef de afbeelding een meer beschrijvende naam en sleep de afbeelding vervolgens naar uw project tekenbaar map. Nu kunt u de openen AppWidgetProviderInfo bestand (in dit geval, dat is new_app_widget_info.xml) en wijzig de volgende regel om naar uw nieuwe voorbeeldafbeelding te verwijzen: 

 android: previewImage = "@ betekenbare / example_appwidget_preview"

Ten slotte kunt u overbodig verwijderen example_appwidget_preview haalbaar vanuit uw project. 

Je widget testen

Het is tijd om de voltooide widget op de proef te stellen!

Installeer eerst het bijgewerkte project op uw fysieke Android-apparaat of AVD. Verwijder alle bestaande instanties van deze widget van je startscherm, dus jij weten je werkt met de nieuwste versie. 

Om je widget toe te voegen, druk je op een lege plek op het startscherm, tik je op widget en selecteer vervolgens je widget. Je krijgt de kans om de grootte van de widget aan te passen en de positie ervan te wijzigen, indien nodig. 

De Laatste update waarde geeft de tijd weer dat u deze widget hebt gemaakt. druk op Tik om te updaten en de widget zou een toast en een nieuwe tijd moeten weergeven. Als u een tweede exemplaar van de widget op uw startscherm plaatst, moet deze een ander tijdstip weergeven dan de eerste. 

U kunt een van deze widget-exemplaren bijwerken door deze te geven Tik om te updaten Tekstweergave een kraan. Als u een handmatige update activeert voor de eerste widget, wordt de tweede widget niet bijgewerkt en omgekeerd. 

Naast handmatige updates wordt de App Widget Manager bijgewerkt allemaal exemplaren van uw widget eenmaal per 30 minuten, op basis van het tijdstip waarop u de eerste instantie hebt gemaakt. Hoewel handmatige updates ertoe kunnen leiden dat instanties verschillende tijden weergeven, worden alle exemplaren eens per half uur tegelijkertijd bijgewerkt, waarna ze tegelijkertijd worden weergegeven.

U kunt een paar voorbeelden van deze widget op uw startscherm behouden, zodat u kunt bijhouden hoe hun inhoud verandert in de loop van de tijd als reactie op een combinatie van automatische en handmatige updates.

Conclusie

In deze serie hebben we een Android-toepassingswidget gemaakt die laat zien hoe u alle meest voorkomende functies in app-widgets implementeert. Als je vanaf het begin meegaat, heb je op dit punt een widget gebouwd die automatisch en in reactie op gebruikersinvoer wordt bijgewerkt en die in staat is om te reageren op onClick-evenementen (je kunt ook het volledige project downloaden van GitHub ). 

In het volgende bericht bekijken we enkele praktische tips om ervoor te zorgen dat uw widget een goede gebruikerservaring biedt en hoe u uw widget kunt verbeteren met een configuratie-activiteit.