Spanish (Resuelto) Servicio en app que funciona en algun dispositivo y en otros no

piramide

Member
Licensed User
Longtime User
Adjunto el codigo:

en el main:

B4X:
#Region  Project Attributes

    #ApplicationLabel: Bomberos

    #VersionCode: 1

    #VersionName:

    'SupportedOrientations possible values: unspecified, landscape or portrait.

    #SupportedOrientations: portrait

    'unspecified

    #CanInstallToExternalStorage: False

#End Region


#Region  Activity Attributes

    #FullScreen: False

    #IncludeTitle: True

#End Region


Sub Process_Globals

    'These global variables will be declared once when the application starts.

    'These variables can be accessed from all modules.

 

    Public SQL1 As SQL

    Public FTP1 As FTP

    Dim List1 As List

 

End Sub


Sub Globals

    'These global variables will be redeclared each time the activity is created.

    'These variables can only be accessed from this module.

 

    Dim Label1 As Label

    Dim Label2 As Label

    Private EditText1 As EditText

    Private EditText2 As EditText

End Sub


Sub Activity_Create(FirstTime As Boolean)

    'Do not forget to load the layout file created with the visual designer. For example:

     Activity.LoadLayout("1")


    File.MakeDir(servicio.DBFilePath,"bomberos")


    If File.Exists(servicio.DBFilePath&servicio.GLOCarpetaLocal, servicio.DBFileName)=False Then


        SQLCreateTable


    End If

  

    EditText1.Text=""

    EditText2.Text=""

 

    List1 = File.ReadList(servicio.DBFilePath&servicio.GLOCarpetaLocal, servicio.DBFileName)

    'Msgbox("List1.Size = " & List1.Size & CRLF & "The third item is: " & List1.Get(2), "")

    EditText1.Text= List1.Get(1)

    EditText2.Text= List1.Get(2)

    servicio.GloSeudonimo = List1.Get(2)

      

    StartService(servicio)


End Sub


Sub Activity_Resume


End Sub


Sub Activity_Pause (UserClosed As Boolean)


End Sub


Sub Button1_Click

    StartService(servicio)

End Sub


Sub Button2_Click

    CancelScheduledService(servicio)  ' Para el  StartServiceAt

    StopService(servicio)

End Sub


Sub muestra

    Label1.Text = servicio.hora

    Label2.Text = servicio.current_min

End Sub


Sub SQLCreateTable


    List1.Initialize

    List1.Add("") 'id del alerta

    List1.Add("") 'id del bombero

    List1.Add("") 'nombre del bombero

    File.WriteList(servicio.DBFilePath&servicio.GLOCarpetaLocal, servicio.DBFileName, List1)


End Sub
 
Last edited:

piramide

Member
Licensed User
Longtime User
este es el servicio:

B4X:
#Region  Service Attributes

 

    #StartAtBoot: True


#End Region


Sub Process_Globals

    'These global variables will be declared once when the application starts.

    'These variables can be accessed from all modules.

  

    Public SQL1 As SQL

    Public FTP1 As FTP

    Dim DBFileName As String                    : DBFileName="bombetxt.txt"

    Dim DBFilePath As String                    : DBFilePath=File.DirInternal

    Public Notif1 As Notification

  

    Public CabeceraEditMode As String

    Public ClienteEditMode As String

    Public ArticuloEditMode As String

    Public SelectedClienteID As String

    Public SelectedClienteNOMBRE As String

    Public SelectedClienteRESP As String

    Public SelectedClientePrec As Int

    Public SelectedArticuloID As String

    Public SelectedArticuloNOMBRE As String

    Public SelectedArticuloUNITARIO As Float

    Public SelectedCabeceraID As Long

    Public SelectedMovimientoID As Long

    Public GLOVendedor As String

    Public GLOPathServidor As String  :GLOPathServidor="https://www.miservidor.com"

    Public GLOIPServidor As String

    Public GLOPuertoServidor As Int

    Public GLOUsuarioServidor As String

    Public GLOClaveServidor As String

    Public GLOCarpetaServidor As String   :GLOCarpetaServidor="bomberos"

    Public GLOCarpetaLocal As String   :GLOCarpetaLocal="/bomberos/"

    Public GLOTxtArt As String  :GLOTxtArt="txtavi.txt"

    Public GLOTxtCli As String

    Public GLOTxtCab As String

    Public GLOTxtMov As String  :GLOTxtMov="tbom.php"

    Public GloTxtVen As String

    Public GloSeudonimo As String

  

  

    Dim cuenta As Int

    cuenta = 0

    Dim hora As String

    Dim N As Notification

  

    Dim current_min, current_dia,current_control,current_actual,current_dif,current_par As Int

    Dim current_hor As Int'String

    Dim gloCelular,gloMensaje As String

    Dim gloTiempo As Int

      

     Type TwoLines (First As String, Second As String)

    Dim List1 As List

  

End Sub


