Android Question Error with Service since moving to android:targetSdkVersion 34

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Moved to SDK version 34 and now get this error when I load in a B4XPages project my OSM map.
It has to do with a Tracker service to keep uninterrupted GPS tracking when using the map.
With SDK 33 all was fine.

This is the full error message:

'------------------------------------------------------------------------------------
cvMap1_ready
*** Service (tracker) Create ***
** Service (tracker) Start **
java.lang.RuntimeException: Unable to start service b4a.exampleljjll.tracker@8f17268 with Intent { cmp=b4a.exampleljjll/.tracker }: java.lang.RuntimeException: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5371)
at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2539)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:9063)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.RuntimeException: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.handleStartIntent(ServiceHelper.java:173)
at b4a.exampleljjll.tracker.handleStart(tracker.java:102)
at b4a.exampleljjll.tracker.access$000(tracker.java:8)
at b4a.exampleljjll.tracker$1.run(tracker.java:74)
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.onStartCommand(ServiceHelper.java:240)
at b4a.exampleljjll.tracker.onStartCommand(tracker.java:72)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5353)
... 9 more
Caused by: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:53)
at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:49)
at android.os.Parcel.readParcelableInternal(Parcel.java:4882)
at android.os.Parcel.readParcelable(Parcel.java:4864)
at android.os.Parcel.createExceptionOrNull(Parcel.java:3064)
at android.os.Parcel.createException(Parcel.java:3053)
at android.os.Parcel.readException(Parcel.java:3036)
at android.os.Parcel.readException(Parcel.java:2978)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:7248)
at android.app.Service.startForeground(Service.java:775)
at anywheresoftware.b4a.objects.ServiceHelper.StartForeground(ServiceHelper.java:85)
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.handleStartIntent(ServiceHelper.java:171)
... 15 more
'-------------------------------------------------------------------------------------

This is the code in the Tracker service:

B4X:
#Region  Service Attributes 
    #StartAtBoot: False
#End Region

Sub Process_Globals
    
    Public bTrackerRunning As Boolean
    Public bNoTracking As Boolean
    
    Public Fused As FusedLocationProviderClient
    
    Public GNSS1 As GNSS
    Private lock As PhoneWakeState

    Public lCurrentTime As Long
    Public dCurrentLatitude As Double
    Public dCurrentLongitude As Double
    Public iCurrentAltitude As Int
    Public iSatellitesCount As Int
    Public iSatellitesUsed As Int
    
    Public arrTileLimits(,) As Int
    Public arrZoomLevels() As String
    Public iProgressInterval As Int
    Public iTilesToDownLoad As Int
    Public iTilesProcessed As Int
    Public iTilesSavedToDB As Int
    Public lstFailedDownloads As List
    Public lstFailedDBSaves As List
    Public bDownLoadFinished As Boolean
    
End Sub

Sub Service_Create
    
    'Log("Tracker, Service_Create")
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_ALWAYS 'we are handling it ourselves(?)
    
    GNSS1.Initialize("GNSS1") 'always initialize this, so we can have the satellites status
    
    If Enums.bUseFusedLocationProviderToRecordJourney Then
        Fused.Initialize("FusedLocation")
    End If
    
End Sub

Sub Service_Start(StartingIntent As Intent)
    
    'this will run about every 5 seconds when GPS is on
    '--------------------------------------------------
    'Log("Tracker, Service_Start, at: " & General.Ticks2String(DateTime.Now, "HH:mm:ss", False))
    
    StartServiceAt(Me, DateTime.Now + 100, True) 'start after 0.1 second
    
End Sub

Public Sub Track
    
    'Log("Tracker, Track, GNSS1.IsInitialized: " & GNSS1.IsInitialized & ", Fused.IsInitialized: " & Fused.IsInitialized)
    
    lock.KeepAlive(False)
    
    If Enums.bUseFusedLocationProviderToRecordJourney Then
        DefineFused
    Else
        GNSS1.Start(0, 0)
    End If
    
    bTrackerRunning = True
    
    'Log("Tracker started")
    
End Sub

