Android Question Only getting notifications if the program is active on the screen

Tim Chapman

Active Member
Licensed User
Longtime User
Notifications do not occur unless the app is open in the foreground.
I have researched the forum and can't find a fix for this.

Thanks again for the assistance!

Tracker service:
#Region  Service Attributes
    #StartAtBoot: True
#End Region

Sub Process_Globals
    'Private nid As Int = 1
    Private GPS As GPS
    Private Tracking As Boolean
    Private LastUpdateTime As Long
    Private lock As PhoneWakeState
    Private Distance As Double
    Private UserWasNotified As Boolean = False
End Sub

Sub Service_Create
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER 'we are handling it ourselves
    GPS.Initialize("gps")
    lock.PartialLock
End Sub

Sub Service_Start (StartingIntent As Intent)
    'Service.StartForeground(nid, CreateNotification("..."))
    Track
End Sub

Public Sub Track
    'Sleep(0)
    If Tracking Then Return
    If Starter.rp.Check(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION) = False Then
        Log("No permission")
        Return
    End If
    GPS.Start(0, 0)
    Tracking = True
End Sub

Sub GPS_LocationChanged (Location1 As Location)
    If DateTime.Now > LastUpdateTime + 10 * DateTime.TicksPerSecond Then
        LastUpdateTime = DateTime.Now
        CheckDistance (Location1)
    End If
End Sub

Sub Service_Destroy
    If Tracking Then
        GPS.Stop
    End If
    Tracking = False
    lock.ReleasePartialLock
End Sub

Sub CheckDistance(Location1 As Location)
    Dim Location2 As Location
    Dim TrueCount As Byte = 0
    'Dim b As Beeper
    Public n As Notification = CreateNotification("Tap to Proceed.") 'This immediately calls the CreateNotification sub.
    'b.Initialize(300, 500) 'Initialize (Duration As Int, Frequency As Int)

    For Each TempContext As Context In Main.Contexts
        'Calculate distances to each context (location) that has a lat/lon.
        If TempContext.Latitude <> 0 Then 'Some contexts have no lat or lon.  Can't use them.
            'Find the distance from each context to the phone.
            Location2.Initialize2(TempContext.Latitude,TempContext.Longitude)
            Distance =  Location1.DistanceTo(Location2) * .00062137 'miles.
            Distance = Round2(Distance, 2)
            'ToastMessageShow (Main.Contexts(X,0)&": " & Distance & " miles.", True)
           
            'Check to see if the distance to the context is within the specifed distance to be considered "close".
            'Make a map of those that are close.
            If Distance < TempContext.Distance Then 'Context is Close.
                TempContext.Close = True
                'Log("Close Context = "&Main.Contexts(x,0))
                TrueCount = TrueCount + 1
                'ToastMessageShow("Close to " & Main.Contexts(x,0),True)
            Else 'Context is not close.
                TempContext.Close = False 'Clear close contexts from Context array.
                TempContext.Show = False 'Clear desired contexts from Context array.
            End If
        End If
        Main.Contexts.Set(Main.Contexts.IndexOf(TempContext),TempContext)
    Next
    If TrueCount > 0 Then 'Some of the contexts are close.
        Main.Close = True
        Log("MenuBuilt = "&Main.MenuBuilt)
        If Main.MenuBuilt = False Then
            CallSubDelayed(Main,"BuildMenuMap")
            Main.MenuBuilt = True
        End If
        If UserWasNotified = False Then
            'b.Beep  'Play a sound and show a message to let the user know.  A notification will also be raised in the Main activity.
            n.Notify(1)
            UserWasNotified = True
        End If
    Else
        Main.Close = False
        UserWasNotified = False
        n.Cancel(1)
    End If
    'Log("TrueCount = "&TrueCount)
    'Log("Close = "&Main.Close)
End Sub

Sub CreateNotification (Body As String) As Notification
    Log("CreateNotification sub started")
    Private notification As Notification
    notification.Initialize2(notification.IMPORTANCE_DEFAULT)
    notification.Icon = "icon"
    notification.AutoCancel = True 'This makes the notification go away when it is clicked on.
    notification.Sound = True
    notification.SetInfo("Contexts Nearby", Body, ShowMenuFlag)
    Log("CreateNotification sub done")
    Return notification
End Sub
 

Attachments

  • TimTodo.zip
    284.1 KB · Views: 20
Last edited:

Tim Chapman

Active Member
Licensed User
Longtime User
Yes. It works. It has a notification up constantly. I am trying to make one appear when close to selected locations and clear when not close to any selected locations.
Since the Tracker is supposed to run in the background, should I make it not reference any variables from the Main module?
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
You need to have a foreground service which means that there should be an ongoing notification.

