注册broadcastreceiver外部活动

时间:2015-05-27 11:51:39

标签: android android-activity broadcastreceiver android-broadcast

我想在我的应用程序中添加提醒功能。 我有一个按钮"Remind in 5 minutes"的活动。当我按下此按钮方法setReminderInMinutes时,我会在5分钟内收到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);
    }

它一直运行良好,直到我继续这个活动,但当我按回按钮活动破坏时,onReceive方法永远不会开火,我收到异常:

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

那么,有没有在我的活动之外注册BroadcastReceiver? 附:我试图在清单文件中注册它:

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

但仍然无效。我做错了什么?

4 个答案:

答案 0 :(得分:1)

在Activity之外注册接收者的唯一方法 - 在应用程序清单中注册它。在你的情况下,它应如下所示:

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

设置name <intent-filter>Intent内部广播内容的操作相同,非常重要。

答案 1 :(得分:1)

在您的情况下,它将无效,因为在清单文件中,您将操作指定为"name",但在创建意图时,您将操作指定为"somemessage"。它是如何工作的。在清单和意图中给出相同的操作名称。

更改您的代码,如下所示

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

在setReminder()方法中

 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)

答案 2 :(得分:0)

试试这个

@Override
public void onResume() {
super.onResume();

   // Register mMessageReceiver to receive messages.
   LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
     new IntentFilter("my-event"));
}

// handler for received Intents for the "my-event" event 
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
   // Extract data included in the Intent
   String message = intent.getStringExtra("message");
   Log.d("receiver", "Got message: " + message);
 }
};

@Override
protected void onPause() {
   // Unregister since the activity is not visible
   LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
   super.onPause();
} 

答案 3 :(得分:0)

没有必要将BroadCastReceiver的引用传递给挂起的intent。您还可以传递活动的引用,以便在挂起的意图过去时为您调用。

如果您想在活动之外使用BroadCastReceiver,可以在清单中声明它

<receiver android:name=".MyReceiver"
          android:exported="true">
</receiver>

然后在您的活动中执行此操作以将其注册到警报管理器

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