Autore Topic: Widget e istanze multiple  (Letto 938 volte)

Offline flashman

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
Widget e istanze multiple
« il: 11 Settembre 2013, 11:15:16 CEST »
0
Salve ragazzi,

un veloce complimenti per il forum. Sto imparando tantissime cose.

Ultimamente mi sto cimentando nei widget e sono partito da vari codici trovati in rete.

Il semplice widget, ormai noto tra gli esempi in rete, prevede la generazione di un numero random al suo interno quando viene posizionato e ogni volta
che viene detectato un click. Ho apportato, vedendo altri esempi, una modifica che permette di istanziare piu' widget che si aggiornano in maniera indipendente.
Funziona tutto ma non riesco a comprendere il funzinamento. Ho dubbi anche sulla bonta' del codice.

Il codice che allego prevede solo l'override del metodo onUpdate nel quale ho inserito dei Log per verificare le chiamate.

Codice (Java): [Seleziona]
// On Update Istance!
        @Override
        public void onUpdate(Context context, AppWidgetManager appWidgetManager,
          int[] appWidgetIds) {
          Toast.makeText(context, "Widget onUpdate method ", Toast.LENGTH_SHORT).show();
      Log.w("onUpdate ", "INPUT");

          final int N = appWidgetIds.length;
         
          // Perform this loop procedure for each App Widget that belongs to this provider
      for (int i=0; i<N; i++) {
          int widgetId = appWidgetIds[i];
         
          // Create some random data
          int number = (new Random().nextInt(100));
         
          // Set a remote View
          RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
          Log.w("onUpdate : widgetId", String.valueOf(widgetId));        
          Log.w("onUpdate : number ", String.valueOf(number));
                         
          // Set the text
          remoteViews.setTextViewText(R.id.update, String.valueOf(number));
         
         
          // Register an onClickListener
          Intent intent = new Intent(context, Mywidget_provider.class);

          intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
          intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);

          PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
                          widgetId, intent, 0);
         
          remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
         
          appWidgetManager.updateAppWidget(widgetId, remoteViews);
         
          Log.w("onUpdate ", "OUTPUT");

      }
        }

Questo e' il log  sulla prima istanza :

Codice (Java): [Seleziona]
09-11 09:04:27.630: W/onUpdate(13543): INPUT
09-11 09:04:27.630: W/onUpdate : widgetId(13543): 97
09-11 09:04:27.630: W/onUpdate : number(13543): 93
09-11 09:04:27.637: W/onUpdate(13543): OUTPUT

e si ripete ogni volta che clicco in maniera corretta.

Vi pongo adesso alcune domande :
 1 - onUpdate viene chiamato quando istanzio il widget e tramite intent aggiorna il widget con il numero casuale. Aggiunge un extra che secondo me non viene utilizzato. E' corretto ?
 2 - Viene schedulato un pending intent che ritriggera il layout  xml (remotevies) sul click. Come si ritriggera l'onUpdate ?
 3 - appWidgetManager.updateAppWidget(widgetId, remoteViews); prende come parametro solo widgetId ma c'e' un ciclo for su tutte le istanze. Non dovrebbe aggiornarle tutte.
 
 Vorrei chiarirmi il flusso del codice ma non ci riesco. Potreste aiutarmi ?

Offline crbin1

  • Utente junior
  • **
  • Post: 61
  • Respect: +6
    • labeltodo
    • Mostra profilo
    • Do Androids Dream of Electric Sheep?
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #1 il: 11 Settembre 2013, 12:18:35 CEST »
0
Citazione
1 - onUpdate viene chiamato quando istanzio il widget e tramite intent aggiorna il widget con il numero casuale. Aggiunge un extra che secondo me non viene utilizzato. E' corretto ?

L'extra dovrebbe essere utilizzato dal servizio che aggiorna il widget

Citazione
2 - Viene schedulato un pending intent che ritriggera il layout  xml (remotevies) sul click. Come si ritriggera l'onUpdate ?

In italiano?  :-P :-P :-P No davvero, a parte gli scherzi, non ho capito cosa intendi

Citazione
3 - appWidgetManager.updateAppWidget(widgetId, remoteViews); prende come parametro solo widgetId ma c'e' un ciclo for su tutte le istanze. Non dovrebbe aggiornarle tutte.

widgetId viene ricreato ogni volta all'interno del ciclo, quindi aggiorna tutti i widget

Offline flashman

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #2 il: 11 Settembre 2013, 13:21:11 CEST »
0
Grazie per il supporto.

onUpdate viene chiamato quando istanzio il widget. Ma, a mio avviso e non e' cosi', non dovrebbe aggiornare nulla fino a quando
non faccio un click.

Non capisco perche' quando lo istanzio ho gia' il numero dentro il widget. Che triggeri l'evento del click mentre lo muovo ?

Potresti spiegarmi le righe che vanno dall'intent alla fine delle routine ?

Infine, e questo il grosso dilemma, il widget che si aggiorna e' solo quello su cui clicco. Non tutti. Non capisco perche'!

Offline crbin1

  • Utente junior
  • **
  • Post: 61
  • Respect: +6
    • labeltodo
    • Mostra profilo
    • Do Androids Dream of Electric Sheep?
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #3 il: 11 Settembre 2013, 17:25:52 CEST »
0
Grazie per il supporto.

