2011-02-01 17 views
6

Sulla base this tutorial ho creato un widget che dovrebbe mostrare il tempo. La modalità java funziona, ma il modo di servizio no.Android Widget aggiornare

HelloWidget.java:

public class HelloWidget extends AppWidgetProvider { 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 

    Intent intent = new Intent(context, UpdateService.class); 
    context.startService(intent); 
} 

UpdateService.java:

public final class UpdateService extends Service { 
@Override 
public void onStart(Intent intent, int startId) { 
    RemoteViews updateViews = new RemoteViews(this.getPackageName(), R.layout.main); 

    Date date = new Date(); 
    java.text.DateFormat format = SimpleDateFormat.getTimeInstance(
      SimpleDateFormat.MEDIUM, Locale.getDefault()); 
      updateViews.setTextViewText(R.id.widget_textview, "Current Time " + format.format(date)); 

    ComponentName thisWidget = new ComponentName(this, HelloWidget.class); 
    AppWidgetManager manager = AppWidgetManager.getInstance(this); 
    manager.updateAppWidget(thisWidget, updateViews); 
} 

@Override 
public IBinder onBind(Intent intent) { 
    // TODO Auto-generated method stub 
    return null; 
} 

}

Il hello_widget_provider.xml ha questa riga: android: updatePeriodMillis = "1000"

Problema: il widget mostra l'ora corrente ma non si aggiorna (è java-way).

Il mio obiettivo principale è aggiornare il widget ad es. 18:56 ogni giorno. Idk se questo è il buon senso, ma ho cercato di modificare il metodo onUpdate come qui di seguito, ma ha un problema con ALARM_SERVICE: ALARM_SERVICE non può essere risolto per una variabile

public class HelloWidget extends AppWidgetProvider { 

@Override 
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 

    AlarmManager alarmManager; 
    Intent intent = new Intent(context, AlarmReceiver.class); 
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, 
     intent, PendingIntent.FLAG_UPDATE_CURRENT); 
    alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE); 
    Calendar cal = Calendar.getInstance(); 
    cal.set(Calendar.HOUR_OF_DAY, 18); 
    cal.set(Calendar.MINUTE, 56); 
    cal.set(Calendar.SECOND, 0); 
    cal.set(Calendar.MILLISECOND, 0); 
    alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), 86400, pendingIntent); 

} }

Qualunque l'aiuto è apprezzato

risposta

15

Guardando indietro nel tempo che ho fatto a questa domanda mi rendo conto di quanto ho appreso negli ultimi 1,5 anni.

Dal momento che ho appena lavorato con un widget nelle ultime due settimane e ho appena trovato questa mia domanda senza risposta, ho deciso di risolverlo. Spero che aiuti gli altri.

L'AppWidgetProvider dovrebbe essere simile a questo:

public class MyWidget extends AppWidgetProvider { 

    public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget"; 
    public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget"; 
    private PendingIntent service = null; 

     @Override 
     public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { 


      final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 

      final Calendar TIME = Calendar.getInstance(); 
      TIME.set(Calendar.MINUTE, 0); 
      TIME.set(Calendar.SECOND, 0); 
      TIME.set(Calendar.MILLISECOND, 0); 

      final Intent i = new Intent(context, MyService.class); 

      if (service == null) 
      { 
       service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT); 
      } 

      m.setRepeating(AlarmManager.RTC, TIME.getTime().getTime(), 1000 * 1, service); 

    } 

     @Override 
     public void onDeleted(Context context, int[] appWidgetIds) { 
       super.onDeleted(context, appWidgetIds); 
     } 

     @Override 
     public void onDisabled(Context context) { 
       super.onDisabled(context); 

       final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); 
       if (service != null) 
       { 
        m.cancel(service); 
       } 
     } 

     @Override 
     public void onEnabled(Context context) { 
       super.onEnabled(context); 
     } 

     @Override 
     public void onReceive(Context context, Intent intent) { 

     super.onReceive(context, intent); 

     } 

} 

Il Servizio:

public class MyService extends Service 
{ 
    @Override 
    public void onCreate() 
    { 
     super.onCreate(); 
    } 

    @Override 
    public int onStartCommand(Intent intent, int flags, int startId) 
    { 
     buildUpdate(); 

     return super.onStartCommand(intent, flags, startId); 
    } 

    private void buildUpdate() 
    { 
     String lastUpdated = DateFormat.format("hh:mm:ss", new Date()).toString(); 

     RemoteViews view = new RemoteViews(getPackageName(), R.layout.widget_layout); 
     view.setTextViewText(R.id.btn_widget, lastUpdated); 

     ComponentName thisWidget = new ComponentName(this, MyWidget.class); 
     AppWidgetManager manager = AppWidgetManager.getInstance(this); 
     manager.updateAppWidget(thisWidget, view); 
    } 

    @Override 
    public IBinder onBind(Intent intent) 
    { 
     return null; 
    } 
} 

Inoltre, registrare il provider e il Servizio nel Manifesto:

<receiver android:name="MyWidget" android:label="Tutorial_Widget 1x1"> 
      <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
       <action android:name="com.something.MyWidget.ACTION_WIDGET_RECEIVER"/> 
      </intent-filter>  
      <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_info"/> 
     </receiver> 

     <service android:enabled="true" android:name=".MyService" /> 
+0

mi dispiace, ma dove sono imposti il ​​tempo che deve determinare intervallo di ripetizione? –

+1

'm.setRepeating (AlarmManager.RTC, TIME.getTime(). GetTime(), 1000 * 1, servizio);' – erdomester

+0

sì, grazie, arrivo con questo. Mi interessa anche come posso impostare un tempo specifico, in cui verrà effettuato l'aggiornamento. –

3

ALARM_SERVICE è un campo statico della classe Context. Quindi digitare Context.ALARM_SERVICE o utilizzare un'importazione statica.

Ricordare che quando si imposta il valore dell'attributo updatePeriodMillis non è garantito che il proprio metodo onUpdate venga chiamato esattamente con quel periodo.

+0

ho mai avuto questo problema finora. Quando digito come hai detto, c'è un problema con getSystemService: "Il metodo getSystemService (String) non è definito per il tipo HelloWidget" – erdomester

+2

getSystemService (String) è un metodo di classe del contesto. Ma i provider di widget non sono contesti. Sono ricevitori broadcast e recuperano il contesto come parametro nei loro metodi. Per questo si deve digitare context.getSystemService (Context.ALARM_SERVICE) nel codice HelloWidget. –