diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
index 652ef527d4325294c8e9c69eb4ea4877ad501e25..763c50332da6d0ff26bf6ee5f683281c1900b95f 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AndroidComponent.java
@@ -26,6 +26,7 @@ import org.briarproject.briar.BriarCoreEagerSingletons;
 import org.briarproject.briar.BriarCoreModule;
 import org.briarproject.briar.android.reporting.BriarReportSender;
 import org.briarproject.briar.api.android.AndroidNotificationManager;
+import org.briarproject.briar.api.android.DozeWatchdog;
 import org.briarproject.briar.api.android.ScreenFilterMonitor;
 import org.briarproject.briar.api.blog.BlogManager;
 import org.briarproject.briar.api.blog.BlogPostFactory;
@@ -140,6 +141,8 @@ public interface AndroidComponent
 
 	TestDataCreator testDataCreator();
 
+	DozeWatchdog dozeWatchdog();
+
 	@IoExecutor
 	Executor ioExecutor();
 
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
index 725a690475b0249b1b2456cbd6f425fcecfde02f..c0e06897655f5c442ed6473a00814ad2e8673533 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/AppModule.java
@@ -15,6 +15,7 @@ import org.briarproject.bramble.api.reporting.DevConfig;
 import org.briarproject.bramble.api.ui.UiCallback;
 import org.briarproject.bramble.util.StringUtils;
 import org.briarproject.briar.api.android.AndroidNotificationManager;
+import org.briarproject.briar.api.android.DozeWatchdog;
 import org.briarproject.briar.api.android.ReferenceManager;
 import org.briarproject.briar.api.android.ScreenFilterMonitor;
 
@@ -40,6 +41,8 @@ public class AppModule {
 		AndroidNotificationManager androidNotificationManager;
 		@Inject
 		NetworkUsageLogger networkUsageLogger;
+		@Inject
+		DozeWatchdog dozeWatchdog;
 	}
 
 	private final Application application;
@@ -183,4 +186,12 @@ public class AppModule {
 		lifecycleManager.registerService(networkUsageLogger);
 		return networkUsageLogger;
 	}
+
+	@Provides
+	@Singleton
+	DozeWatchdog provideDozeWatchdog(LifecycleManager lifecycleManager) {
+		DozeWatchdogImpl dozeWatchdog = new DozeWatchdogImpl(application);
+		lifecycleManager.registerService(dozeWatchdog);
+		return dozeWatchdog;
+	}
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
index 2ac0c3e3e60166d5e6de8da51e0cef53ce0d7773..0e6bb7c399b79d68f0bc942164f8d0b4013b6125 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/BriarService.java
@@ -3,16 +3,12 @@ package org.briarproject.briar.android;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
-import android.content.BroadcastReceiver;
 import android.content.ComponentName;
-import android.content.Context;
 import android.content.Intent;
-import android.content.IntentFilter;
 import android.content.ServiceConnection;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
-import android.os.PowerManager;
-import android.support.annotation.Nullable;
 import android.support.v4.app.NotificationCompat;
 import android.support.v4.content.ContextCompat;
 
@@ -32,15 +28,12 @@ import javax.inject.Inject;
 import static android.app.PendingIntent.FLAG_UPDATE_CURRENT;
 import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TOP;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
-import static android.os.Build.VERSION.SDK_INT;
-import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
 import static android.support.v4.app.NotificationCompat.CATEGORY_SERVICE;
 import static android.support.v4.app.NotificationCompat.PRIORITY_MIN;
 import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
 import static java.util.logging.Level.WARNING;
 import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.ALREADY_RUNNING;
 import static org.briarproject.bramble.api.lifecycle.LifecycleManager.StartResult.SUCCESS;
