Android Question basic notification doesn't work when the app is background

Baris Karadeniz

Active Member
Licensed User
I use standart notification. It works when the app is foreground. But it doesn't work when the app is background. What should I do?

B4X:
Sub Process_Globals
     Dim n As Notification
End Sub

Sub Activity_Create(FirstTime As Boolean)
n.Initialize
End Sub

Sub JobDone (Job As HttpJob)
  Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
  If Job.Success = True Then
      Select Job.JobName
        Case "Job1"
            'print the result to the logs
            'Log(Job.GetString)
        Case "Job2"
            'print the result to the log
             Log(Job.GetString)
             If Job.GetString > 0 Then    
             n.SetInfo(warningtitle1, AlertMessage, Me)
             n.Icon = "icon"
             n.Notify(1)
             End If
        Case "Job3"
            'print the result to the logs
            'Log(Job.GetString)
      End Select
  Else
      Log("Error: " & Job.ErrorMessage)
  End If
  Job.Release
End Sub
 

DonManfred

Expert
Licensed User
Longtime User
httputils can run in a service
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
I moved process global "Dim n As Notification" at the codes above to the Process_Globals in the Starter service module. It says that "These global variables will be declared once when the application starts. These variables can be accessed from all modules." there.

But there are red logs and it says; "Undeclared variable 'n' is used before it was assigned any value" for the codes remains at Main. So I understand that, I need to move all codes related to n to the Starter Serice module. But why it says; "These global variables will be declared once when the application starts. These variables can be accessed from all modules." ? As I see, other modules can not reach to these variables.
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Did you recall to reference n as "myservice.n" in Main?

Anyway, you should move any code relating to the notification to the service.
Regarding post #3, when your Main is foreground and a JobDone is executed, you can call a sub in the service that prepares and send the notification.

udg
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Baris,

I meant altering your code in Main from n.setinfo() to Myservice.n.setinfo().
As explained by NJDude and DonManfred, you should move the whole notification strategy to your service.
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
Ok. It is understood well. In the notification codes there are something like "warning title" and "alertmessage". They are Dim As String in Main. So I will move them also because they are written at the notification codes. But the problem is they are used in other places in the Main too. Do I need to move all codes related to these strings too?

B4X:
 n.SetInfo(warningtitle1, AlertMessage, Me)
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Baris, sorry for the delay.
I would dim those strings in service too. Then to use them in Main just preprend "Main." to the items like in "Main.warningtitle1" while in service you use just their "pure" name like warningtitle1="Warning!!!"
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
Thanks udg. Is it same also for panels, buttons? Anw where should I write "Main.xxx" in service module? into the Process Globals at the service module?
 
Upvote 0

DonManfred

Expert
Licensed User
Longtime User
Upvote 0

udg

Expert
Licensed User
Longtime User
'service module named MyService
B4X:
Sub Process_Globals
  Dim warningtitle1 as String
  ...
End Sub

Sub Mysub1
warningtitle1 = "Warning!!"

'Main
B4X:
...
MyService.warningtitle1 = "Warning 2"
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
Service module runs when the app is at background only or at foreground too? I send information to the server. This information should go at the foreground and at the background. In this case should I write codes only in service module or to the Main also? Or will I write codes to the service module and call at the Main?
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
I moved notification, gps and httpjob codes to the service starter module. There is a timer at the main module. If timer is enabled at the main module service starter codes work. At the foreground it is ok but at the background, service starter codes doesn't work still. Is this because timer is enabled at the main? How can I provide service codes works at the background? Where should I start timer?

Service Starter codes;

B4X:
#Region  Service Attributes
    #StartAtBoot: False
    #ExcludeFromLibrary: 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.
     Dim GPS1 As GPS
     Dim n As Notification
     Dim GPS As Boolean
     Dim GPS2 As String
     Dim Latitude As String
     Dim Longitude As String
     Dim Speed As String
     Dim Accuracy As String
     Dim Altitude As String
     Dim Heading As String
     Dim Time As String
     Dim lblSatellite As String
End Sub

Sub Service_Create
    'This is the program entry point.
    'This is a good place to load resources that are not specific to a single activity.
   
    GPS1.Initialize("GPS")
    n.Initialize
End Sub

Sub Service_Start (StartingIntent As Intent)
    If GPS1.GPSEnabled = False Then
        GPS = False
        GPS2 = "gpsno"
    Else
        GPS1.Start(0, 0) 'Listen to GPS with no filters.
        GPS = True
        GPS2 = "gpsok"
        ServerJobs
    End If
End Sub

'Return true to allow the OS default exceptions handler to handle the uncaught exception.
Sub Application_Error (Error As Exception, StackTrace As String) As Boolean
    Return True
End Sub

Sub Service_Destroy

End Sub

Sub GPS_LocationChanged (Location1 As Location)
    Latitude = NumberFormat(Location1.Latitude, 2, 6)
    Longitude = NumberFormat(Location1.Longitude, 2, 6)
    Speed = NumberFormat(Location1.Speed, 1,0)
    Accuracy = NumberFormat(Location1.Accuracy, 1, 0)
    Altitude = NumberFormat(Location1.Altitude, 1, 1)
    Heading = NumberFormat(Location1.Bearing, 1, 0)
    DateTime.DateFormat = "yyyy-MM-dd"
    DateTime.TimeFormat = "HH:mm:ss"
    Time = DateTime.Date(Location1.Time) & " " & DateTime.Time(Location1.Time)
End Sub

Sub GPS_UserEnabled (Enabled As Boolean)
   
