Search code examples
javaandroidbroadcastreceiver

Change Variable in BroadcastReceiver


I want to change a variable of a BroadcastReceiver. Unfortunately the App crashed everytime I try to access it.

Here is an example:

public class MainActivity extends AppCompatActivity {

    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.buttonAlarm).setOnClickListener(new View.OnClickListener() {
            setAlarm();
        });
    }

    public void setAlarm(){
        Calendar calendar = Calendar.getInstance();
        calendar.set(datePicker.getYear(),datePicker.getMonth(),datePicker.getDayOfMonth(),timePicker.getCurrentHour(),timePicker.getCurrentMinute(), 0);
        am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(this, MyAlarm.class);
        pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
        am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), Interval*60000, pi);
    }
}

This is the MyAlarm.java Class that extends the BroadcastReceiver:

public class MyAlarm extends BroadcastReceiver {
    int RecordTimeMinutes;

    public void onReceive(final Context context, Intent intent) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run(){
                //do some stuff
            }
        }, RecordTimeMinutes * 60000);
    }
}

So basically I want to acces the Variable RecordTimeMinutes of the MyAlarm class within the MainActivity class. Is that possible?


Solution

  • Pass the variable from the Activity via the Intent extras:

    public void setAlarm(){
            Calendar calendar = Calendar.getInstance();
            calendar.set(datePicker.getYear(),datePicker.getMonth(),datePicker.getDayOfMonth(),timePicker.getCurrentHour(),timePicker.getCurrentMinute(), 0);
            am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Intent i = new Intent(this, MyAlarm.class);
    
            i.putInt("Interval", 42); // Pass "interval" value here
    
            pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
            am.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), Interval*60000, pi);
    }
    

    And then in the receiver:

    public class MyAlarm extends BroadcastReceiver {
        public void onReceive(final Context context, Intent intent) {
    
            int interval = intent.getIntExtra("Interval", 0) // Get "interval" value here
    
            new Handler().postDelayed(new Runnable() {
                @Override
                public void run(){
                    //do some stuff
                }
            }, interval * 60000); // Use "interval" here
        }
    }
    

    That said - you should not be posting a handler to fire in the future inside a BroadcastReceiver. There is no guarantee that your process will still be alive 1 minute from now to execute your code. Instead you could schedule another alarm or use WorkManager to schedule a job to run later.

    Hope that helps!