-import static org.briarproject.briar.android.util.UiUtils.needsDozeWhitelisting;
 
 public class BriarService extends Service {
 
@@ -52,8 +45,6 @@ public class BriarService extends Service {
 
 	private final AtomicBoolean created = new AtomicBoolean(false);
 	private final Binder binder = new BriarBinder();
-	@Nullable
-	private BriarBroadcastReceiver receiver = null;
 
 	@Inject
 	protected DatabaseConfig databaseConfig;
@@ -62,7 +53,7 @@ public class BriarService extends Service {
 	protected volatile LifecycleManager lifecycleManager;
 	@Inject
 	protected volatile AndroidExecutor androidExecutor;
-	private volatile boolean started = false, hasDozed = false;
+	private volatile boolean started = false;
 
 	@Override
 	public void onCreate() {
@@ -93,7 +84,7 @@ public class BriarService extends Service {
 		Intent i = new Intent(this, NavDrawerActivity.class);
 		i.setFlags(FLAG_ACTIVITY_NEW_TASK | FLAG_ACTIVITY_CLEAR_TOP);
 		b.setContentIntent(PendingIntent.getActivity(this, 0, i, 0));
-		if (SDK_INT >= 21) {
+		if (Build.VERSION.SDK_INT >= 21) {
 			b.setCategory(CATEGORY_SERVICE);
 			b.setVisibility(VISIBILITY_SECRET);
 		}
@@ -118,7 +109,6 @@ public class BriarService extends Service {
 				}
 			}
 		}.start();
-		registerBroadcastReceiver();
 	}
 
 	private void showStartupFailureNotification(StartResult result) {
@@ -163,7 +153,6 @@ public class BriarService extends Service {
 	public void onDestroy() {
 		super.onDestroy();
 		LOG.info("Destroyed");
-		if (receiver != null) unregisterReceiver(receiver);
 		stopForeground(true);
 		// Stop the services in a background thread
 		new Thread() {
@@ -181,21 +170,6 @@ public class BriarService extends Service {
 		// FIXME: Work out what to do about it
 	}
 
-	private void registerBroadcastReceiver() {
-		if (SDK_INT < 23) return;
-		IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED);
-		receiver = new BriarBroadcastReceiver();
-		registerReceiver(receiver, filter);
-	}
-
-	public boolean hasDozed() {
-		return hasDozed;
-	}
-
-	public void resetDozeFlag() {
-		hasDozed = false;
-	}
-
 	/**
 	 * Waits for all services to start before returning.
 	 */
@@ -251,15 +225,4 @@ public class BriarService extends Service {
 			return binder;
 		}
 	}
-
-	public class BriarBroadcastReceiver extends BroadcastReceiver {
-		@Override
-		public void onReceive(Context context, Intent intent) {
-			if (SDK_INT < 23 || !needsDozeWhitelisting(getApplicationContext()))
-				return;
-			PowerManager pm = (PowerManager) getSystemService(POWER_SERVICE);
-			if (pm.isDeviceIdleMode()) hasDozed = true;
-		}
-	}
-
 }
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b104ca0f805727b84dbc15e0f271d673fb4e8be
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/android/DozeWatchdogImpl.java
@@ -0,0 +1,56 @@
+package org.briarproject.briar.android;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.PowerManager;
+
+import org.briarproject.bramble.api.lifecycle.Service;
+import org.briarproject.bramble.api.lifecycle.ServiceException;
+import org.briarproject.briar.api.android.DozeWatchdog;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static android.content.Context.POWER_SERVICE;
+import static android.os.Build.VERSION.SDK_INT;
+import static android.os.PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED;
+
+class DozeWatchdogImpl implements DozeWatchdog, Service {
+
+	private final Context appContext;
+	private final AtomicBoolean dozed = new AtomicBoolean(false);
+	private final BroadcastReceiver receiver = new DozeBroadcastReceiver();
+
+	DozeWatchdogImpl(Context appContext) {
+		this.appContext = appContext;
+	}
+
+	@Override
+	public boolean getAndResetDozeFlag() {
+		return dozed.getAndSet(false);
+	}
+
+	@Override
+	public void startService() throws ServiceException {
+		if (SDK_INT < 23) return;
+		IntentFilter filter = new IntentFilter(ACTION_DEVICE_IDLE_MODE_CHANGED);
+		appContext.registerReceiver(receiver, filter);
+	}
+
+	@Override
+	public void stopService() throws ServiceException {
+		appContext.unregisterReceiver(receiver);
+	}
+
+	private class DozeBroadcastReceiver extends BroadcastReceiver {
+
+		@Override
+		public void onReceive(Context context, Intent intent) {
+			if (SDK_INT < 23) return;
+			PowerManager pm =
+					(PowerManager) appContext.getSystemService(POWER_SERVICE);
+			if (pm.isDeviceIdleMode()) dozed.set(true);
+		}
+	}
+}
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
index 64cc194f3e179eac48cb9cbb3ea298ed89789a7a..d00730f2448db7b361072965692d5a51ae09178d 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/activity/BriarActivity.java
@@ -2,7 +2,6 @@ package org.briarproject.briar.android.activity;
 
 import android.annotation.SuppressLint;
 import android.content.Intent;
-import android.os.Build;
 import android.support.v7.app.ActionBar;
 import android.support.v7.app.AlertDialog;
 import android.support.v7.widget.Toolbar;
@@ -28,6 +27,7 @@ import static android.content.Intent.FLAG_ACTIVITY_CLEAR_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS;
 import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK;
 import static android.content.Intent.FLAG_ACTIVITY_NO_ANIMATION;
+import static android.os.Build.VERSION.SDK_INT;
 import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_DOZE_WHITELISTING;
 import static org.briarproject.briar.android.activity.RequestCodes.REQUEST_PASSWORD;
 import static org.briarproject.briar.android.util.UiUtils.getDozeWhitelistingIntent;
@@ -64,7 +64,7 @@ public abstract class BriarActivity extends BaseActivity {
 		if (!briarController.hasEncryptionKey() && !isFinishing()) {
 			Intent i = new Intent(this, PasswordActivity.class);
 			startActivityForResult(i, REQUEST_PASSWORD);
-		} else {
+		} else if (SDK_INT >= 23) {
 			briarController.hasDozed(new UiResultHandler<Boolean>(this) {
 				@Override
 				public void onResultUi(Boolean result) {
@@ -78,7 +78,7 @@ public abstract class BriarActivity extends BaseActivity {
 	}
 
 	public void setSceneTransitionAnimation() {
-		if (Build.VERSION.SDK_INT < 21) return;
+		if (SDK_INT < 21) return;
 		Transition slide = new Slide(Gravity.RIGHT);
 		slide.excludeTarget(android.R.id.statusBarBackground, true);
 		slide.excludeTarget(android.R.id.navigationBarBackground, true);
@@ -160,7 +160,7 @@ public abstract class BriarActivity extends BaseActivity {
 	}
 
 	private void finishAndExit() {
-		if (Build.VERSION.SDK_INT >= 21) finishAndRemoveTask();
+		if (SDK_INT >= 21) finishAndRemoveTask();
 		else supportFinishAfterTransition();
 		LOG.info("Exiting");
 		System.exit(0);
diff --git a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
index 9ecd35e915d67542dffb2c94e169b27a4476c6d2..a8d90dd0cc98a9162e9a1eaed234e53e404ad5c1 100644
--- a/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
+++ b/briar-android/src/main/java/org/briarproject/briar/android/controller/BriarControllerImpl.java
@@ -4,8 +4,6 @@ import android.app.Activity;
 import android.content.Intent;
 import android.os.IBinder;
 import android.support.annotation.CallSuper;
-import android.support.annotation.Nullable;
-import android.support.annotation.WorkerThread;
 
 import org.briarproject.bramble.api.db.DatabaseConfig;
 import org.briarproject.bramble.api.db.DatabaseExecutor;
@@ -15,6 +13,7 @@ import org.briarproject.bramble.api.settings.SettingsManager;
 import org.briarproject.briar.android.BriarService;
 import org.briarproject.briar.android.BriarService.BriarServiceConnection;
 import org.briarproject.briar.android.controller.handler.ResultHandler;
+import org.briarproject.briar.api.android.DozeWatchdog;
 
 import java.util.concurrent.Executor;
 import java.util.logging.Logger;
@@ -37,22 +36,22 @@ public class BriarControllerImpl implements BriarController {
 	@DatabaseExecutor
 	private final Executor databaseExecutor;
 	private final SettingsManager settingsManager;
+	private final DozeWatchdog dozeWatchdog;
 	private final Activity activity;
 
 	private boolean bound = false;
 
-	@Nullable
-	private volatile BriarService service;
-
 	@Inject
 	BriarControllerImpl(BriarServiceConnection serviceConnection,
 			DatabaseConfig databaseConfig,
 			@DatabaseExecutor Executor databaseExecutor,
-			SettingsManager settingsManager, Activity activity) {
+			SettingsManager settingsManager, DozeWatchdog dozeWatchdog,
+			Activity activity) {
 		this.serviceConnection = serviceConnection;
 		this.databaseConfig = databaseConfig;
 		this.databaseExecutor = databaseExecutor;
 		this.settingsManager = settingsManager;
+		this.dozeWatchdog = dozeWatchdog;
 		this.activity = activity;
 	}
 
@@ -81,15 +80,6 @@ public class BriarControllerImpl implements BriarController {
 		activity.startService(new Intent(activity, BriarService.class));
 		bound = activity.bindService(new Intent(activity, BriarService.class),
 				serviceConnection, 0);
-		if (!bound) throw new IllegalStateException();
-
-		new Thread(() -> {
-			try {
-				service = getBriarService();
-			} catch (InterruptedException e) {
-				LOG.warning("Interrupted while waiting for service");
-			}
-		}).start();
 	}
 
 	@Override
@@ -99,13 +89,11 @@ public class BriarControllerImpl implements BriarController {
 
 	@Override
 	public void hasDozed(ResultHandler<Boolean> handler) {
-		BriarService briarService = service;
-		if (briarService == null || !briarService.hasDozed() ||
-				!needsDozeWhitelisting(activity)) {
+		if (!dozeWatchdog.getAndResetDozeFlag()
+				|| !needsDozeWhitelisting(activity)) {
 			handler.onResult(false);
 			return;
 		}
-		if (briarService.hasDozed()) briarService.resetDozeFlag();
 		databaseExecutor.execute(() -> {
 			try {
 				Settings settings =
@@ -137,11 +125,12 @@ public class BriarControllerImpl implements BriarController {
 	public void signOut(ResultHandler<Void> eventHandler) {
 		new Thread() {
 			@Override
-			@SuppressWarnings("ConstantConditions")
 			public void run() {
 				try {
-					if (service == null) service = getBriarService();
 					// Wait for the service to finish starting up
+					IBinder binder = serviceConnection.waitForBinder();
+					BriarService service =
+							((BriarService.BriarBinder) binder).getService();
 					service.waitForStartup();
 					// Shut down the service and wait for it to shut down
 					LOG.info("Shutting down service");
@@ -155,12 +144,6 @@ public class BriarControllerImpl implements BriarController {
 		}.start();
 	}
 
-	@WorkerThread
-	private BriarService getBriarService() throws InterruptedException {
-		IBinder binder = serviceConnection.waitForBinder();
-		return ((BriarService.BriarBinder) binder).getService();
-	}
-
 	private void unbindService() {
 		if (bound) activity.unbindService(serviceConnection);
 	}
diff --git a/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java b/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java
new file mode 100644
index 0000000000000000000000000000000000000000..9b37aebff0af6407657c693f471f64a8f28189e0
--- /dev/null
+++ b/briar-android/src/main/java/org/briarproject/briar/api/android/DozeWatchdog.java
@@ -0,0 +1,6 @@
+package org.briarproject.briar.api.android;
+
+public interface DozeWatchdog {
+
+	boolean getAndResetDozeFlag();
+}