Public Sub StopTracker
    
    If GNSS1.IsInitialized Then
        GNSS1.Stop
    End If
    
    If Fused.IsInitialized Then
        Fused.RemoveLocationUpdates
    End If
    
    lock.ReleaseKeepAlive
    CancelScheduledService(Me)
    Service.StopForeground(1)
    StopService (Me)
    
    bTrackerRunning = False
    
End Sub

Private Sub DefineFused
    
    If Fused.IsLocationEnabledInSettings Then
        Fused.GetLocationAvailability
        Wait For FusedLocation_LocationAvailabilityRequestCompleted (Available As Boolean)
        'Log("LocationAvailable=" & Available)
        If Available Then
            Fused.GetLastLocation
            Wait For FusedLocation_LocationRequestCompleted (Result As LocationResult)
            If Result.Status = LocationResult.STATUS_SUCCESSFUL Then
                If Result.Location.IsInitialized Then
                    Dim LastLocation As LocationF = Result.Location 'ignore
                    'Log("LastLocation Latitude = " & LastLocation.Latitude)
                    'Log("LastLocation Longitude = " & LastLocation.Longitude)
                    'Do whatever you want with other LocatioF properties and methods
                Else
                    Log("Unknown last location")
                End If
            End If
        End If
    
        'Initiate FusedLocation's LocationRequest which will allow events to be fired and it will continue to work in background
        Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize(1000) 'Refresh interval is 1000 miliseconds
        LocationRequest1.SetMinUpdateIntervalMillis(100) 'Minimum refresh interval is 100 miliseconds
        LocationRequest1.SetPriority(Priority.PRIORITY_HIGH_ACCURACY) 'Request high accuracy location
        LocationRequest1.SetMinUpdateDistanceMeters(0) 'Minimum distance in meters to fire location change event (0 is default)
        LocationRequest1.SetGranularity(Granularity.GRANULARITY_FINE)
        Fused.RequestLocationUpdates(LocationRequest1) 'Set location request to FusedLocationProviderClient and start FusedLocation
    Else
        MsgboxAsync("Location is turned off in devices's settings. Turn it on.","Warning")
        StartActivity(Fused.LocationSettingsIntent)
    End If
    
End Sub


'to get the satellite count when we are running Fused and not GNSS1
'------------------------------------------------------------------
Public Sub Start_GNSS1
    
    'as then this will run continuously when the map page shows
    '----------------------------------------------------------
    If Enums.bUseFusedLocationProviderToRecordJourney = False Then Return
    
    GNSS1.Start(0, 0)
    
End Sub

Public Sub StopGNSS1
    
    GNSS1.Stop
    
End Sub

Sub GNSS1_GNSSStatus(Status As GnssStatus)
    
    Dim i As Int
    
    'Log("GNSS1_GNSSStatus, Status.SatelliteCount: " & Status.SatelliteCount)
    'Log("GNSS1_GNSSStatus, bNoTracking: " & bNoTracking)
    
    If bNoTracking Then
        Return
    End If
    
    'Sleep(20)
    
    iSatellitesCount = Status.SatelliteCount
    iSatellitesUsed = 0
    
    'Sleep(20)
    
    'Log("GNSS1_GNSSStatus, iSatellitesCount: " & iSatellitesCount)
    
    For i = 0 To Status.SatelliteCount - 1
        If Status.UsedInFix(i) Then
            iSatellitesUsed = iSatellitesUsed + 1
            Sleep(0)
        End If
    Next
    
    'Log("GNSS1_GNSSStatus, iSatellitesUsed: " & iSatellitesUsed)
    
End Sub

Sub GNSS1_LocationChanged(Location1 As Location)
    
    If Enums.bUseFusedLocationProviderToRecordJourney Or bNoTracking Then Return
    
    lCurrentTime = DateTime.Now / 1000
    dCurrentLatitude = Location1.Latitude
    dCurrentLongitude = Location1.Longitude
    iCurrentAltitude = Location1.Altitude
    
End Sub