Since the Tracker is supposed to run in the background, should I make it not reference any variables from the Main module?
Best to switch to B4XPages and then you will be able to access all modules, assuming that the service was started after the main page appeared.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
If you have an existing large app then it can require some work.
I recommend you to start with the B4XPages example to understand how it works:
 
Upvote 0

Tim Chapman

Active Member
Licensed User
Longtime User
Thank you for the replies.
I got a compromise to work with the code below.
A notification with sound occurs when the phone moves close to a designated location.
A notification with no sound occurs when the phone moves away from a designated location.
It seems that cancelling the notification to make it go away completely won't work.
I had to guess at Integer values for the Importance. If those numbers are available for the 4 levels of importance, I would love to have them and to know how to get them would be a plus.

Tracker module:
#Region  Service Attributes
    #StartAtBoot: True
#End Region

Sub Process_Globals
    'Private nid As Int = 1
    Private GPS As GPS
    Private Tracking As Boolean
    Private LastUpdateTime As Long
    Private lock As PhoneWakeState
    Private Distance As Double
    Private UserWasNotified As Boolean = False
    Public Close As Boolean
End Sub

Sub Service_Create
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_NEVER 'we are handling it ourselves
    GPS.Initialize("gps")
    lock.PartialLock
End Sub

Sub Service_Start (StartingIntent As Intent)
    'Service.StartForeground(0, Null)
    Service.StartForeground(1, CreateNotification("","",0))
    Track
End Sub

Public Sub Track
    'Sleep(0)
    If Tracking Then Return
    If Starter.rp.Check(Starter.rp.PERMISSION_ACCESS_FINE_LOCATION) = False Then
        Log("No permission")
        Return
    End If
    GPS.Start(0, 0)
    Tracking = True
End Sub

Sub GPS_LocationChanged (Location1 As Location)
    If DateTime.Now > LastUpdateTime + 10 * DateTime.TicksPerSecond Then
        LastUpdateTime = DateTime.Now
        CheckDistance (Location1)
    End If
End Sub

Sub Service_Destroy
    If Tracking Then
        GPS.Stop
    End If
    Tracking = False
    lock.ReleasePartialLock
End Sub

Sub CheckDistance(Location1 As Location)
    Dim Location2 As Location
    Dim TrueCount As Byte = 0
  
    For Each TempContext As Context In Main.Contexts
        'Calculate distances to each context (location) that has a lat/lon.
        If TempContext.Latitude <> 0 Then 'Some contexts have no lat or lon.  Can't use them.
            'Find the distance from each context to the phone.
            Location2.Initialize2(TempContext.Latitude,TempContext.Longitude)
            Distance =  Location1.DistanceTo(Location2) * .00062137 'miles.
            Distance = Round2(Distance, 2)
            'ToastMessageShow (Main.Contexts(X,0)&": " & Distance & " miles.", True)
          
            'Check to see if the distance to the context is within the specifed distance to be considered "close".
            'Make a map of those that are close.
            If Distance < TempContext.Distance Then 'Context is Close.
                TempContext.Close = True
                'Log("Close Context = "&Main.Contexts(x,0))
                TrueCount = TrueCount + 1
                'ToastMessageShow("Close to " & Main.Contexts(x,0),True)
            Else 'Context is not close.
                TempContext.Close = False 'Clear close contexts from Context array.
                TempContext.Show = False 'Clear desired contexts from Context array.
            End If
        End If
        Main.Contexts.Set(Main.Contexts.IndexOf(TempContext),TempContext)
    Next
    If TrueCount > 0 Then 'Some of the contexts are close.
        Log("**Close = True")
        Close = True
        Log("MenuBuilt = "&Main.MenuBuilt)
        If Main.MenuBuilt = False Then
            CallSubDelayed(Main,"BuildMenuMap")
            Main.MenuBuilt = True
        End If
        If UserWasNotified = False Then
            Dim n As Notification = CreateNotification("Contexts Nearby","Tap to Proceed.",3)
            n.Notify(1)
            UserWasNotified = True
        End If
    Else
        Log("**Close = False")
        Close = False
        UserWasNotified = False
        Dim n As Notification = CreateNotification("No Contexts Near","",0)
        n.Notify(1)
    End If
    'Log("TrueCount = "&TrueCount)
    'Log("Close = "&Main.Close)
End Sub

Sub CreateNotification (Title As String, Body As String, Importance As Int) As Notification
    Log("CreateNotification sub started")
    Public notification As Notification
    notification.Initialize2(Importance)
    notification.Icon = "icon"
    notification.AutoCancel = True 'This makes the notification go away when it is clicked on.
    notification.Sound = True
    notification.SetInfo(Title, Body, ShowMenuFlag)
    Log("CreateNotification sub done")
    Return notification
End Sub
 
Last edited:
Upvote 0
Top