title: Android background location update is not coming when the screen is off
body: <p>We are working on mobile tracking app. For location updates, Fused location API is used with High Accuracy as priority. </p>
  
  <p>Location update is required even when the screen is off. So, we are using background <code>Service</code>. Background <code>Service</code> is also acquiring partial <code>WakeLock</code> so that the device does not goes to sleep.
  In the background <code>Service</code> we request location updates with the pending update of the <code>Service</code>.</p>
  
  <p>The problem is that we are only receiving location updates when the screen is on. As soon as the screen is off location updates stops coming. Also there is a <code>Thread</code> run by the <code>Service</code> which is not getting kill at any point. </p>
  
  <p>Creating the location request again when the screen is off by <code>BroadcastReceiver</code> does not work either.</p>
  
  <p>Here is the background <code>Service</code> class (<code>RouteExecution</code>):</p>
  
  <pre><code>private static final String TAG = "RouteExecution";
  
  private static RouteExecution routeExecution = null;
  
  private static GoogleApiClient mGoogleApiClient;
  private static PendingIntent pendingIntent = null;
  private PowerManager.WakeLock waitLock;
  /**
   * Creates an IntentService.  Invoked by your subclass's constructor.
   */
  public RouteExecution() {
      super(TAG);
  
      RouteExecution.routeExecution = this;
  }
  
  @Override
  public void onCreate() {
      super.onCreate();
  
      mGoogleApiClient = new GoogleApiClient.Builder(this)
              .addApi(LocationServices.API)
              .addConnectionCallbacks(this)
              .addOnConnectionFailedListener(this)
              .build();
  
      mGoogleApiClient.connect();
  
      IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
      filter.addAction(Intent.ACTION_SCREEN_OFF);
      BroadcastReceiver mReceiver = new PowerButtonReceiver();
      registerReceiver(mReceiver, filter);
  
      PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
      waitLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
      waitLock.acquire();
  }
  
  @Override
  protected void onHandleIntent(Intent intent) {
  
      if (LocationResult.hasResult(intent)) {
  
          LocationResult locationResult = LocationResult.extractResult(intent);
          Location location = locationResult.getLastLocation();
  
          GPSLocation gpsLocation = new GPSLocation(location);
  
          Log.d(TAG, "Location Accuracy: " + location.getAccuracy() + " "
                  + " has: " + location.hasAccuracy() + " Provider: " + location.getProvider()
                  + " long: " + location.getLongitude() + " lat: " + location.getLatitude());
      }
  }
  
  
  
  public boolean checkLocationPermission() {
  
      if (ActivityCompat.checkSelfPermission(routeExecution, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
              &amp;&amp; ActivityCompat.checkSelfPermission(routeExecution, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
          //    ActivityCompat#requestPermissions
          // here to request the missing permissions, and then overriding
          //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
          //                                          int[] grantResults)
          // to handle the case where the user grants the permission. See the documentation
          // for ActivityCompat#requestPermissions for more details.
          return false;
      }
  
      return true;
  }
  
  public void createLocationListener() {
  
      if (!this.checkLocationPermission()) {
          return;
      }
  
      LocationRequest mLocationRequest = LocationRequest.create();
      mLocationRequest.setInterval(5000);
      mLocationRequest.setFastestInterval(5000);
      mLocationRequest.setSmallestDisplacement(0);
      mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
  
      PendingResult&lt;Status&gt; statusPendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
              mLocationRequest, pendingIntent);
  }
  
  @Override
  public void onConnected(@Nullable Bundle bundle) {
  
      Log.d(TAG, mGoogleApiClient.isConnected() + "   On Connected");
      synchronized (this) {
  
              createLocationListener();
      }
  }
  
  
  public static GoogleApiClient getmGoogleApiClient() {
      return mGoogleApiClient;
  }
  
  @Override
  public void onDestroy() {
      super.onDestroy();
  
  
      waitLock.release();
      mGoogleApiClient.disconnect();
  }
  
  public static RouteExecution getRouteExecution() {
      return routeExecution;
  }
  
  public static void setPendingIntent(PendingIntent pendingIntent) {
      RouteExecution.pendingIntent = pendingIntent;
  }
  </code></pre>
  
  <p><code>Service</code> is started using <code>AlarmManager</code>. Here is the extraction: </p>
  
  <pre><code>AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
  Intent updateServiceIntent = new Intent(context, RouteExecution.class);
  PendingIntent pendingUpdateIntent = PendingIntent.getService(context, 0, updateServiceIntent, 0);
  RouteExecution.setPendingIntent(pendingUpdateIntent);
  alarmManager.set(AlarmManager.RTC_WAKEUP, 50000, pendingUpdateIntent);
  </code></pre>
  
  <p><code>BroadcastReceiver</code>:</p>
  
  <pre><code>public class PowerButtonReceiver extends BroadcastReceiver {
      private static final String TAG = "PowerButton";
  
      @Override
      public void onReceive(Context context, Intent intent) {
  
          Log.d(TAG, "Power Button");
          if (RouteExecution.getRouteExecution() != null) {
              RouteExecution.getRouteExecution().createLocationListener();
          }
      }
  }
  </code></pre>
  
  <p>How to keep getting location updates even when the screen is off.</p>
  
  <p>Thanks for the help.</p>