Private Sub FusedLocation_LocationChanged (mLocation As LocationF)
    
    'This event will be fired anytime your actual location is changed and if it meets the criteria of the defined LocationRequest
    'Log("Lat=" & mLocation.Latitude & CRLF & "Lng=" & mLocation.Longitude)
    
    If Enums.bUseFusedLocationProviderToRecordJourney = False Or bNoTracking Then Return
    
    lCurrentTime = DateTime.Now / 1000
    dCurrentLatitude = mLocation.Latitude
    dCurrentLongitude = mLocation.Longitude
    iCurrentAltitude = mLocation.Altitude
    
End Sub

Sub Service_Destroy
    StopTracker
End Sub

And this is the text of may manifest:

'-----------------------------------------------------------
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="34"/>
<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)
'End of default text.
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE)

'added 31/01/2025


SetActivityAttribute(main, android:windowSoftInputMode, adjustResize|stateHidden)

'SetApplicationAttribute(android:largeHeap,"true")

AddApplicationText(<meta-data android:name="com.google.android.gms.version" android:value="@Integer/google_play_services_version" />)

SetApplicationAttribute(android:icon, "@mipmap/ic_launcher")
CreateResource(mipmap-anydpi-v26, ic_launcher.xml,
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/background"/>
<foreground android:drawable="@mipmap/foreground"/>
</adaptive-icon>
)
'-----------------------------------------------------------

From some research in the questions group I understand I need to add something to my manifest, but no idea what exactly that should be.
Any advice appreciated.

RBS
 

RB Smissaert

Well-Known Member
Licensed User
Longtime User
Moved to SDK version 34 and now get this error when I load in a B4XPages project my OSM map.
It has to do with a Tracker service to keep uninterrupted GPS tracking when using the map.
With SDK 33 all was fine.

This is the full error message:

'------------------------------------------------------------------------------------
cvMap1_ready
*** Service (tracker) Create ***
** Service (tracker) Start **
java.lang.RuntimeException: Unable to start service b4a.exampleljjll.tracker@8f17268 with Intent { cmp=b4a.exampleljjll/.tracker }: java.lang.RuntimeException: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5371)
at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2539)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:230)
at android.os.Looper.loop(Looper.java:319)
at android.app.ActivityThread.main(ActivityThread.java:9063)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:588)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1103)
Caused by: java.lang.RuntimeException: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.handleStartIntent(ServiceHelper.java:173)
at b4a.exampleljjll.tracker.handleStart(tracker.java:102)
at b4a.exampleljjll.tracker.access$000(tracker.java:8)
at b4a.exampleljjll.tracker$1.run(tracker.java:74)
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.onStartCommand(ServiceHelper.java:240)
at b4a.exampleljjll.tracker.onStartCommand(tracker.java:72)
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5353)
... 9 more
Caused by: android.app.MissingForegroundServiceTypeException: Starting FGS without a type callerApp=ProcessRecord{f436782 19757:b4a.exampleljjll/u0a416} targetSDK=34
at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:53)
at android.app.MissingForegroundServiceTypeException$1.createFromParcel(MissingForegroundServiceTypeException.java:49)
at android.os.Parcel.readParcelableInternal(Parcel.java:4882)
at android.os.Parcel.readParcelable(Parcel.java:4864)
at android.os.Parcel.createExceptionOrNull(Parcel.java:3064)
at android.os.Parcel.createException(Parcel.java:3053)
at android.os.Parcel.readException(Parcel.java:3036)
at android.os.Parcel.readException(Parcel.java:2978)
at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:7248)
at android.app.Service.startForeground(Service.java:775)
at anywheresoftware.b4a.objects.ServiceHelper.StartForeground(ServiceHelper.java:85)
at anywheresoftware.b4a.objects.ServiceHelper$StarterHelper.handleStartIntent(ServiceHelper.java:171)
... 15 more
'-------------------------------------------------------------------------------------

This is the code in the Tracker service:

B4X:
#Region  Service Attributes
    #StartAtBoot: False
#End Region

