7

Mi aplicación tiene un widget que muestra la fecha de hoy y debe actualizarse a medianoche. El widget se define en el manifiesto como¿Cómo actualizar un widget de aplicación en la medianoche?

<manifest> 
    ... 
    <application> 
     ... 
     <receiver 
      android:name=".MyWidgetProviderClass" 
      android:label="MyLabel" > 
      <intent-filter> 
       <action android:name="android.appwidget.action.APPWIDGET_UPDATE" /> 
      </intent-filter> 

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

Y el archivo de información del widget es

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" 
    android:initialLayout="@layout/my_layout" 
    android:minHeight="40dp" 
    android:minWidth="294dp" 
    android:updatePeriodMillis="3600000" > 
</appwidget-provider> 

Esto hace que el widget para actualizar la información en cualquier momento entre la medianoche y las 13:00, pero quiero para actualizarse más cerca de la medianoche por lo que añade a la aplicación de un receptor intención

<receiver 
    android:name=".MyWidgetUpdaterClass" 
    android:enabled="true" > 
    <intent-filter> 
     <action android:name="MyAction" /> 
     </intent-filter> 
</receiver> 

y un método estático

public static void setMidngintAlarms(Context context) { 
    Intent intent = new Intent("MyAction"); 
    PendingIntent pendingIntent = 
     PendingIntent.getBroadcast(context, 0, intent, 0);    
    long interval = 24*60*60*1000;   
    long firstTime = SystemClock.elapsedRealtime() + 
     millisecondsToNextMidnight(); 
    AlarmManager am = (AlarmManager)context.getSystemService(
     Context.ALARM_SERVICE); 
    am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, 
        firstTime, interval, pendingIntent); 
} 

(dado que las solicitudes del gestor de alarmas con la misma intención se sobrescriben entre sí no hay ningún problema al llamar a setMidngintAlarms varias veces).

Intenté llamar a setMidnightAlarms() desde pocos lugares (desde la actividad principal de la aplicación, desde onUpdate() de AppWidgetProvider). Todo funciona bien y los intentos del administrador de alarmas se reciben y el widget se actualiza, pero solo mientras se ejecuta la aplicación. Si eliminé la aplicación, los widgets dejan de actualizarse a medianoche.

¿Alguna idea de cómo hacer que los widgets se actualicen en la medianoche? ¿Debo agregar un servicio? ¿Si es así, cómo? ¿Algún ejemplo?

Estoy un poco sorprendido de lo poco trivial que es lograr que funcione esta funcionalidad básica.

+0

El widget todavía debe actualizarse porque está configurando una alarma para él. Por lo tanto, no importa si la aplicación se está ejecutando o no. No importa si el dispositivo se reinicia y usted no registra su alarma desde el principio. –

+0

Cuando se establece una alarma de repetición y nunca se cancela explícitamente. ¿Bajo qué condiciones el sistema Android lo cancela, si es que lo hace? No pude encontrar información relevante. Por ejemplo, ¿está vinculado a la actividad o servicio que lo envió o vive para siempre independientemente? – user1076637

Respuesta

0

resuelvo este problema:

  1. Iniciar un servicio para escuchar el mensaje Intent.ACTION_TIME_TICK. A continuación, envíe una transmisión al widget si el tiempo ha MARCADO. (En cada minuto).

  2. recibir la emisión de widget y juez de tiempo es la medianoche por:

Código:

if (MyWidget.BROADCAST_TIME_TICK.equals(action)) { 
     //If it's midnight, then update. 
     int hour = Calendar.getInstance().get(Calendar.HOUR); 
     int minute = Calendar.getInstance().get(Calendar.MINUTE); 
     Utils.log(TAG, "time is : " + hour+":" + minute); 
     if (!(hour == 0 && minute == 0)) { //Only update at midnight's time tick. 
      return; 
     } else { 
      //Do the midnight stuff. 
     } 
    } 
0

ad esto a su receptor widget de manifiesto

<intent-filter> 
      <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> 
      <action android:name="android.intent.action.DATE_CHANGED" />... 

la cambio en la fecha activará su onReceive() para iniciar con "android.intent.action.DATE_CHANGED" acción

Cuestiones relacionadas