End Sub

Sub GPS_GpsStatus (Satellites As List)
    lblSatellite = "Satellites:" & CRLF
    For i = 0 To Satellites.Size - 1
        Dim Satellite As GPSSatellite
        Satellite = Satellites.Get(i)
        lblSatellite = lblSatellite & CRLF & Satellite.Prn & _
            " " & Satellite.Snr & " " & Satellite.UsedInFix & " " & Satellite.Azimuth _
            & " " & Satellite.Elevation
    Next
End Sub

Sub ServerJobs
    Dim Job1 As HttpJob
      Job1.Initialize("MyJob", Me)
      Job1.Download2("http://www.taksi-m.com.tr/track/server/http/android.php", Array As String("op", GPS2, "imei", Main.imeiService, "dt", Time, "lat", Latitude, "lng", Longitude, "altitude", Altitude, "angle", Heading, "speed", Speed, "params", Main.occupiedService, "event", Main.EventService))
      Main.EventService = ""
    Dim Job2 As HttpJob
       Job2.Initialize("Job2", Me)
       Job2.Download2("http://www.taksi-m.com.tr/track/server/s_service.php", Array As String("op", "chat_new_messages", "imei", Main.imeiService))
End Sub

Sub JobDone (Job As HttpJob)
  Log("JobName = " & Job.JobName & ", Success = " & Job.Success)
  If Job.Success = True Then
      Select Job.JobName
        Case "Job1"
            'print the result to the logs
            'Log(Job.GetString)
        Case "Job2"
            'print the result to the log
             Log(Job.GetString)
             If Job.GetString > 0 Then   
             n.Icon = "icon"
             n.SetInfo(Main.warningtitle1, Main.AlertMessage, Me)
             n.Notify(1)
             End If
        Case "Job3"
            'print the result to the logs
            'Log(Job.GetString)
      End Select
  Else
      Log("Error: " & Job.ErrorMessage)
  End If
  Job.Release
End Sub


Main codes;

B4X:
Sub Process_Globals

     Public Timer1 As Timer
End Sub

Sub Activity_Create(FirstTime As Boolean)

    Timer1.Initialize("Timer1", 5000)

End Sub

Sub BtnSystemOnOff_CheckedChange(Checked As Boolean)
    If TextFieldimei.Text.Length = 15 Then
    If BtnSystemOnOff.Checked = True Then    
    BtnSystemOnOff.Color = Colors.Green
    Timer1.Enabled=True
    Event = ""
    Else
    BtnSystemOnOff.Color = Colors.Red
    Timer1.Enabled=False
    End If
    Else
    Msgbox(warning1, warningtitle1)
    End If
End Sub

Sub Timer1_Tick
    StartService(Starter)
    lblLongitude.Text = Starter.Longitude
    lblLatitude.Text = Starter.Latitude
    lblAltitude.Text = Starter.Altitude
    lblAccuracy.Text = Starter.Accuracy
    lblHeading.Text = Starter.Heading
    lblSpeed.Text = Starter.Speed
    lblTime.Text = Starter.Time
End Sub
 
Upvote 0

udg

Expert
Licensed User
Longtime User
Hi Baris,
I'm experiencing some hard time to fully understand your goal, so please don't be disappointed if I missed it..
Seems to me that you'd like to call a "service" every 5 secs in order to read GPS data and call web services that, if succesful, should start a notification.
If I am correct, you don't need and shouldn't use any timer in Main.
Instead, define in Main a sub specialized in showing the needed GPS data, then when (and if) you receive a new reading from the GPS function in service (LocationChanged) terminate it with a CallSubDelay to the specialized function you wrote in main; this way updated data are displayed once Main gets awaken.
BTW, do you really need to start GPS with (0,0) parameters? That will drain your device's battery very quickly.

Now, for the ServerJobs function. Is data from the website that you have to read every 5 secs? In that case, put the httpjob stuff in a second service, and continously restart it with StartServiceAt (.., interval in milliseconds).
BTW, are you sure that HttpJobs will be completely handled in 5 secs? Website will accept to be called so many times in a so short time span?

Again, sorry if I didn't understand correctly your project. Eventually share with us your goals and surely you'll get more correct and valuable hints and directions.

Have a nice weekend.

udg
ps: have a look to CallSubPlus for another useful tool
 
Upvote 0

Baris Karadeniz

Active Member
Licensed User
Dear UDG, first of all thank you very much for your kindness and wasting time for my problem. After #18 I wrote that the problem is solved but I think there happen a problem and it was not posted. I just solved it 3 hours ago. But I read n,ce things in your post.

I was thinking that one time calling service would be enough. But after searching more and more, I found the code line below to use in Service_Start;

B4X:
StartServiceAt("", DateTime.Now + 5 * DateTime.TicksPerSecond, True)

Now I start service from Main and it works good at he foreground and at the background. I can stop it also.

Yes, I send datas to the server every 5 seconds and it works good. There is no problem with the server. You are right, if the location doesn't changes no need to send. I should improve codes. Which parameter can I get when the location is changed? Should I compare the gps datas? If I know this parameter I can send datas to the server when the location is changed. But there is a limitation in the server; it is 1 minute. If server can not receive gps parameters more than 1 minute it turns off the object.

I use timer in the Main to refresh GPS datas in the view. Is there any other way to refresh the datas in the view?

I just looked to the parameters of the GPS. You are right 0,0 is very high. May be 5,5 is better if I use location changes?


Best regards
 
Upvote 0
Top