Autore Topic: [AppWidget] Problema con RemoteViews e id del widget  (Letto 1797 volte)

Offline teskio

  • Moderatore globale
  • Utente normale
  • *****
  • Post: 387
  • Respect: +118
    • Github
    • Google+
    • Mostra profilo
    • Skullab
  • Dispositivo Android:
    Cubot GT99 / SurfTab Ventos 10.1
  • Play Store ID:
    Skullab Software
  • Sistema operativo:
    windows 7 / ubuntu 12.04
[AppWidget] Problema con RemoteViews e id del widget
« il: 08 Gennaio 2011, 23:45:03 CET »
0
Salve a tutti !
Scrivo questo post perchè sto avendo problemi nell'aggiornare graficamente un widget.
Spiego meglio : Ho realizzato un app widget, il quale al click dell'utente fa partire un servizio, e fin qui tutto bene. Ora il problema sorge nel voler cambiare graficamente una parte del layout del widget stesso. Il mio problema è che dal logcat che eseguo in fase di testing l'id relativo al widget, nel momento che eseguo l'updateAppWidget risulta essere diverso dall'id del widget creato !  o_O
Dato che è il servizio che aggiorna il layout ho inserito nell'intent una informazione relativa all'id  in questo modo :

intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);

Ma quando vado a "ripescarla" nel servizio :

Bundle extras = intent.getExtras();
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);

L'id è completamente un altro numero !  :-o
Addirittura nell'emulatore l'id è fisso a 6... :-\

Ora dato che il mio obbiettivo è quello di cambiare una parte del layout (in pricipio un Button), se qualcuno ha metodi alternativi vanno benissimo  :-)
Ho usato un Button nel layout per implementare il selettore degli stati ( pressed,focused and normal), ho poi provato a sostituirlo con un ImageView...o persino cambiato strada creando 3 diversi layout per il widget ma niente...non cambia
Non so più dove cercare...non trovo info a riguardo
Credo che il problema sia quel benedetto id del widget che non coincide, ma non so più che fare

Nel provider :
Codice (Java): [Seleziona]
            ...
            Intent updateIntent = new Intent(context,  goRouteService.class);
            updateIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
            Log.v(TAG,"widget id -> "+appWidgetId);     // <- L'ID DEL WIDGET !
            // Create Pending Intent
            PendingIntent pendingIntent = PendingIntent.getService(context, 0, updateIntent, 0);
            // Get Layout
            views = new RemoteViews(context.getPackageName(), R.layout.goroute_disabled);
            // Set onClickListener
            views.setOnClickPendingIntent(R.id.goroute_button, pendingIntent);
            //Update
            appWidgetManager.updateAppWidget(appWidgetId, views);

E questo è il Service :
Codice (Java): [Seleziona]
            ...
            Log.v(TAG,"started...");
            if(intent != null)Log.v(TAG,"ok intent");
           
            Bundle extras = intent.getExtras();
            int widgetId = 0 ;
            if(extras != null){
                widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
                Log.v(TAG,"ok extras - widget id : "+widgetId);   // <- QUI L'ID CAMBIA  NON E' QUELLO DEL WIDGET !!!!!!
            }else Log.v(TAG,"null extras");
            ...

Se qualchuno ne sa... :-P

Offline JD

  • Amministratore
  • Utente storico
  • *****
  • Post: 1600
  • Respect: +232
    • leinardi
    • Mostra profilo
  • Dispositivo Android:
    LG Nexus 5
  • Sistema operativo:
    L'ultima Ubuntu
Re:[AppWidget] Problema con RemoteViews e id del widget
« Risposta #1 il: 09 Gennaio 2011, 12:05:43 CET »
0
Purtroppo io non posso esserti d'aiuto: non mi sono ancora cimentato con i widget e quindi ho pochissima esperienza a riguardo :(

Vediamo se qualcuno dei widgettari riesce a darti qualche buon consiglio ;)
È stata trovata una soluzione al tuo problema?
Evidenzia il post più utile premendo . È un ottimo modo per ringraziare chi ti ha aiutato ;).
E se hai aperto tu il thread marcalo come risolto cliccando !

Offline teskio

  • Moderatore globale
  • Utente normale
  • *****
  • Post: 387
  • Respect: +118
    • Github
    • Google+
    • Mostra profilo
    • Skullab
  • Dispositivo Android:
    Cubot GT99 / SurfTab Ventos 10.1
  • Play Store ID:
    Skullab Software
  • Sistema operativo:
    windows 7 / ubuntu 12.04
Re:[AppWidget] Problema con RemoteViews e id del widget
« Risposta #2 il: 09 Gennaio 2011, 15:25:17 CET »
+4
Ce l’ho fatta !!  :D
Dopo varie prove e imprecazioni varie sono riuscito nell’intento !
Spiego come, magari potrà essere utile a qualcuno.
Allora, spulciando tra la documentazione di google ho scovato questo esempio di appWidget : http://code.google.com/p/wiktionary-android/source/browse/trunk/Wiktionary/src/com/example/android/wiktionary/WordWidget.java