Sub Process_Globals
   
    Public bTrackerRunning As Boolean
    Public bNoTracking As Boolean
   
    Public Fused As FusedLocationProviderClient
   
    Public GNSS1 As GNSS
    Private lock As PhoneWakeState

    Public lCurrentTime As Long
    Public dCurrentLatitude As Double
    Public dCurrentLongitude As Double
    Public iCurrentAltitude As Int
    Public iSatellitesCount As Int
    Public iSatellitesUsed As Int
   
    Public arrTileLimits(,) As Int
    Public arrZoomLevels() As String
    Public iProgressInterval As Int
    Public iTilesToDownLoad As Int
    Public iTilesProcessed As Int
    Public iTilesSavedToDB As Int
    Public lstFailedDownloads As List
    Public lstFailedDBSaves As List
    Public bDownLoadFinished As Boolean
   
End Sub

Sub Service_Create
   
    'Log("Tracker, Service_Create")
    Service.AutomaticForegroundMode = Service.AUTOMATIC_FOREGROUND_ALWAYS 'we are handling it ourselves(?)
   
    GNSS1.Initialize("GNSS1") 'always initialize this, so we can have the satellites status
   
    If Enums.bUseFusedLocationProviderToRecordJourney Then
        Fused.Initialize("FusedLocation")
    End If
   
End Sub

Sub Service_Start(StartingIntent As Intent)
   
    'this will run about every 5 seconds when GPS is on
    '--------------------------------------------------
    'Log("Tracker, Service_Start, at: " & General.Ticks2String(DateTime.Now, "HH:mm:ss", False))
   
    StartServiceAt(Me, DateTime.Now + 100, True) 'start after 0.1 second
   
End Sub

Public Sub Track
   
    'Log("Tracker, Track, GNSS1.IsInitialized: " & GNSS1.IsInitialized & ", Fused.IsInitialized: " & Fused.IsInitialized)
   
    lock.KeepAlive(False)
   
    If Enums.bUseFusedLocationProviderToRecordJourney Then
        DefineFused
    Else
        GNSS1.Start(0, 0)
    End If
   
    bTrackerRunning = True
   
    'Log("Tracker started")
   
End Sub

Public Sub StopTracker
   
    If GNSS1.IsInitialized Then
        GNSS1.Stop
    End If
   
    If Fused.IsInitialized Then
        Fused.RemoveLocationUpdates
    End If
   
    lock.ReleaseKeepAlive
    CancelScheduledService(Me)
    Service.StopForeground(1)
    StopService (Me)
   
    bTrackerRunning = False
   
End Sub

Private Sub DefineFused
   
    If Fused.IsLocationEnabledInSettings Then
        Fused.GetLocationAvailability
        Wait For FusedLocation_LocationAvailabilityRequestCompleted (Available As Boolean)
        'Log("LocationAvailable=" & Available)
        If Available Then
            Fused.GetLastLocation
            Wait For FusedLocation_LocationRequestCompleted (Result As LocationResult)
            If Result.Status = LocationResult.STATUS_SUCCESSFUL Then
                If Result.Location.IsInitialized Then
                    Dim LastLocation As LocationF = Result.Location 'ignore
                    'Log("LastLocation Latitude = " & LastLocation.Latitude)
                    'Log("LastLocation Longitude = " & LastLocation.Longitude)
                    'Do whatever you want with other LocatioF properties and methods
                Else
                    Log("Unknown last location")
                End If
            End If
        End If
   
        'Initiate FusedLocation's LocationRequest which will allow events to be fired and it will continue to work in background
        Dim LocationRequest1 As LocationRequest
        LocationRequest1.Initialize(1000) 'Refresh interval is 1000 miliseconds
        LocationRequest1.SetMinUpdateIntervalMillis(100) 'Minimum refresh interval is 100 miliseconds
        LocationRequest1.SetPriority(Priority.PRIORITY_HIGH_ACCURACY) 'Request high accuracy location
        LocationRequest1.SetMinUpdateDistanceMeters(0) 'Minimum distance in meters to fire location change event (0 is default)
        LocationRequest1.SetGranularity(Granularity.GRANULARITY_FINE)
        Fused.RequestLocationUpdates(LocationRequest1) 'Set location request to FusedLocationProviderClient and start FusedLocation
    Else
        MsgboxAsync("Location is turned off in devices's settings. Turn it on.","Warning")
        StartActivity(Fused.LocationSettingsIntent)
    End If
   
