2012-11-20 2 views
6

Il TextView nel mio widget è impostato correttamente con le informazioni corrette quando viene inserito nella schermata iniziale. Ma quando aggiorno le informazioni nell'app principale, il widget mostra ancora le vecchie informazioni.TextView nel widget di Android non si aggiorna

manifesto:

<receiver android:name=".WidgetProvider" android:label="@string/app_name" android:exported="false"> 
    <intent-filter> 
     <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
    </intent-filter> 

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

WidgetProvider.java:

package com.example.huskeliste; 

import android.app.PendingIntent; 
import android.appwidget.AppWidgetManager; 
import android.appwidget.AppWidgetProvider; 
import android.content.Context; 
import android.content.Intent; 
import android.widget.RemoteViews; 

public class WidgetProvider extends AppWidgetProvider { 

    @Override 
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 
     final int N = appWidgetIds.length; 

     for (int i = 0; i < N; i++) { 
      int widgetId = appWidgetIds[i]; 

      DBAdapter info = new DBAdapter(context); 

      info.open(); 
      String data = info.getTextViewData(); 
      info.close(); 

      Intent intent = new Intent(context, Main.class); 
      PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0); 

      RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget); 
      views.setOnClickPendingIntent(R.id.loWidget, pendingIntent); 
      views.setTextViewText(R.id.txtView, data); 
      appWidgetManager.updateAppWidget(widgetId, views); 
     } 
    } 
} 

res - widget.xml:

<?xml version="1.0" encoding="utf-8"?> 
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:initialLayout="@layout/widget" 
    android:minWidth="294dp" 
    android:minHeight="72dp" 
    android:updatePeriodMillis="1800000"> 
</appwidget-provider> 

Layout - widget.xml:

<?xml version="1.0" encoding="utf-8"?> 
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    android:id="@+id/loWidget" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    android:orientation="vertical" 
    android:gravity="center" 
    android:layout_margin="1dp" 
    android:background="@drawable/background"> 

    <TextView 
     android:id="@+id/txtView" 
     android:layout_width="wrap_content" 
     android:layout_height="wrap_content" 
     android:textSize="22dp" 
     android:textColor="#ffffff" 
     android:text="" /> 
</LinearLayout> 

background.xml:

<?xml version="1.0" encoding="utf-8"?> 
<shape xmlns:android="http://schemas.android.com/apk/res/android"> 
    <gradient android:startColor="#CC111111" android:endColor="#CC111111" android:angle="0" /> 
    <padding android:left="4dp" android:top="1dp" android:right="4dp" android:bottom="1dp" /> 
    <corners android:radius="3dp" /> 
</shape> 

getTextViewData() da DBAdapter.java:

public String getTextViewData() { 
    String[] columns = new String[] { KEY_NAME }; 
    Cursor c = ourDatabase.query(DATABASE_TABLE, columns, null, null, null, null, null); 

    String result = ""; 

    for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) {   
     if (result.length() > 0) { 
      result += ", "; 
     } 

     result += c.getString(0); 
    } 

    return result; 
} 

Qualcuno ha idea di cosa manca nel mio codice?

risposta

4

È necessario impostare un intervallo di aggiornamento in millisecondi all'interno del provider XML del widget. Example code:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:minWidth="294dp" 
    android:minHeight="72dp" 
    android:updatePeriodMillis="86400000" 
    android:previewImage="@drawable/preview" 
    android:initialLayout="@layout/example_appwidget" 
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode="horizontal|vertical" 
    android:widgetCategory="home_screen|keyguard" 
    android:initialKeyguardLayout="@layout/example_keyguard"> 
</appwidget-provider> 

Tuttavia, si dovrebbe sapere che il sistema non garantisce il widget da aggiornare il più spesso. Inoltre, se desideri che il widget si aggiorni più spesso (ad esempio dopo una modifica alla configurazione, come nella tua domanda), devi farlo manualmente. Ecco come procedo:

In questo esempio la mia classe Widget si chiama semplicemente Widget.class:

public class Widget extends AppWidgetProvider { 

    // TODO: Don't forget to override the onUpdate method also 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     if (intent.getAction().equals("update_widget")) { 
      // Manual or automatic widget update started 

      RemoteViews remoteViews = new RemoteViews(context.getPackageName(), 
        R.layout.widget); 

      // Update text, images, whatever - here 
      remoteViews.setTextViewText(R.id.yourTextID, "My updated text"); 

      // Trigger widget layout update 
      AppWidgetManager.getInstance(context).updateAppWidget(
        new ComponentName(context, Widget.class), remoteViews); 
     } 
    } 

} 

Assicurarsi di sostituire il layout e la TextView con riferimenti il ​​layout dei widget.

Poi ogni volta che si desidera aggiornare il tuo widget (ad esempio nel metodo della vostra attività principale o ogni volta che un pulsante Salva si fa clic), si chiama un PendingIntent:

Intent updateWidget = new Intent(context, Widget.class); // Widget.class is your widget class 
updateWidget.setAction("update_widget"); 
PendingIntent pending = PendingIntent.getBroadcast(context, 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT); 
pending.send(); 
+0

Grazie per answere veloce. In Main.java il "contesto" in Intent updateWidget = new Intent (context, WidgetProvider.class); è vuoto. A cosa dovrei impostare il contesto? Il contesto – user1759708

+0

è contrassegnato con "il contesto non può essere risolto in una variabile". – user1759708

+1

Questo è il tuo contesto di attività. Puoi usare 'getBaseContext()' o 'this' there. –