Sub Service_Create 

    'Entra la 1era vez que inicia el servicio

    'Aqui se pueden inicializar los procesos y las variables globales

    'Este se mantiene en marcha hasta que se llame a StopService o se destruya

    'Establecimiento de las Propiedades de Notificación

    N.Initialize

    N.Icon = "icon"

    N.Sound = False

    N.Vibrate = False

    N.Light = False

    N.OnGoingEvent=True

    N.SetInfo("Bomberos", "Activa", Main) 'N.SetInfo("Contador", cuenta, Main)

    N.Notify(1)

    hora = DateTime.Time(DateTime.Now)

End Sub


Sub Service_Start (StartingIntent As Intent)

  

    Dim LocId As String

  

    cuenta = cuenta + 1

  

    hora = DateTime.Time(DateTime.Now)

    current_hor = NumberFormat(DateTime.GetHour(DateTime.Now),2,0)

    current_min = NumberFormat(DateTime.GetMinute(DateTime.Now),2,0)

    current_dia = DateTime.GetDayOfWeek(DateTime.Now) 'dom=7 lun=1 mar=2

  

    current_par = (DateTime.Now/1000)

    current_actual = current_par

            

            Dim j As HttpJob

            j.Initialize("j",Me)

            j.Download(GLOPathServidor&"/"&GLOCarpetaServidor&"/"&GLOTxtArt)

        

            Wait For (j) JobDone(j1 As HttpJob)


        If j1.Success Then

                

                Dim parser As JSONParser

                parser.Initialize(j.GetString)

  

                Dim quotes As List = parser.NextArray

                For Each quot As Map In quotes

                    gloCelular = quot.Get("_id") 'texto

                    gloMensaje = quot.Get("_tipo") 'texto

                    gloTiempo = quot.Get("_tiempo") 'numero

              

                    current_dif = current_actual-gloTiempo

                    Log("dife:"&current_dif)

                If gloCelular <> " " Then

                        Log("row: "&", "&gloCelular&" "&gloMensaje)

                                          

            '    If (current_dif >=0) And (current_dif <10) Then 'si ocurrio el alerta hace 5 segundos

                                        

                        Try

                          

                        LocId=""

                        List1 = File.ReadList(DBFilePath&GLOCarpetaLocal,DBFileName)

                        LocId= List1.Get(0)

                          

                        If LocId = gloCelular Then

                            Log("tiene registro local")

                        Else

                            Log("NO lo tiene") ''"&(quot.Get("_id"))&"'

                                            

                            StartActivity(aviso) 'aqui abro una pantalla como aviso

                          

                                                

                        End If

                                      

                        Catch

                        Log("error")

                            ToastMessageShow("Error: "&LastException, True)

                        End Try

                      

                'End If   'si ocurrio algo hace 5 segundos

                      

                End If 'gloCelular <> " "

      

                Next

              

            Else

                Log("Error: "& j.ErrorMessage)

            End If

          

            j.Release

  

                

    StartServiceAt("", DateTime.Now + 1 * (DateTime.TicksPerSecond * 5), True) 'DateTime.TicksPerSecond

      

    CallSub(Main, "muestra")

    'Service.StopAutomaticForeground 'Call this when the background task completes (if there is one)

End Sub


Sub Service_Destroy

    N.Cancel(1)

End Sub
 
Last edited:

piramide

Member
Licensed User
Longtime User
en el editor manifest tengo esto:

B4X:
AddManifestText(

<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="26"/>

<supports-screens android:largeScreens="true"

    android:normalScreens="true"

    android:smallScreens="true"

    android:anyDensity="true"/>)

SetApplicationAttribute(android:icon, "@drawable/icon")

SetApplicationAttribute(android:label, "$LABEL$")

CreateResourceFromFile(Macro, Themes.LightTheme)

AddPermission(android.permission.MANAGE_DOCUMENTS)

AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)

AddPermission(android.permission.READ_EXTERNAL_STORAGE)
 
Last edited:

piramide

Member
Licensed User
Longtime User
Aclaro que la idea es que cada 5 segundos se comprueba si hay un nuevo txt con datos en el servidor. Si hay un nuevo txt (que en la primer linea tien un numero de id) y lo busco en un txt local. Si el id del txtx del servidor es distinto al id guardado en un txt local, entonces mando un aviso en pantalla que es otro activity con un mensaje.
 

drgottjr

Expert
Licensed User
Longtime User
no se sabe nada de los dispositivos (ej, version de android), ni de cualquier error que se arroje.
y si el servidor es tuyo, perferiría ver algún tipo de "push" que "poll" (sondeo). o sea, cuando hay alguna novedad, el servidor la "empuja". los usuarios que quieren recibir el mensaje, lo recibirán. si no, un montón de usuarios pasan todo el día pidiendo noticias que posiblemente no hay. que se trate de un servicio, da igual. es como si llamaras a tu novia cada 5 segundos para preguntar si ella tiene alguna cosita que decirte. cuando quiere decirte algo, se comunicará contigo.
 

josejad

Expert
Licensed User
Longtime User
Hola piramide:

Aún no me he puesto a mirar tu código. Por favor, edita los mensajes y quita los espacios en los corchetes de [ code] y [/ code] (yo puse los espacios para que se mostrar el texto). O bien en el menú insert (el de los 3 puntos), pulsa en code y pega tu código dentro:
1585942247796.png


Como te digo, aún no he mirado tu código, lo que sí te puedo decir ya por lo que he leído otras veces en el foro, es que Android no te va a dejar iniciar un servicio cada 5 segundos.
O bien tienes que poner esos tiempos bastante más largos (15 minutos?) o bien tienes que dejar un servicio corriendo constantemente, con un temporizado que compruebe cada 5 segundos.

Después, lo que indica drgottjr. Me parece que estar mirando el servidor para ver si hay algo, a menos que las actualizaciones sean muy, pero que muy constantes, es mucha tela.
Sería mejor que implementaras las notificaciones Push (FCM) y que cuando hubiese algún cambio en el servidor, éste notificara a tu app.

saludos,
 

piramide

Member
Licensed User
Longtime User
Gracias x sus respuestas.
Los dispositivos no dan error, de hecho yo muetro un reloj que se actualiza cada 5 segundos y eso funciona. Da la sensacion que no esta funcionando la parte de leer en el server o el acceso a este. (Aclaro que en mi celular y con el b4 bridge la app funciona en modo release). y me funciono tambien en dos celulares mas instalando la apk.
 

piramide

Member
Licensed User
Longtime User
Les cuento que la idea era la siguiente. Un programa hecho en php y colgado en un server al precionar un boton genera un txt con una linea con un id. Entonces la app lee ese archivo txt y encuentra la linea con el id y la app reacciona lanzando un mensaje en pantalla del celular
 

josejad

Expert
Licensed User
Longtime User
Mientras se ejecuta tu servicio, la aplicación está abierta, o cerrada?

De todas formas, de nuevo, creo (al igual que drgottjr) que la forma correcta de hacerlo sería que tu página php al pulsar el botón y generar el txt, lanzara también una notificación push, tu app la recibe y bien mandas ahí la información que quieras (por ejemplo, el id) o lees lo que quieras del servidor.

saludos,
 

Xicu

Active Member
Licensed User
Longtime User
Si la informacion a actualizar es tan critica que precisas que la aplicación se actualice de forma inmediata, la mejor opción es utilizar firebase como indica @drgottjr y @José J. Aguilar. Pero tendras que investigar como enviar la notificaciónes push desde tu aplicación PHP, habilitar firebase en tu app, y configurar tu proyecto/aplicación en el servidor firebase.
En cambio, si la información no es tan crítica y puede esperar 10 a 15 min., puedes utilizar peticiones pull como hacías. La ventaja que tendras es que no precisaras aprender nuevas tecnologias y no dependeras del servidor firebase.
Menos tiempo, como ya te han indicado no te funcionara en la app. Además estas generando un bombardeo de peticiones innecesarias al servidor, que si además es tuyo (no contratado) tendrás problemas de rendimiento.
 

drgottjr

Expert
Licensed User
Longtime User
he mencionado push porque me parecía idóneo para la tarea, sabiendo que aprender una nueva tecnología no es siempre fácil. pero si hemos de quedarnos con el servicio y okhttp, ¿qué podríamos hacer asegurar lo más posible el funcionamiento? cada 5 segundos es mucho.

otras soluciones - y hay varias - requiren nueva tecnología (udp en lugar de okhttp, websockets, fcm). tambien existe (o existía) broadcast. se evita (o evitaba) las muchas conexiones que requieren okhttp. http (incluso tcp) no fue hecho para conectar/disconectar cada 5 segundos. por eso se inventan nuevas tecnologías: http 1.0 no mantenía la conexión ----> http 1.1 sí la mantenía ---> websockets presenta una conexión duradera ---> etc.
 

piramide

Member
Licensed User
Longtime User
Mientras se ejecuta el servicio por lo general la app esta cerrada. Y el servicio deberia estar corriendo.
Voy a ver si cambio esto por las notificaciones push.
Luego comento aqui como me fue.
Gracias x sus respuestas Jose , Xicu y drgottjr. Saludos.
 

piramide

Member
Licensed User
Longtime User
Hola a todos, lo resolvi enviando la notificacion desde mi sitio web tomando como ejemplo lo que detalla en un hilo Douglas Farias (lo pueden ver aqui -> https://www.b4x.com/android/forum/threads/send-firebase-notification-via-php-curl.98339/)
Y en el cuerpo de la notificacion envio los datos que necesita la app instalada el smartphone , al momento de recibir la notificacion ejecuto un activity el cual manda un dato a una base de datos en el servidor. Esto ultimo con los ejemplos de erel de MySql y lo del post donde responde Jose Mujico -> https://www.b4x.com/android/forum/threads/consultar-bases-de-datos-mysql.29163/
Por este lado voy a dar x resuelta mi consulta.
Gracias a todos, me sirvio mucho sus consejos
NOTA: ahora me falta resolver el porque en algunos telefonos al recibir la notificacion no abren el activity que deberian abrir.
 
Top