End Sub


'to get the satellite count when we are running Fused and not GNSS1
'------------------------------------------------------------------
Public Sub Start_GNSS1
   
    'as then this will run continuously when the map page shows
    '----------------------------------------------------------
    If Enums.bUseFusedLocationProviderToRecordJourney = False Then Return
   
    GNSS1.Start(0, 0)
   
End Sub

Public Sub StopGNSS1
   
    GNSS1.Stop
   
End Sub

Sub GNSS1_GNSSStatus(Status As GnssStatus)
   
    Dim i As Int
   
    'Log("GNSS1_GNSSStatus, Status.SatelliteCount: " & Status.SatelliteCount)
    'Log("GNSS1_GNSSStatus, bNoTracking: " & bNoTracking)
   
    If bNoTracking Then
        Return
    End If
   
    'Sleep(20)
   
    iSatellitesCount = Status.SatelliteCount
    iSatellitesUsed = 0
   
    'Sleep(20)
   
    'Log("GNSS1_GNSSStatus, iSatellitesCount: " & iSatellitesCount)
   
    For i = 0 To Status.SatelliteCount - 1
        If Status.UsedInFix(i) Then
            iSatellitesUsed = iSatellitesUsed + 1
            Sleep(0)
        End If
    Next
   
    'Log("GNSS1_GNSSStatus, iSatellitesUsed: " & iSatellitesUsed)
   
End Sub

Sub GNSS1_LocationChanged(Location1 As Location)
   
    If Enums.bUseFusedLocationProviderToRecordJourney Or bNoTracking Then Return
   
    lCurrentTime = DateTime.Now / 1000
    dCurrentLatitude = Location1.Latitude
    dCurrentLongitude = Location1.Longitude
    iCurrentAltitude = Location1.Altitude
   
End Sub

Private Sub FusedLocation_LocationChanged (mLocation As LocationF)
   
    'This event will be fired anytime your actual location is changed and if it meets the criteria of the defined LocationRequest
    'Log("Lat=" & mLocation.Latitude & CRLF & "Lng=" & mLocation.Longitude)
   
    If Enums.bUseFusedLocationProviderToRecordJourney = False Or bNoTracking Then Return
   
    lCurrentTime = DateTime.Now / 1000
    dCurrentLatitude = mLocation.Latitude
    dCurrentLongitude = mLocation.Longitude
    iCurrentAltitude = mLocation.Altitude
   
End Sub

Sub Service_Destroy
    StopTracker
End Sub

And this is the text of may manifest:

'-----------------------------------------------------------
AddManifestText(
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="34"/>
<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)
'End of default text.
AddPermission(android.permission.ACCESS_FINE_LOCATION)
AddPermission(android.permission.WRITE_EXTERNAL_STORAGE)
AddPermission(android.permission.MANAGE_EXTERNAL_STORAGE)

'added 31/01/2025


SetActivityAttribute(main, android:windowSoftInputMode, adjustResize|stateHidden)

'SetApplicationAttribute(android:largeHeap,"true")

AddApplicationText(<meta-data android:name="com.google.android.gms.version" android:value="@Integer/google_play_services_version" />)

SetApplicationAttribute(android:icon, "@mipmap/ic_launcher")
CreateResource(mipmap-anydpi-v26, ic_launcher.xml,
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/background"/>
<foreground android:drawable="@mipmap/foreground"/>
</adaptive-icon>
)
'-----------------------------------------------------------

From some research in the questions group I understand I need to add something to my manifest, but no idea what exactly that should be.
Any advice appreciated.

RBS
This seems to have fixed it, in the Manifest:

SetServiceAttribute(Tracker, android:foregroundServiceType, "location")
AddPermission(android.permission.FOREGROUND_SERVICE_LOCATION)

RBS
 
Upvote 1
Top