Nell’esempio proposto da google, la creazione del layout del widget è demandata completamente ad un servizio, che parte automaticamente sull’OnUpdate del widget. Nel mio caso ho semplicemente aggiunto l’informazione relativa all’id del widget nell’Intent in questo modo :
Codice (Java): [Seleziona]
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
    for(i=0;i<appWidgetIds.length;i++){
        Intent intent = new Intent(context,servizioDelWidget.class);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetIds[i]);
        context.startService(intent);
    }
}

Poi vado a riprendere tale informazione nell’onStartCommand del servizio :
Codice (Java): [Seleziona]
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Bundle extra = intent.getExtras();
    int appWidgetId = extra.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
    return Service.START_STICKY  ;
}

In questo modo l’id del widget inviato al servizio coincide esattamente con quello inviato al mometo della creazione del widget ! Credo che il problema sia dato dall’updateAppWidget di AppWidgetManager, nel senso che una volta aggiornato il layout del widget si abbiano problemi di sincronizzazione, almeno questo è quello che ne ho dedotto. :-\

Comunque sia, anche se avevo risolto questo problema, non avevo ancora ottenuto ciò che mi ero prefissato: cambiare il layout del widget sul click dell’utente.
Analizzando l’esempio sopra citato ho scoperto un nuovo modo per aggiornare la RemoteViews del widget, non più usando l’id del widget ma bensì utilizzando un oggeto chiamato ComponentName, ed ecco come ho risolto :

Ho creato un oggetto statico che mi permette di aggiornare il layout sia nel widgetProvider sia nel Service associato al click del widget:
Codice (Java): [Seleziona]
public static class WidgetUpdate {
    public static void changeLayout(Context context,int layout){
        if(switchButton){ // variabile globale statica che mi permette di cambiare il layout ad ogni click del widget
            switchButton = false ;
        }else switchButton = true ;
        // Creao l’intent associate al servizio e il PendingIntent associate all’onClick
        Intent updateIntent = new Intent(context, servizioDelWidget.class);
        PendingIntent pendingIntent = PendingIntent.getService(context, 0, updateIntent, 0);
        // Prendo il riferimento al layout passato come argomento al metodo
        RemoteViews updateViews = new RemoteViews(context.getPackageName(),layout);
        // Setto l’onclick sul Button (nel mio caso…)
        updateViews.setOnClickPendingIntent(R.id.goroute_button, pendingIntent);
        // Creo un “identificatore” del componente specific, cioè il widget stesso ! LA SOLUZIONE !
        ComponentName widget = new ComponentName(context,goRouteProvider.class);
        // Prendo una istanza dell’AppWidgetManager
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        // Aggiorno il widget con la RemoteViews !!!
        manager.updateAppWidget(widget, updateViews);
    }
}

Ta-daa !  :D
Praticamente uso questo metodo nell’onUpdate del widgetProvider e nel Service associato, passandogli di volta in volta un layout differente.
Basta mi sono dilungato troppo, spero sia utile a qualcuno !

P.S : Ah dimenticavo di dire che con questa soluzione il layout si aggiornerà su tutti i widgets presenti nella home, in pratica cliccando su uno il layout cambierà per tutti !
(lo so non è il massimo, ma per come funziona il widget che sto sviluppando va benissimo...)

(JD non c’è il tasto AUTO-RISOLTO ?  :-P)
« Ultima modifica: 09 Gennaio 2011, 15:58:57 CET da teskio »

Offline Christian Giupponi

  • Utente junior
  • **
  • Post: 128
  • Respect: 0
    • Google+
    • http://it.linkedin.com/pub/christian-giupponi/29/628/810
    • ultimoprofeta
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
  • Play Store ID:
    ItalianDevTeam
  • Sistema operativo:
    Mac OSX Lion
Re:[AppWidget] Problema con RemoteViews e id del widget
« Risposta #3 il: 18 Luglio 2011, 15:28:42 CEST »
0
Grazie mille teskio era la soluzione che stavo cercando!!

Offline alepio

  • Utente normale
  • ***
  • Post: 163
  • Respect: +3
    • Google+
    • 107850838
    • Mostra profilo
  • Dispositivo Android:
    SAMSUNG ACE
  • Play Store ID:
    Alessandro Piola
  • Sistema operativo:
    WIN 7
Re:[AppWidget] Problema con RemoteViews e id del widget
« Risposta #4 il: 17 Settembre 2011, 20:47:08 CEST »
0

P.S : Ah dimenticavo di dire che con questa soluzione il layout si aggiornerà su tutti i widgets presenti nella home, in pratica cliccando su uno il layout cambierà per tutti !
(lo so non è il massimo, ma per come funziona il widget che sto sviluppando va benissimo...)

(JD non c’è il tasto AUTO-RISOLTO ?  :-P)

così facendo tutti i widget si aggiornano e questo comporta un dispendio di batteria.
Supponendo di aggiornare in widget ogni minuti tutti si aggiornano... Addio Batteria!!

ho proprio questo problema e volevo sapere se poi hai risolto
ciao
-----------------------------------------------------
Con RISPARMIO BATTERIA - Battery Saver puoi anche dimenticarti a casa il carica batteria. Inoltre con gli EXTRAS puoi configurare la navigazione e disattivare i banner pubblicitari. Battery Saver controlla in automatico lo stato dello schermo.Se è spento disattiva WIFI e NAVIGAZIONE MOBILE, per poi riaccenderle a schermo attivo.
[APP] BatterySaver - Android Developers Italia
--------