如何将数据从广播员传递到开始的活动?
-
26-09-2019 - |
题
我有一个Android应用程序,需要全天偶然唤醒。
为此,我正在使用AlarmManager来设置悬浮词并触发广播员。然后,这位广播员开始了一项活动,将UI带到前景。
以上所有这些似乎都起作用,因为该活动正确地启动了自己。但是我希望广播员通知活动是由警报启动的(而不是由用户启动)。为此,我正在尝试,从广播员的OnReceive()方法中,在意图的附加捆绑包中设置一个变量,因此:
Intent i = new Intent(context, MyActivity.class);
i.putExtra(wakeupKey, true);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
在我的活动的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");
}
getIntent()。getExtras()在onResume()中呼叫始终返回null-我似乎根本无法通过此捆绑包中的任何附加功能。
但是,如果我使用相同的方法将额外的方法绑定到触发广播剂的悬浮材料中,则附加物可以通过良好。
谁能告诉我,将捆绑包从广播员转移到活动中而不是将捆绑包从活动转移到广播界的活动有何不同?我担心我可能在这里做一些非常明显的错误...
解决方案
只是为了清楚起见(因为我花了很多时间弄清楚如何使它起作用)
在扩展的服务类中 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
确保应用程序如果已经打开,则不会重新打开。这意味着首先打开您的活动的“旧”意图是重复使用的,它将不包含额外的值。您必须以另一种称为的方法来捕获它们 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
请注意这两个如果语句 - onResume()
不知道是否在 OnCreate()->OnStart() OR onRestart()->onStart()
请参见: http://www.anddev.org/images/android/activity_lifecycle.png
它只是用于测试用户是否启动了该应用程序(无额外的意图)还是由 BroadcastReceiver
(带有额外的意图)。
其他提示
然后,这位广播员开始了一项活动,将UI带到前景。
这可能是您在这里问题的关键。尝试覆盖 onNewIntent()
看看是否 Intent
传递给它有您的额外。如果是这样,那是因为您在清单中设置活动的方式(例如,您正在使用 singleTop
)以及在这种特定情况下已经存在的事实。
您可能还考虑摆脱 i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
看看这是否重要。
结果是您正在做的事情 - 将额外的额外放在 Intent
为了 startActivity()
- 应该工作正常。实际上,您可以看到其中的例子 这里. 。这表明这项活动很时髦(例如, singleTop
)或您调用活动的方式(例如, FLAG_ACTIVITY_NEW_TASK
).
编辑:
由于我的第一批镜头不起作用,因此在上面给出了您的“好奇”评论...
这有点像 PendingIntent
- 有了这些,除非您采取步骤,否则您将无法更新附加功能。
一时兴起,尝试添加一秒钟 <intent-filter>
在清单中的活动中,仅在一些独特的动作字符串上,然后尝试使用该活动从接收器开始您的活动。或者,只需将一些动作字符串扔进您的 Intent
接收器正在使用 startActivity()
, ,不弄乱清单。
代替 getIntent().getExtras().getBoolean(wakeupKey)
写作更常规 getIntent().getBooleanExtra(wakeupKey, defaultValue)
. 。我不确定这是否与您的问题有关,但是我不确定在GetExtras()中创建一个捆绑包有一些关系,因此无论如何都值得一试。
设置Flag 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);
只需覆盖像这样的onnewintent,捆绑量将在onResume方法中提供:
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}