title: Android9, how to keep uploading position?
body: <p>I'm building a location uploader app and using a smartphone as a test device. But the program can't keep uploading location. Either the program or GPS will be killed (or frozen) by the phone. The following are some key points:</p>
  
  <ol>
  <li>The OS is Android 9, and the phone is Nokia 6.</li>
  <li>Foreground service is used and START_STICKY is returned.</li>
  <li>Hold PARTIAL_WAKE_LOCK.</li>
  <li>Set the app to "not optimized" in "battery optimization".</li>
  <li>Set the background activity to be enabled in "battery management".</li>
  <li>Battery saver is off.</li>
  </ol>
  
  <p>Even after the steps above, the upload still stops after several minutes with screen off. The progress seems to be alive, but the GPS callback does not get invoked. It resumes quickly when I unlock the phone.</p>
  
  <p>So, the question is: Is there a way to build a screen-off position uploader in user mode? (The same app does not work on a rooted phone, just last longer.) It is very frustrating to fight the question.</p>
  
  <p>Here is some key code:</p>
  
  <pre class="lang-java prettyprint-override"><code>// MainService
      @Override
      public int onStartCommand(Intent intent, int flags, int startId) {
          if (android.os.Build.VERSION.SDK_INT &lt; 26)
              return super.onStartCommand(intent, flags, startId);
  
          Log.d("MainService", "onStartCommand()");
  
          String channelId = "LocationUpdaterChannel";
          NotificationChannel channel = new NotificationChannel(channelId, "LocationUpdater", NotificationManager.IMPORTANCE_DEFAULT);
          NotificationManager manager = getSystemService(NotificationManager.class);
          manager.createNotificationChannel(channel);
          Notification notification = new Notification.Builder(getApplicationContext(), channelId)
              .setContentTitle("Location Updater")
              .setContentText("Location updater is uploading your position.")
              .setSmallIcon(R.mipmap.ic_launcher_round)
              .build();
          startForeground(5463, notification);
          return START_STICKY;
      }
  
  // start service
          intent = new Intent(getApplication(), MainService.class);
          intent.setAction("com.jay.example.service.MAIN_SERVICE");
          if (android.os.Build.VERSION.SDK_INT &lt; 26) startService(intent);
          else startForegroundService(intent);
  
  </code></pre>