Search code examples
androidbroadcastreceiverboot

BroadcastReceiver not triggered on boot - programmatically


I am trying to start my app if user wishes so on boot. I have checkbox that un/register broadcast receiver. If i declare receiver in manifest my app always starts on boot which is unwanted behaviour. I tried also getApplicationcontext().registerReceiver without a luck. Am I missing something?

    final BroadcastReceiver startMyActivityAtBootReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {

            Log.i("LockState", "broadcast receiver called started");
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                Intent activityIntent = new Intent(context, MainActivity.class);
                activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(activityIntent);
            }
        }
    };

    if (switch4.isChecked()){
        LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(startMyActivityAtBootReceiver, new IntentFilter("android.intent.action.BOOT_COMPLETED"));
        Log.i("LockState", "broadcastreceiver registered");
    }
    else {
        LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(startMyActivityAtBootReceiver);
        Log.i("LockState", "broadcastreceiver unregistered");
    }

    switch4.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
            SharedPref.write(Constants.LAUNCH_AT_START, isChecked);
            Log.i("LockState", "launch app at start: " + isChecked);

            if (isChecked) {
                LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(startMyActivityAtBootReceiver, new IntentFilter("android.intent.action.BOOT_COMPLETED"));
                Log.i("LockState", "broadcastreceiver registered");
            } else {
                LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(startMyActivityAtBootReceiver);
                Log.i("LockState", "broadcastreceiver unregistered");
            }
        }
    });

Solution

  • It must be declared in the manifest. You are going about this the wrong way. Rather than allowing the user to enable/disable the broadcast receiver for boot, you should handle that option within the receiver itself. Either launch the activity or not, based on the saved user preference value from the checkbox.

        @Override
        public void onReceive(Context context, Intent intent) {
            // Handle user preference
            if (!isUserPreferenceEnabled()) return;
    
            if (Intent.ACTION_BOOT_COMPLETED.equals(intent.getAction())) {
                Intent activityIntent = new Intent(context, MainActivity.class);
                activityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                context.startActivity(activityIntent);
            }
        }