【问题标题】:Why doesn't my BroadcastReceiver's onReceive get called when the BroadcastReceiver is an inner class?当 BroadcastReceiver 是内部类时,为什么不调用我的 BroadcastReceiver 的 onReceive?
【发布时间】:2014-05-10 07:51:42
【问题描述】:

当我在它自己的文件中包含下面的 AlarmReceiver 类时,会记录日志语句并调用 onReceive 方法。我需要让我的 BroadcastReceiver 成为一个内部类,这样我就可以从我的 Activity 中调用 getFragmentManager()。但是,当我将其作为主 Activity 类的内部类时,它不会被调用。这是为什么呢?

 public class MainActivity extends Activity {

        public class AlarmReceiver extends BroadcastReceiver { //this needs to be an inner class to access the activity

            @Override
            public void onReceive(Context arg0, Intent arg1) {
                Log.d("BROADCAST","RECEIVED");
                //start a new activity, an alarm has gone off
                AlarmFragment alarmFragment=new AlarmFragment();  
              // getFragmentManager().beginTransaction().replace(R.id.container, alarmFragment).commit();

            }
        }

public void setAlarm(){
   Intent intentAlarm = new Intent(this, AlarmReceiver.class);

   //Get the Alarm Service
   AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

   Long currentTime = new GregorianCalendar().getTimeInMillis();

   //DEBUG TIME
   alarmManager.set(AlarmManager.RTC_WAKEUP,currentTime+7500,PendingIntent.getBroadcast(this,1,  intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT));
}

}

【问题讨论】:

    标签: android broadcastreceiver inner-classes


    【解决方案1】:

    请将您的 Activity 类更改为 FragmentActivity 并使用上下文对象进行访问,如下面的代码。

    arg0.getFragmentManager().beginTransaction().replace(R.id.container, alarmFragment).commit();
    

    这是一个尝试。请让我知道您的反馈。

    【讨论】:

    • 上下文对象不是Activity上下文。
    • android.app.ReceiverRestrictedContext 无法转换为 android.app.Activity
    【解决方案2】:

    为什么会这样?

    关于发送和接收广播机制的工作原理,你犯了一个重大的根本性错误:

    您正在向警报管理器提供PendingIntent 以开始广播,但在实践中 - 您在没有指定任何操作的情况下提供它的意图。

    没有动作就发送广播是没有意义的!!!

    您应该向intentAlarm 对象添加一个标识您的广播的自定义操作字符串,并使用处理此自定义操作的IntentFilter 以编程方式注册您的AlarmReceiver 接收器:

     Intent intentAlarm = new Intent(CUSTOM_ACTION_STRING);
     ....
     ....
    

    (您应该持有对 AlarmReceiver 类实例的引用。这就是 mAlarmReceiver ...) 添加到ActivityonResume()回调注册到广播:

     @Override
    public void onResume() {
        super.onResume();
    
        registerReceiver(mAlarmReceiver , new IntentFilter(CUSTOM_ACTION_STRING));
    }
    

    别忘了注销接收者:

    @Override
    public void onPause() {
        unregisterReceiver(mAlaramReceiver);
    
        super.onPause();
    }
    

    【讨论】:

    • 虽然这很有趣,我可能会尝试一下,但我仍然想知道为什么当我将类移动到另一个文件时它会起作用,而当它是内部类时它不起作用。跨度>
    • @TylerPfaff:即使它不是嵌套类,它也不应该工作。如果它正常工作 - 那么它是操作系统或设备固件中的错误。 broadcastReceiver 假设在发送具有当前注册到的适当意图过滤器的广播时唤醒并执行 onReceive 方法
    • @TylerPfaff:顺便说一下 - 如果您设置的警报仅用于在一段时间后执行片段事务 - 那么使用 AlarmManager 发送广播完全是开销。有更简单的方法可以做到这一点,例如通过处理程序延迟发布。
    • 也许它可以工作,因为您可以在清单中声明一个接收者?
    • 我将通过处理程序查看延迟的可运行,谢谢。
    猜你喜欢
    • 1970-01-01
    • 2016-02-22
    • 1970-01-01
    • 2019-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-25
    相关资源
    最近更新 更多