9

我有一个 Android 应用程序需要全天偶尔唤醒。

为此,我使用 AlarmManager 来设置 PendingIntent 并让它触发一个 BroadcastReceiver。然后此 BroadcastReceiver 启动一个 Activity 以将 UI 带到前台。

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

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

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

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 - 我似乎无法在此捆绑包中传递任何额外内容。

但是,如果我使用相同的方法将额外内容绑定到触发 BroadcastReceiver 的 PendingIntent,那么额外内容就可以了。

谁能告诉我将包从广播接收器传递到活动与将包从活动传递到广播接收器有什么不同?我担心我可能在这里做一些非常明显的错误......

4

5 回答 5

30

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

在扩展的服务类中BroadcastReceiver。将以下代码放入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 的“旧”意图被重新使用,它不会包含额外的值。您必须在另一个调用onNewIntent()的方法中捕获它们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() OR onRestart()->onStart()
请参阅: http ://www.anddev.org/images/android/activity_lifecycle.png

它仅用于测试应用程序是由用户启动(没有额外的意图)还是由BroadcastReceiver(有额外的意图)启动。

于 2011-07-28T10:41:18.420 回答
5

然后此 BroadcastReceiver 启动一个 Activity 以将 UI 带到前台。

这可能是您问题的症结所在。尝试覆盖onNewIntent()并查看Intent传递给它的是否有额外的。如果是这样,那是因为您在清单中设置活动的方式(例如,您正在使用singleTop)以及在这种特定情况下,活动已经存在的事实。

你也可以考虑摆脱,i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);看看改变是否重要。

结果是你正在做的事情——把额外的放在Intentfor 中startActivity()——应该工作得很好。事实上,您可以在此处查看相关示例。这表明活动(例如,singleTop)或您调用活动的方式(例如, )有些奇怪FLAG_ACTIVITY_NEW_TASK

编辑:

由于我的第一枪没有用,并且在上面给出了您的“好奇”评论...

这感觉有点像PendingIntent- 有了这些,除非您采取措施,否则您将无法更新额外内容。

一时兴起,尝试<intent-filter>在清单中为您的活动添加一秒钟,只是在一些独特的操作字符串上,并尝试使用它从您的接收器开始您的活动。或者,只需将一些操作字符串扔到Intent接收者正在使用的您的 for 中startActivity(),而不会弄乱清单。

于 2010-04-11T11:48:41.983 回答
2

而不是getIntent().getExtras().getBoolean(wakeupKey)更传统的写法getIntent().getBooleanExtra(wakeupKey, defaultValue)。我不能确定这是否与您的问题有关,但是在 getExtras() 中创建一个包有一些事情我不确定,所以无论如何它可能值得一试。

于 2010-04-11T11:45:19.837 回答
1

设置标志 SingleTop 有效(不要与其他标志混合)

Intent intent = new Intent(ContextManager.getContext(),OrderList.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Bundle bundle = new Bundle();       

bundle.putString("username",username);
bundle.putString("password",password);

intent.putExtras(bundle);
startActivityForResult(intent,0); 
于 2011-02-23T06:25:14.487 回答
0

只需像这样覆盖 onNewIntent 并且 Bundle 变量将在 onresume 方法中可用:

@Override
protected void onNewIntent(Intent intent) {
    super.onNewIntent(intent);
    setIntent(intent);
}
于 2012-12-31T13:23:59.237 回答