该应用程序有多个Activity,在被置于后台时,任何一个Activity都可能是活动的。
我想允许用户单击通知以恢复当前的Activity。我知道如何恢复特定的Activity,但不确定是否有一种方法可以恢复用户上次所在的Activity?当然,我可以跟踪上次所在的Activity,然后从通知回调中调用它,但想知道是否有一种在任务级别上实现的方法?
感谢您提供的任何建议。
你所需要的仅仅是一个什么都不做的简单 Activity。这里有一个示例:
public class NotificationActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Now finish, which will drop the user in to the activity that was at the top
// of the task stack
finish();
}
}
设置通知以启动此活动。请确保在清单中此活动的任务关联与应用程序中其他活动的任务关联相同(如果没有明确设置android:taskAffinity,则默认情况下是相同的)。
当用户选择此通知时,如果您的应用程序正在运行,则NotificationActivity将在应用程序任务中位于最顶部的活动上启动,并将该任务带到前台。当NotificationActivity完成时,它将简单地将用户返回到应用程序中位于最顶部的活动(即:当应用程序进入后台时离开的位置)。
如果您的应用程序尚未运行,则此方法将不起作用。但是,您有两个选项来解决这个问题:
确保当您的应用程序未运行时,通知栏中不存在该通知。
在NotificationActivity的onCreate()方法中检查您的应用程序是否正在运行,如果没有运行则调用startActivity()并启动您的应用程序。如果您这样做,请务必在启动应用程序时设置标志Intent.FLAG_ACTIVITY_NEW_TASK,以便任务的根活动不是NotificationActivity。
非常有效,谢谢David! 以下类检查应用程序是否已经在运行,如果没有,则在完成之前启动它(如选项2中所建议的)。
public class NotificationActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// If this activity is the root activity of the task, the app is not running
if (isTaskRoot())
{
// Start the app before finishing
Intent startAppIntent = new Intent(getApplicationContext(), MainActivity.class);
startAppIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(startAppIntent);
}
finish();
}
}
有一个更简单的解决方案,不需要额外的操作。请参见此文章以获取详细信息。基本上,通知会像在应用程序在后台时单击启动器图标时一样启动(可能存在的)任务。
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
这种方法确实有效,没有任何疑问,但问题在于当你将intent设置为ACTION_MAIN时。此时你将无法向intent中添加任何bundle。我的意思是,因为ACTION_MAIN不能包含任何额外数据,所以你的原始数据将无法从目标活动中接收。
相反,你可以将你的活动设置为singleTask,并正常调用你的意图,而不需要设置ACTION_MAIN,并从目标活动的onNewIntent()方法中接收意图。
但要注意,如果你调用super.onNewIntent(intent);那么将会创建第二个活动实例。只需不调用super方法即可。
setAction
函数因某些奇怪的原因而需要,以允许不同的通知发送到不同的类,因此您的解决方案是必需的。 - behelit我的解决方案模拟启动器的行为(将任务置于前台):
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClassName(MyApplication.class.getPackage().getName(), MainActivity.class.getName());
public class YourRootActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
if (!isTaskRoot()) // checks if this root activity is at root, if not, we presented it from notification and we are resuming the app from previous open state
{
val extras = intent.extras // do stuffs with extras.
finish();
return;
}
// OtherWise start the app as usual
}
}
Intent
”,您可以通过调用PackageManager.getLaunchIntentForPackage("my.package.name")
来获取它。但是,这种解决方案并不适用于所有情况,如果它不起作用,调试可能会很困难。我的答案中的解决方案应该始终有效,因为它不依赖于特殊的Intent
标志或启动模式。 - David Wasser