title: Why is my bound foreground service being stopped by Android Oreo?
body: <p>I've created an app that needs to scan for our my own bluetooth devices in the background constantly. When one of the bluetooth devices is nearby the app needs to undertake certain actions.</p>
  
  <p>I use a bound foreground service to scan for bluetooth devices, when a device is nearby the app starts listening for location updates. When the device isn't nearby the app stops the location updates and just start scanning again. This has been working great until Oreo.</p>
  
  <p>On Android Oreo the service is stopped usually after 2-3 days of running. And I can't figure out why this is happening.</p>
  
  <p>This is how I create the service in the main activity:</p>
  
  <pre><code>private void initServiceConnection() {
      mServiceConnection = new ServiceConnection() {
          @Override
          public void onServiceConnected(ComponentName componentName, IBinder service)
          {
              mService = ((MyService.LocalBinder) service).getService();
              mService.startBLEScan();
          }
  
          @Override
          public void onServiceDisconnected(ComponentName componentName)
          {
              // When the service is killed we restart the app in onDestroy by calling finish() here
              mService = null;
              finish();
          }
      };
  
      Intent serviceIntent = new Intent(this, MyService.class);
      bindService(serviceIntent, mServiceConnection, BIND_AUTO_CREATE | BIND_IMPORTANT);
  
      if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
          startForegroundService(serviceIntent);
      }
  }
  </code></pre>
  
  <p>This is a simplified version of the service:</p>
  
  <pre><code>public class MyService extends Service
  {    
      private static final long SCAN_TIMEOUT  = 8000;
      private static final long PAUSE_TIMEOUT = 15000;
  
      private Handler mHandler;
      private BluetoothAdapter mBluetoothAdapter;
      private final IBinder mBinder = new LocalBinder();
  
      public MyService()
      {
          mHandler = new Handler();
      }
  
      @Override
      public IBinder onBind(Intent intent)
      {
          return mBinder;
      }
  
      public void initialize()
      {
          mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
      }
  
      @Override
      public void onCreate() {
          super.onCreate();
  
          startInForeground();
          initialize();
      }
  
      @Override
      public void onDestroy()
      {
          mHandler.removeCallbacks(timeoutScan);
          mHandler.removeCallbacks(timeoutPause);
  
          stopForeground(true);
  
          stopScan();
  
          super.onDestroy();
      }
  
      public class LocalBinder extends Binder
      {
          public MyService getService()
          {
              return MyService.this;
          }
      }
  
      private void startInForeground()
      {
          NotificationCompat.Builder mNotifyBuilder;
  
          if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.O) {
              MyNotificationManager notificationManager = new MyNotificationManager(getApplicationContext());
              notificationManager.createServiceNotificationChannel();
  
              mNotifyBuilder = new NotificationCompat.Builder(this, notificationManager.getChannelId());
          } else {
              mNotifyBuilder = new NotificationCompat.Builder(this);
          }
  
          mNotifyBuilder
                  .setSmallIcon(R.drawable.ic_logo_notify)
                  .setPriority(NotificationCompat.PRIORITY_MAX);
  
          startForeground(hashCode(), mNotifyBuilder.build());
      }
  
      private void startScan()
      {
          if (mBluetoothAdapter == null) {
              return;
          }
  
          mHandler.removeCallbacks(timeoutScan);
          mHandler.removeCallbacks(timeoutPause);
  
          if (mBluetoothAdapter.isEnabled())
          {
              mBluetoothAdapter.startLeScan(mLeScanCallback);
          }
  
          mHandler.postDelayed(timeoutScan, SCAN_TIMEOUT);
      }
  
      private void stopScan()
      {
          mHandler.removeCallbacks(timeoutScan);
  
          if (mBluetoothAdapter != null)
          {
              mBluetoothAdapter.stopLeScan(mLeScanCallback);
          }
      }
  
      private Runnable timeoutScan = new Runnable ()
      {
          @Override
          public void run()
          {
              stopScan();
  
              mHandler.postDelayed(timeoutPause, PAUSE_TIMEOUT);
          }
      };
  
      private Runnable timeoutPause = new Runnable ()
      {
          @Override
          public void run()
          {
              startScan();
          }
      };
  
      private final BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback()
      {
          @Override
          public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord)
          {
              // DO STUFF
          }
      };
  } 
  </code></pre>
  
  <p>My question is am I doing something wrong? 
  Can I somehow restart the service after it has been killed?</p>