0

I migrate my app to oreo (as it's requiered by google play now), and i have now an error when i start my phone :

Not allowed to start service Intent

My app is listening in background any location update and send periodically those grabbed locations to a server. for this i do :

in AndroidManifest.xml

  <receiver android:name="com.myapp.StartServiceBroadcastReceiver">  
    <intent-filter>  
      <action android:name="android.intent.action.BOOT_COMPLETED" />  
    </intent-filter>  
  </receiver> 

in the StartServiceBroadcastReceiver i do :

  @Override
  public void onReceive(Context context, Intent intent) {

    try {

        /* start the location service */  
        Intent startServiceIntent = new Intent(context, LocationService.class);
        context.startService(startServiceIntent);

    } catch (Throwable e){ Log.e(TAG, "Exception", e); }  

  }

and the LocationService basiqually do :

public void onCreate() {

  mLocationServices.setListener(this);
  mLocationServices.startLocationUpdates(true, // startWithLastKnownLocation,

                                         150000, // interval => 2.5 min  // Set the desired interval for active location updates, in milliseconds.
                                                                         // The location client will actively try to obtain location updates for your
                                                                         // application at this interval, so it has a direct influence on the amount
                                                                         // of power used by your application. Choose your interval wisely.

                                         30000, // fastestInterval => 30 s  // Explicitly set the fastest interval for location updates, in milliseconds.
                                                                            // This controls the fastest rate at which your application will receive location updates, which might be faster than setInterval(long)
                                                                            // in some situations (for example, if other applications are triggering location updates).
                                                                            // This allows your application to passively acquire locations at a rate faster than it actively acquires locations, saving power.

                                         900000, // maxWaitTime => 15 min  // Sets the maximum wait time in milliseconds for location updates.
                                                                           // If you pass a value at least 2x larger than the interval specified with setInterval(long), then location
                                                                           // delivery may be delayed and multiple locations can be delivered at once. Locations are determined at
                                                                           // the setInterval(long) rate, but can be delivered in batch after the interval you set in this method.
                                                                           // This can consume less battery and give more accurate locations, depending on the device's hardware
                                                                           // capabilities. You should set this value to be as large as possible for your needs if you don't
                                                                           // need immediate location delivery.

                                         LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY, // priority => Block level accuracy is considered to be about 100 meter accuracy.
                                                                                           //             Using a coarse accuracy such as this often consumes less power.

                                         25); // smallestDisplacement => 25 meters // Set the minimum displacement between location updates in meters  


}

@Override
public void onLocationChanged(Location location) {
   ....
}

Everything was working well on pre-oreo but now it's failed on oreo+. What i can do to make my service running ?

Phantômaxx
  • 37,901
  • 21
  • 84
  • 115
zeus
  • 12,173
  • 9
  • 63
  • 184
  • 1
    Have u tried `startForegroundService()` – AskNilesh Sep 24 '18 at 12:50
  • using foreground service is one solution – Manohar Sep 24 '18 at 12:50
  • @NileshRathod what is exactly the difference between startForegroundService and startService ? – zeus Sep 24 '18 at 12:59
  • @Redman same question, what it's imply to use foreground service ? – zeus Sep 24 '18 at 13:00
  • Possible duplicate: https://stackoverflow.com/questions/46445265/android-8-0-java-lang-illegalstateexception-not-allowed-to-start-service-inten?rq=1 – Markus Penguin Sep 24 '18 at 14:27
  • Possible duplicate of [Android 8.0: java.lang.IllegalStateException: Not allowed to start service Intent](https://stackoverflow.com/questions/46445265/android-8-0-java-lang-illegalstateexception-not-allowed-to-start-service-inten) – Markus Penguin Sep 24 '18 at 14:27
  • @MarkusPenguin : i update the question to focus more on the location update so it's not anymore a duplicate – zeus Sep 24 '18 at 14:32

1 Answers1

4

Starting in Android Oreo you cannot simply start a background service while the app is in the background.

You can start your service as foreground service like that (Kotlin, but similar in Java):

val serviceIntent = Intent(context, LocationService::class.java)
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    context.startForegroundService(serviceIntent)
} else {
    context.startService(serviceIntent)
}

In your service make sure you call startForeground as soon as possible. This will also issue a notification so that the user knows your app is active in the background.

As Anis BEN NSIR has pointed out in the comments, you will probably also be affected by the new background location limits.

There is a nice article about Oreo's background exexution limits.

Markus Penguin
  • 1,581
  • 12
  • 19
  • thanks markus, but what really imply to start a service in Foreground ? what is the difference between background service ? – zeus Sep 24 '18 at 13:01
  • @loki, basically it means that the service is noticable by the user (it shows a notification) and it is allowed to run even when the user is not actively using the app. See also [this summary](https://developer.android.com/guide/components/services). – Markus Penguin Sep 24 '18 at 13:04
  • @MarkusPenguin .. no it's not possible to show at full time a notification to the user :( is their any other way ? – zeus Sep 24 '18 at 13:05
  • @loki Starting with Android Oreo it is required to do that. You won't be able to have your app running permanently in the background without the user noticing. If you do not want to have a persistent notification you could [schedule a job](https://developer.android.com/topic/performance/scheduling) - but that of course depends on your use case. – Markus Penguin Sep 24 '18 at 13:10
  • @MarkusPenguin - In this way how other app do to grab location update ? none of them have a persistent notification as i see ... – zeus Sep 24 '18 at 13:13