Android 恢复任务而不是特定活动的通知?

Android 恢复任务而不是特定活动的通知?,android,android-activity,notifications,Android,Android Activity,Notifications,我有一个前台服务,只要用户登录到应用程序,它就会保持与服务器的连接打开。这样,即使用户按Home键将应用程序发送到后台,连接仍保持活动状态,并可以直接从服务器接收消息 应用程序有许多活动,当它被发送到后台时,其中任何活动都可能是活动的 我希望允许用户单击通知以恢复当前活动。我了解如何恢复特定的活动,但想知道是否有方法恢复用户参与的最后一个活动?当然,我可以跟踪最后一个,然后从通知回调调用它,但我认为在任务级别可能有一种方法 感谢您提供的任何建议。您需要的只是一个简单的活动,它什么都不做。以下是一

我有一个前台服务,只要用户登录到应用程序,它就会保持与服务器的连接打开。这样,即使用户按Home键将应用程序发送到后台,连接仍保持活动状态,并可以直接从服务器接收消息

应用程序有许多活动,当它被发送到后台时,其中任何活动都可能是活动的

我希望允许用户单击通知以恢复当前活动。我了解如何恢复特定的活动,但想知道是否有方法恢复用户参与的最后一个活动?当然,我可以跟踪最后一个,然后从通知回调调用它,但我认为在任务级别可能有一种方法


感谢您提供的任何建议。

您需要的只是一个简单的活动,它什么都不做。以下是一个例子:

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中所建议的)


    有一个更简单的解决方案,不需要额外的活动。有关详细信息,请参阅。基本上,当应用程序位于后台时,通知启动(可能存在)任务的方式与单击启动器图标启动任务的方式相同。

    My solution,它模拟启动器的行为(将任务调到前台):

    这是可行的,毫无疑问,但问题是当你把你的意图设定为主要行动时。那么您将无法将任何捆绑设置为意图。我的意思是,您的原始数据将不会从目标活动接收,因为ACTION_MAIN不能包含任何额外的数据

    与此相反,您可以将活动设置为singleTask并正常调用您的意图,而无需设置ACTION_MAIN并从目标活动的onNewIntent()方法接收意图


    但是如果你打电话给super.onNewIntent(intent),请注意;然后将创建该活动的第二个实例。只是不要调用超级方法。

    我结合了David Wasser和Raginmari的解决方案,通过对应用程序的根活动进行这种方法,那么当应用程序已经启动或尚未启动时,它将适用于这两种情况

    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
            }
        }
    

    很好的回答,谢谢@DavidWasserWorks,但是很愚蠢的是,这个黑客是这个问题唯一可靠的解决方案。没有多少意图标志可以让你在API 16+中从最近的应用列表中可靠地恢复应用。现在这仍然是最好的主意吗?@ArchieG.Quiñones一般来说,更好的解决方案是使用“启动器
    intent
    ”,你可以通过调用
    PackageManager.getLaunchIntentForPackage(“my.package.name”)
    ,然而,这个解决方案并不是在所有情况下都能工作,如果它不能工作,调试可能会很困难。我的答案中的解决方案应该总是有效的,因为它不依赖于特殊的
    意图
    标志或启动模式。我一直在搜索这个。这是需要在文档中记录的解决方案。非常感谢!事实上,这个想法本身并不能在Android API 23Kudos for isTaskRoot()方法中可靠地工作。是的!谢谢你<出于某些奇怪的原因,需要代码>设置操作
    ,以允许不同的通知进入不同的类,因此需要您的解决方案。
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    intent.setClassName(MyApplication.class.getPackage().getName(), MainActivity.class.getName());
    
    Intent intent = new Intent(Intent.ACTION_MAIN);
    intent.addCategory(Intent.CATEGORY_LAUNCHER);
    
    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
            }
        }