如何将数据从 BroadcastReceiver 传递到正在启动的 Activity? [英] How do I pass data from a BroadcastReceiver through to an Activity being started?

查看:33
本文介绍了如何将数据从 BroadcastReceiver 传递到正在启动的 Activity?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 Android 应用程序,需要在一天中偶尔被唤醒.

I've got an Android application which needs to be woken up sporadically throughout the day.

为此,我使用AlarmManager 设置PendingIntent 并触发BroadcastReceiver.然后这个 BroadcastReceiver 启动一个 Activity 将 UI 带到前台.

To do this, I'm using the AlarmManager to set up a PendingIntent and have this trigger a BroadcastReceiver. This BroadcastReceiver then starts an Activity to bring the UI to the foreground.

以上所有似乎都有效,因为 Activity 可以正确启动;但我希望 BroadcastReceiver 通知 Activity 它是由警报启动的(而不是由用户启动).为此,我正在尝试从 BroadcastReceiver 的 onReceive() 方法在意图的附加包中设置一个变量,因此:

All of the above seems to work, in that the Activity launches itself correctly; but I'd like the BroadcastReceiver to notify the Activity that it was started by the alarm (as opposed to being started by the user). To do this I'm trying, from the onReceive() method of the BroadcastReceiver to set a variable in the extras bundle of the intent, thus:

    Intent i = new Intent(context, MyActivity.class);
    i.putExtra(wakeupKey, true);
    i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    context.startActivity(i);

在我的 Activity 的 onResume() 方法中,我然后寻找这个布尔变量的存在:

In the onResume() method of my Activity, I then look for the existence of this boolean variable:

protected void onResume() {
    super.onResume();

    String wakeupKey = "blah";      
    if (getIntent()!=null && getIntent().getExtras()!=null)
        Log.d("app", "onResume at " + System.currentTimeMillis() + ":" + getIntent().getExtras().getBoolean(wakeupKey));
    else
        Log.d("app", "onResume at " + System.currentTimeMillis() + ": null");
}

onResume() 中的 getIntent().getExtras() 调用总是返回 null - 我似乎无法在这个包中传递任何额外内容.

The getIntent().getExtras() call in onResume() always returns null - I don't seem to be able to pass any extras through at all in this bundle.

如果我使用相同的方法将附加项绑定到触发 BroadcastReceiver 的 PendingIntent,附加项就可以正常通过.

If I use the same method to bind extras to the PendingIntent which triggers the BroadcastReceiver however, the extras come through just fine.

谁能告诉我将包从 BroadcastReceiver 传递到 Activity 与将包从 Activity 传递到 BroadcastReceiver 有何不同?我担心我在这里可能做错了一些非常非常明显的错误...

Can anyone tell me what's different about passing a bundle from a BroadcastReceiver to an Activity, as opposed to passing the bundle from an Activity to a BroadcastReceiver? I fear I may be doing something very very obvious wrong here...

推荐答案

只是为了说清楚(因为我花了很多时间弄清楚如何让它工作)

Just to make it clear (because I used a lot of time figuring out how to make it work)

在扩展 BroadcastReceiver 的服务类中.在onReceive()

In the service class that extends BroadcastReceiver. Put in the following code in onReceive()

Intent intent2open = new Intent(context, YourActivity.class);
intent2open.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2open.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
String name = "KEY";
String value = "String you want to pass";
intent2open.putExtra(name, value);
context.startActivity(intent2open);

FLAG_ACTIVITY_SINGLE_TOP 确保应用程序在已经打开的情况下不会重新打开.这意味着首先打开 YourActivity 的旧"意图被重新使用,它不会包含额外的值.您必须在 YourActivity.

The FLAG_ACTIVITY_SINGLE_TOP makes sure the apps doesn't re-open if already open. This means that the "old" intent that opened YourActivity in the first place is re-used and it will NOT contain the extra values. You have to catch them in another method called onNewIntent() in YourActivity.

public class YourActivity extends Activity {
    private String memberFieldString;

    @Override
    public void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState);
         setContentView(R.layout.main);

         // Code doing your thing...
    } // End of onCreate()

    @Override
    protected void onNewIntent(Intent intent) {
    Log.d("YourActivity", "onNewIntent is called!");

    memberFieldString = intent.getStringExtra("KEY");

    super.onNewIntent(intent);
} // End of onNewIntent(Intent intent)

    @Override
    protected void onResume() {
        if (memberFieldString != null) {
            if (opstartsIntent.getStringExtra(KEY) != null) {
               Log.d("YourActivity", "memberFieldString: "+ memberFieldString);
            } else {
               Log.d("YourActivity", "The intent that started YourActivity did not have an extra string value");
            }
        }
    } // End of onResume()

}  // End of YourActivity

请注意两个 if 语句 - onResume() 不知道它是在 OnCreate()->OnStart() 还是 onRestart()->onStart() 之后调用的
请参阅: http://www.anddev.org/images/android/activity_lifecycle.png

Please note the two if statements - the onResume() does not know if it's called after OnCreate()->OnStart() OR onRestart()->onStart()
Please see: http://www.anddev.org/images/android/activity_lifecycle.png

它只是用来测试应用是由用户启动的(没有额外的意图)还是由BroadcastReceiver(有额外的意图)启动.

It's just used to test if the app is launched by the user (intent with no extras) OR by the BroadcastReceiver (intent with extras).

这篇关于如何将数据从 BroadcastReceiver 传递到正在启动的 Activity?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