Search code examples
androidbroadcastreceiverboot

BroadcastReceiver conditionally start service on boot without starting the app


I have an application that has a service to be conditionally started on boot (based on a checkbox preference defined in xml). My broadcast receiver class is this:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
import android.util.Log;

public class BootServiceReceiver extends BroadcastReceiver {
private static final String TAG = "tweakmanager";

@Override
public void onReceive(Context context, Intent intent) {
    if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
        SharedPreferences prefLights;
        prefLights = PreferenceManager.getDefaultSharedPreferences(context);
        if (prefLights.getBoolean("checkbox1", false)) {
            Log.i(TAG, "doing nothing...");
        } else {
            Intent p = new Intent();
            p.setAction("app.tweaks.Service");
            context.startService(p);
        }
    }
}
}

Note that service should only start if checkbox is unchecked. Default state is checked.

Now, on normal operation, all is working good - if checkbox is checked, service doesn't start, if it's unchecked, service starts on boot.

The problem lies if the application is installed but never run... In this case, service starts at next boot even if checkbox is checked. I thought about writing the default preferences to a file that could be read by the receiver, but I don't think that's the nicest solution...


Solution

  • In this case, service starts at next boot even if checkbox is checked

    It should not do so, as there will be no preference, and so your getBoolean() should return false as you specified.

    That being said, there is a better solution:

    1. Add android:enabled="false" to the manifest for this <receiver> element.

    2. When they toggle the checkbox in preferences, use PackageManager and setComponentEnabledSetting() to enable or disable the BroadcastReceiver, such that you are enabled when the checkbox is checked.

    This way, Android does not have to bother forking your process on a reboot, if the user has not checked this checkbox.