Spanish [SOLUCIONADO] Actualizacion Widget

Edu Portu

Member
Licensed User
Longtime User
He desarrollado un widget, que esta dentro de una aplicacion, la cosa es que al instalar la nueva version el widget muestra los datos correctamente, pero al de un tiempo (cuando se refresca supongo) ya no muestra nada...

Os dejo el codigo que es muy sencillo a ver si veis donde puede estar el error

B4X:
Sub Process_Globals
    'These global variables will be declared once when the application starts.
    'These variables can be accessed from all modules.
    Dim rv As RemoteViews
End Sub

Sub Service_Create
    'Set the widget to update every 60 minutes.
    rv = ConfigureHomeWidget("layoutwidget2", "rv", 60, "SAB Widget (3x1)", True)
End Sub

Sub Service_Start (StartingIntent As Intent)
    If rv.HandleWidgetEvents(StartingIntent) Then Return
    rv_RequestUpdate
End Sub

Sub rv_RequestUpdate

    Dim FechaHoy, FechaRuta As Long

    FechaHoy = DateTime.DateParse(DateTime.Date(DateTime.Now))   
    Dim i As Int
    Dim Datos() As String
    For i = Main.Tabla.Length-1 To 0 Step -1
        Datos=Regex.Split(";",Main.Tabla(i))
        FechaRuta = DateTime.DateParse(Datos(0))
        If FechaRuta = FechaHoy Then
            rv.SetText("Label2", Datos(1))   
        End If
    Next
       
    rv.UpdateWidget
End Sub

Sub rv_Disabled
    StopService("")
End Sub

Sub Service_Destroy

End Sub

"Tabla" es una tabla que tengo definida en el Main de la aplicacion.

Saludos y gracias
Edu
 

Heppy

Active Member
Licensed User
Longtime User
Last edited:

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Edu


Se me adelantó Heppy, la solucion que te ha dado es la correcta, no te actualiza por que no haces nada para que lo haga, simplemente lo actualizas cuando se añade el witget en el escritorio:
B4X:
Sub rv_RequestUpdate
 'Entra cuando se pone el Widgets en el escritorio
y con lo de volver a llamarlo tal como te ha dicho Heppy ya lo tendras, yo añadiria unas cosas para que en el caso de quitar el Witget no siga llamando al servicio:

B4X:
Sub Service_Start (StartingIntent As Intent)

  ' asegurar que el witget no se ha quitado antes de hacer la llamada
  If StartingIntent.Action <> "android.appwidget.action.APPWIDGET_DISABLED" Then
     StartServiceAt("", TimeToNextMinute, False)
   End If


' Si el witget se quitó de la pantalla, cancelar la siguiente llamada y parar el servicio
Sub rv_Disabled
   CancelScheduledService("") 
   StopService("")

Gracias Heppy por hacer referencia a mi tutorial

Saludos
 

Edu Portu

Member
Licensed User
Longtime User
Muchas gracias por las respuestas, pero no se supone que al poner

B4X:
rv = ConfigureHomeWidget("layoutwidget2", "rv", 60, "SAB Widget (3x1)", True)

se llama al RequestUpdate cada 60 minutos?

Saludos y gracias
Edu
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Edu

Perdona, pero no vi que habias puesto un tiempo en esa linea :oops:. Tal como lo tienes configurado tiene que actualizar cada 60 minutos.

Mira que el proceso este activo en el administrador de aplicaciones, y sobre todo cuando falten pocos minutos para que se cumpla la siguiente actualización, Android a veces mata los servicios.
Lo mejor es que pongas logs, y a estos logs le añadas la hora, para saber cuando entra. Y asi podras seguir el proceso y sabras si vuelve a entrar una vez actualizado. Acuerdate que un servicio no lo puedes hacer en debug, de ahi a que pongas logs.

Quita en :
B4X:
Sub Service_Start (StartingIntent AsIntent)
If rv.HandleWidgetEvents(StartingIntent) ThenReturn
rv_RequestUpdate ' QUITA ESTA LINEA

Ya que ademas de entrar en rv_RequestUpdate cuando pones el witget en el escritorio, entrará cuando se cumpla su tiempo de actualización, y si la dejas entrara tres veces, y no se si el resto de tu codigo tiene previsto eso.

