3

HERE SDK tries to start its MapService internally when consumers call MapEngine.init(). Due to Android 8 background execution restrictions, this fails if MapEngine is to be initialized from a background Service. Is there any way to initialize MapEngine that doesn't involve the SDK starting a Service internally?

The exception log:

> java.lang.IllegalStateException: Not allowed to start service Intent { act=com.here.android.mpa.service.MapService.v3 cmp=de.newecho.app/com.here.android.mpa.service.MapService (has extras) }: app is in background uid UidRecord{6924417 u0a225 CEM  idle change:cached procs:1 seq(0,0,0)}
       at android.app.ContextImpl.startServiceCommon(ContextImpl.java:1521)
       at android.app.ContextImpl.startService(ContextImpl.java:1477)
       at android.content.ContextWrapper.startService(ContextWrapper.java:650)
       at com.nokia.maps.MapServiceClient.a(SourceFile:77)
       at com.nokia.maps.MapsEngine.a(SourceFile:622)
       at com.nokia.maps.MapsEngine.a(SourceFile:364)
       at com.here.android.mpa.common.MapEngine.init(SourceFile:260)

EDIT: I have no idea why this got marked as a duplicate. My question is not about how to generally handle background work on Android 8 as in the "duplicated" question. The call to startService() happens in the HERE SDK internally, so consumers have no means to change that. The question is directed towards HERE devs to clarify whether there is a way to initialize MapEngine in a manner so that the HERE SDK doesn't start a Service internally.

jbxbergdev
  • 860
  • 1
  • 10
  • 23
  • Update: I've emailed with HERE and they state that they 'need' to start a foreground Service because the SDK requires runtime permissions. I objected stating it should be the consumer's responsibility to check permissions and the permissions may as well be checked (even though not set) in the background. They might look into changing the behavior .... or not. – jbxbergdev Feb 02 '18 at 10:46
  • Is there any particular reason that you try to start map engine on the background thread? AFAIU, you should call this method on the main thread. – NazarK Feb 05 '18 at 12:50
  • Reason is we need to use MapEngine in a background Service. Unless there is more to it than the permission checks mentioned by HERE, the restriction to foreground Services or even to the main thread (btw. do you have a source for that?) is a case of less-than-ideal design IMHO. – jbxbergdev Feb 06 '18 at 08:51
  • Services and threads are different things, you can easily start runnable on the main thread from any place in the code. new Handler(Looper.getMainLooper()).post(() -> { /*start MapEngine*/}); – NazarK Feb 06 '18 at 09:02
  • @NazarK, my apologies, I just realized that my post wasn't quite clear about background Service/Thread. I rephrased the question. The problem is about being in a background Service, so posting to the main Looper won't help. – jbxbergdev Feb 06 '18 at 09:13
  • 1
    OK, I see :). When app is in background you should not start MapEngine(or generally do any heavy cpu operation). That’s how Google wants us to write apps. There is no possibility to opt out of starting service from MapEngine, sorry. One ugly & temporary solution would be to set 'targetSdkVersion 25' (or lower) in build.gradle, that might work for a while. – NazarK Feb 06 '18 at 09:56
  • This isn't entirely true: Google encourages (Android 8+: forces) developers to use the JobScheduler API for background tasks, which is what we do. There is no general restriction on how heavy the background work may be. In any case, they don't advocate forcing the app foreground behaviour for things that should happen in the background. Just to clarify things: Are you actually working for HERE? – jbxbergdev Feb 06 '18 at 10:07
  • *forcing foreground behavior – jbxbergdev Feb 06 '18 at 10:13
  • @jbxbergdev Hi! Any Updates on your problem? – Grecha Apr 26 '18 at 13:12
  • getting same issue. – Nouman Ch Jul 13 '18 at 05:38
  • @Grecha, I'm not working on the project any more and haven't received any update from HERE since. – jbxbergdev Jul 13 '18 at 11:32

1 Answers1

0

Within HERE Mobile SDK it is not possible to init the map from a background thread.

It is possible to continue function like Navigation in background after map init(in foreground) is done by ensuring a) The required map data is already loaded on the device, b) a foreground service is triggered

From Documentation : https://developer.here.com/documentation/android-premium/dev_guide/topics/map-guidance.html

If you are using Turn-by-Turn Navigation Mode for driving, you can also set HERE SDK to perform guidance (including voice instructions and event callbacks) while the app is in the background. However, unlike the foreground navigation scenario, HERE SDK does not stream map data during background navigation on Android. To properly support background navigation for these devices, HERE SDK requires your app to preload map data (such as for the current city or state) using the MapLoader class.

Important: Starting with Android O (8.0), if your app is running in the background, then the location system service only computes a new location for your app a few times each hour. To avoid this behavior, start a foreground service by following the instructions in the Android documentation. Important: Starting with Android P (9.0), app that requires use of foreground service must request android.permission.FOREGROUND_SERVICE permission from the user. For more information, please refer to Android Pie behaviour change documentation.

Dharman
  • 30,962
  • 25
  • 85
  • 135