DevCorner620

DevCorner: sviluppiamo un semplice widget

Giuseppe Tripodi

Tutte le app che si rispettino (o quasi) allegano ormai al proprio bagaglio un widget da piazzare in HomeScreen: da semplici shortcut alle impostazioni ad applicazioni più o meno complesse direttamente in home, ormai se ne vedono davvero di tutti i tipi. Per questo motivo, se volete fregiarvi dell’ingombrante titolo di sviluppatore Android, è il caso che diate  un’occhiata a come svilupparne uno. 

Per iniziare con questo tutorial, per prima cosa create un nuovo progetto per un’applicazione ma, a differenza di quanto fate di solito, potete ignorare la spunta per creare automaticamente un’Activity poiché non ne avremo alcuna. Per prima cosa, quindi, definiamo l’aspetto estetico del nostro widget, creando un layout all’interno dell’omonima cartella: noi ci abbiamo inserito il logo della rubrica DevCorner con sotto un tasto, il tutto circondato da un background chiaro. Voi, ovviamente, procedete pure come vi pare.



Fatto questo, il prossimo step prevede la creazione di una cartella chiamata xml che conterrà un file con la medesima estensione: si tratta del cosiddetto provider, che specifica larghezza e altezza massima del nostro widget nonché il layout cui fare riferimento.

È quindi arrivato il momento di scrivere finalmente un po’ di codice Java: creiamo una nuova classe (che noi abbiamo chiamato MyWidgetProvider) e facciamole estendere AppWidgetProvider: nei widget non c’è il classico concetto di OnClickListner cui siamo abituati, per questo motivo andremo a fare l’Override di due metodi per poter gestire al meglio il click sul tasto, che nel nostro caso vogliamo che lanci un Toast e apra il browser con tutte le puntate di DevCorner. I due metodi in questione sono onUpdate e onReceive: come è facile intuire dai nomi, il primo definisce cosa deve fare il widget quando riceve un input di aggiornamento, mentre il secondo riceve il suddetto input e lo gestisce a seconda di cosa lo ha scatenato.

Per questo motivo, dopo aver definito una stringa arbitraria per definire il nostro evento, nel metodo onUpdate andremo a definire la nostra RemoteViews attraverso il layout e la classe che si occuperà di gestirlo, ossia la stessa MyWidgetProvider che stiamo attualmente scrivendo. Utilizziamo, quindi, il metodo setOnClickPendingIntent della RemoteView per assegnare un PendingIntent (definito con la nostra stringa SYNC_CLICKED) al bottone sotto il nostro Androide. Infine, segnaliamo all’appWidgetManager di controllare il widget in questione tramite questa classe che stiamo sviluppando.

Prima di procedere con l’onReceive, inoltre, occupiamoci di definire il semplice metodo getPendingSelfIntent che abbiamo già utilizzato:

public class MyWidgetProvider extends AppWidgetProvider {

    private static final String SYNC_CLICKED = "AwDevCorner";

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        RemoteViews remoteViews;
        ComponentName watchWidget;

        remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
        watchWidget = new ComponentName(context, MyWidgetProvider.class);

        remoteViews.setOnClickPendingIntent(R.id.buttonPlus, getPendingSelfIntent(context, SYNC_CLICKED));
        appWidgetManager.updateAppWidget(watchWidget, remoteViews);
    }

    protected PendingIntent getPendingSelfIntent(Context context, String action) {
        Intent intent = new Intent(context, getClass());
        intent.setAction(action);
        return PendingIntent.getBroadcast(context, 0, intent, 0);
    }

Per completare la classe, definiamo anche cosa deve fare una volta ricevuto il PendingIntent, a patto che l’azione dello stesso corrisponda con quella definita nella stringa all’inizio della classe. Nel nostro caso, il widget lancerà un Toast con la frase “DevCorner: Nelle puntate precedenti…” (sempre d’effetto!) e aprirà il browser con l’url che rimanda a tutti gli appuntamenti della rubrica.

 @Override
    public void onReceive(Context context, Intent intent) {
        // TODO Auto-generated method stub
        super.onReceive(context, intent);

        if (SYNC_CLICKED.equals(intent.getAction())) {

            AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

            RemoteViews remoteViews;
            ComponentName watchWidget;

            remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
            watchWidget = new ComponentName(context, MyWidgetProvider.class);
            Log.e("ProvaClick","Received");
            Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.androidworld.it/tag/devcorner"));
            browserIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            context.getApplicationContext().startActivity(browserIntent);
            Toast.makeText(context.getApplicationContext(), "DevCorner: Nelle puntate precedenti...", Toast.LENGTH_LONG).show();;
            appWidgetManager.updateAppWidget(watchWidget, remoteViews);

        }
    }

Prima di concludere, tuttavia, c’è un ultimo step da eseguire, senza il quale tutto il nostro lavoro sarà andato perduto: inserire un receiver all’interno del Manifeste, dal quale filtriamo la classe che si occupa del Widget e l’XML che funziona da provider. Già che siamo nel Manifest, poi, inseriamo anche i permessi per utilizzare  Internet.

Anche per questa settimana l’appuntamento con DevCorner è finito: nell’attesa del prossimo martedì potete dar libero sfogo alla vostra fantasia con i Widget più disparati e, nel caso aveste bisogno di una mano, potete sempre ricorrere al nostro forum, dove tra l’altro troverete i sorgenti completi e l’apk di riferimento per questo tutorial.