onUpdate viene chiamato quando istanzio il widget. Ma, a mio avviso e non e' cosi', non dovrebbe aggiornare nulla fino a quando
non faccio un click.

Non capisco perche' quando lo istanzio ho gia' il numero dentro il widget. Che triggeri l'evento del click mentre lo muovo ?

Potresti spiegarmi le righe che vanno dall'intent alla fine delle routine ?

Infine, e questo il grosso dilemma, il widget che si aggiorna e' solo quello su cui clicco. Non tutti. Non capisco perche'!


onUpdate viene chiamato quando il widget viene automaticamente aggiornato in base al valore che hai messo come updatePeriodMillis. Viene chiamato anche quando l'utente aggiunge il widget se non hai creato un'activity di configurazione, è per questo che nel tuo caso vedi subito il numero. Se non vuoi che aggiorni niente senza il click devi togliere quel ciclo di aggiornamento, se invece vuoi che lo aggiorni solo quando passa il tempo dell'autoaggiornamento ma non alla sua creazione devi appunto creare un'activity di configurazione.

In pratica gli dici che sul click lanci un broadcast

Codice (Java): [Seleziona]
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, widgetId, intent, 0);
Potresti usare PendingIntent.getActivity o PendingIntent.getService se vuoi lanciare un'activity o un service al click.

Tu usi un broadcast quindi da qualche parte dovresti usare un broadcast receiver, giusto?

Offline flashman

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #4 il: 11 Settembre 2013, 18:06:59 CEST »
0
Concordo sulla chiamata.

Ma nel codice aggiorno il numero tramite remoteview su cui detecto un click tramite un pending intent.

Quindi anche se chiamata non dovrei vedere il numero ma solo il testo di default. E' corretto ?

Ho sempre maggiore confusione  :-(

Mi date qualche indicazione per capire meglio questa porzione di codice ?


Offline crbin1

  • Utente junior
  • **
  • Post: 61
  • Respect: +6
    • labeltodo
    • Mostra profilo
    • Do Androids Dream of Electric Sheep?
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #5 il: 12 Settembre 2013, 14:39:30 CEST »
0
Concordo sulla chiamata.

Ma nel codice aggiorno il numero tramite remoteview su cui detecto un click tramite un pending intent.

Quindi anche se chiamata non dovrei vedere il numero ma solo il testo di default. E' corretto ?

Ho sempre maggiore confusione  :-(

Mi date qualche indicazione per capire meglio questa porzione di codice ?

onUpdate viene chiamata quando l'utente aggiunge il wigdet (alle condizioni dette sopra) e in onUpdate il tuo codice crea per ogni widget un numero casuale e popola con quello la TextView, quinsi è normale che in quel momento ci sia il primo aggiornamento.

Per il click hai un broadcast receiver?

Offline flashman

  • Nuovo arrivato
  • *
  • Post: 20
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Galaxy Nexus
Re:Widget e istanze multiple
« Risposta #6 il: 12 Settembre 2013, 15:14:47 CEST »
0
Si ti allego il file AndroidManifest :

AndroidManifest :
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.learn.mywidget"
   android:versionCode="1"
   android:versionName="1.0" >

    <uses-sdk
       android:minSdkVersion="8"
       android:targetSdkVersion="17" />

    <application
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name" >
        <receiver android:name="Mywidget_provider" >
            <intent-filter >
                <action
                   android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
               android:name="android.appwidget.provider"
               android:resource="@xml/widget_info" />
        </receiver>
    </application>
   

</manifest>

main activity :
Codice (XML): [Seleziona]
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:paddingBottom="@dimen/activity_vertical_margin"
   android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   tools:context=".MainActivity" >

</RelativeLayout>

widget layout :
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   android:id="@+id/layout"
   android:layout_width="match_parent"
   android:layout_height="match_parent"
   android:layout_margin="8dip"
   android:background="@drawable/myshape" >

    <TextView
       android:id="@+id/update"
       style="@android:style/TextAppearance.Medium"
       android:layout_width="match_parent"
       android:layout_height="match_parent"
       android:layout_gravity="center"
       android:gravity="center_horizontal|center_vertical"
       android:layout_margin="4dip"
       android:text="Static Text" >
    </TextView>

</LinearLayout>

widget_info :
Codice (XML): [Seleziona]
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
   xmlns:android="http://schemas.android.com/apk/res/android"
   android:minHeight="72dip"
   android:updatePeriodMillis="180000"
   android:minWidth="146dip"
   android:initialLayout="@layout/widget_layout">
   

</appwidget-provider>

Post unito: 12 Settembre 2013, 19:05:49 CEST
Ho aggiunto un Log per stampare appWidgetIds.length ed e' sempre 1 qualsiasi sia il numero di widget che aggiungo.

E' come se si aggiungesse un nuovo oggetto per ogni widget.

Avete qualche suggerimento da darmi ? Dovrei avere N che aumenta e non e' cosi'.

« Ultima modifica: 12 Settembre 2013, 19:05:49 CEST da flashman, Reason: Merged DoublePost »