2011-02-01 42 views
6

Basado en el tutorial this creé un widget que debería mostrar la hora. La forma Java funciona, pero la forma de servicio no funciona.Android Widget update

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; 
} 

}

El hello_widget_provider.xml tiene esta fila: android: updatePeriodMillis = "1000"

Problema: el widget muestra la hora actual pero no se está actualizando (es la ruta java).

Mi objetivo principal es actualizar el widget, p. 18:56 todos los días. Idk si este es el buen camino, pero traté de modificar el método onUpdate como el de abajo, pero tiene un problema con ALARM_SERVICE: ALARM_SERVICE no se puede resolver de una variable

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); 

} }

Cualquier ayuda es apreciada

Respuesta

15

Mirando hacia atrás el tiempo que hice esta pregunta me hace darme cuenta de lo mucho que aprendí en los últimos 1,5 años.

Como he estado trabajando con un widget en las últimas dos semanas y acabo de encontrar esta pregunta sin respuesta, decidí resolverla. Espero que ayude a otros.

El AppWidgetProvider debería tener este aspecto:

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); 

     } 

} 

El servicio:

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; 
    } 
} 

Además, registrar el proveedor y el Servicio en el Manifiesto:

<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

lo siento, pero ¿dónde se establece el tiempo que tiene que determinar el intervalo de repetición? –

+1

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

+0

sí, gracias, me encargo de esto. También me interesó cómo puedo establecer una hora específica, en la cual se llevará a cabo la actualización. –

3

ALARM_SERVICE es un campo estático de la clase Contexto. Así que escriba Context.ALARM_SERVICE o use una importación estática.

Recuerde que cuando establece el valor del atributo updatePeriodMillis, no se garantiza que el método onUpdate se invoque con ese período exactamente.

+0

nunca he tenido este problema hasta ahora. Cuando escribo como dijo, hay un problema con getSystemService: "El método getSystemService (String) no está definido para el tipo HelloWidget" – erdomester

+2

getSystemService (String) es un método de la clase Context. Pero los proveedores de widgets no son contextos. Son receptores de difusión y recuperan el contexto como un parámetro en sus métodos. Por lo tanto, debe escribir context.getSystemService (Context.ALARM_SERVICE) en el código HelloWidget. –