Search code examples
androidandroid-activitybroadcastreceiverandroid-broadcast

register broadcastreceiver outside activity


I want to add reminder functionality to my Application. I have Activity with a Button "Remind in 5 minutes". When I press this Button method setReminderInMinutes calls and in 5 minutes I will get a Dialog Fragment.

public void setReminderInMinutes(int timeInMinutes){
        BroadcastReceiver receiver = new BroadcastReceiver() {
            @Override public void onReceive(Context context, Intent intent){

                    ReasonsNonDeliveryDlgFragment cityDlg = ReasonsNonDeliveryDlgFragment.newinstance();
                    cityDlg.show(getSupportFragmentManager(), CityDlgFragment.TAG);
                    ((Vibrator)getSystemService(VIBRATOR_SERVICE)).vibrate(800);
                    context.unregisterReceiver(this);                
            }
        };
        this.registerReceiver(receiver, new IntentFilter("somemessage"));
        PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("somemessage"), 0 );
        AlarmManager manager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
        manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*timeInMinutes, pintent);
    }

It works well until I stay on this Activity, but when I press back Button Activity destroys, onReceive method never fire and I receive exception:

     " android.app.IntentReceiverLeaked: Activity MyActivity has leaked    
     IntentReceiver MyActivity$1@42136488 that was originally registered   
     here. Are you missing a call to unregisterReceiver()?"

So, is there anyway to register BroadcastReceiver outside my Activity? P.S. I have tried to register it in manifest file:

<receiver android:name=".receivers.ReminderReceiver">
     <intent-filter>
          <action android:name="name"/>
     </intent-filter>
 </receiver>

But still nothing works. What am I doing wrong?


Solution

  • In your case it will not work because in manifest file you given the action as "name" but while creating intent you given the action as "somemessage". So how it works. Give the same action name in manifest and intent.

    Change your code like below

    <receiver android:name=".receivers.ReminderReceiver">
         <intent-filter>
              <action android:name="some_action"/>
         </intent-filter>
     </receiver>
    

    And in setReminder() method

     PendingIntent pintent = PendingIntent.getBroadcast( this, 0, new Intent("some_action"), 0 );
            AlarmManager manager = (AlarmManager)(this.getSystemService(Context.ALARM_SERVICE));
            manager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + 1000*60*timeInMinutes, pintent)