Si aun asi no ves por que no actualiza, crea un pequeño proyecto, lo subes y te lo miro cuando tenga un rato, hay que analizar todo, por que has puesto la parte basica, pero seria cuestion de ver al completo el servicio.

Saludos
 

Heppy

Active Member
Licensed User
Longtime User
Perdona Edu.

No me había dado cuenta del ConfigureHomeWidget.

Se supone que si, que deberia actualizarte ya que cuando recibe el Request debería entrar en Service_Start.

Como bien dice bgsoft, sube un proyectillo. Lo único que el tiempo de refresco está limitado a 30 minutos de refresco.
 

bgsoft

Well-Known Member
Licensed User
Longtime User
Hola Edu

Al principio de hacer cosas con servicios tuve muchos problemas, problemas que al final nadie me aclaró y que me los tuve que resolver yo a mi manera. En el tutorial mio de servicios [B4A] [Tutorial] Módulos de Servicio ,http://www.b4x.com/android/forum/threads/b4a-tutorial-módulos-de-servicio.42689/ , planteo algunos de los problemas que tuve.

Como te dije ayer, pon Logs para ver que hace realmente la aplicación. Como habitualmente los servicios los llamas con tiempos muy largos, hacerles un seguimiento en tiempo real es casi imposible, por que no harias otra cosa. Yo cansado de que nadie me diera una solucion y que el comportamiento era totalmente aleatorio, decidí crearme una traza. Cree un sub que lo llamaba desde los sitios que me interesaban; Service_Start, Service_Create, etc, y le pasaba un string, ("Entrada en Create" por ejemplo) este sub cogia la fecha y la hora actual y el texto pasado y añadia una linea a un fichero, de esta forma al dia siguiente podia mirar rapidamente que habia estado haciendo, y si me interesaba borraba el fichero o me lo guardaba para compararlo mas adelante. Luego si ya no queria utilizar esta "traza", simplemente a la entrada del sub ponia un return y no tenia que ir log por log comentandolos , tambien me valia para activarlo con pulsar en el fondo de algo. Antes de esto empleaba una variable que hacia que me escribiera logs dependiendo del valor de dicha variable, pero era mucho mas practico ver un fichero con fechas y horas y que habia echo. La verdad que gracias a esto pude "cazar" los problemas que estaba teniendo con el servicio. Al final esta traza la tengo como una subrutina que me ha ido muy bien para ver que hacen algunas aplicaciones sin tener que estar pendientes de ellas.

Saludos
 

Edu Portu

Member
Licensed User
Longtime User
Muchas gracias a los 2. Voy a intentar lo de los logs...

De todas maneras aqui os dejo el proyectillo. Para simplificarlo he quitado el codigo del programa (excepto la tabla de datos) y he dejado el del widget... lo he dejado tal y como lo tenia, he puesto entre comentarios de momento las instrucciones que me habiais comentado...

Al ejecutarlo sale el dato correcto en el widget, pero al de un tiempo (supongo que seran los 60 minutos de refresco) desaparece la informacion y ya no vuelve a salir ni aunque vuelva a instalar el widget o ejecutar el programa...
 

Attachments

  • Siguealburro.zip
    12.7 KB · Views: 220

Edu Portu

Member
Licensed User
Longtime User
Bueno, he probado a hacer lo que comentateis del log y he dado con el problema (y la solucion).

La tabla de donde saco los datos esta definida en el Main, es decir, en el programa, no en el widget y claro la primera vez que lo ejecutas pues funciona el widget porque el programa esta cargado en memoria... pero claro al de un rato de estar fuera del programa, Android lo elimina de la memoria para liberar espacio y las siguientes actualizaciones del widget no encuentran datos para buscar (en el log me ponia "Recorriendo tabla 40 elementos" la primera vez, y "Recorriendo tabla 0 elementos" las siguientes.

La solucion, aunque un poco chapucera ha sido definir la tabla con los datos tanto en el Main como en el widget... no se me ocurre ninguna solucion mejor para no tener que repetir los datos que no implique sacarlos a un fichero o algo asi...

Muchas gracias a bgsoft y a heppy por su ayuda...
 
Top