【问题标题】:Back to main activity from notification-created activity从通知创建的活​​动返回主活动
【发布时间】:2012-12-10 12:10:23
【问题描述】:

我正在尝试实现here 描述的行为,其中通知(或其他)在您的应用程序中启动“内部”活动,然后当用户按下它时,它会转到我的“家庭”活动。

Android 文档说

在返回按钮的情况下,您应该使导航更多 可预测的通过将完整的插入任务的回栈 向上导航到应用最顶部屏幕的路径。这允许用户 谁忘记了他们是如何进入您的应用程序以导航到应用程序的 退出前的最上面的屏幕。

有没有什么好方法可以真正做到这一点? Stackoverflow 上的其他问题建议以告诉它启动内部活动的意图来启动主要活动,但这似乎是一个巨大的黑客攻击,我有点怀疑谷歌会在 Gmail 中使用它,我认为有一个不错的方法,给定他们正在倡导这种行为。

那么有没有一种简单的方法可以做到这一点?

【问题讨论】:

    标签: android


    【解决方案1】:

    啊哈,我只需要使用PendingIntent.getActivities() 而不是getActivity()。另外值得一提的是TaskStackBuilder

    这里有一些代码:

        Intent backIntent = new Intent(ctx, MainActivity.class);
        backIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    
        Intent intent = new Intent(ctx, ConversationActivity.class);
        intent.putExtra("whatever", whatever);
        final PendingIntent pendingIntent = PendingIntent.getActivities(ctx, UNIQUE_REQUEST_CODE++,
                new Intent[] {backIntent, intent}, PendingIntent.FLAG_ONE_SHOT);
    

    刚刚测试过。它就像一个魅力。我最初怀疑如果应用程序已经在运行,可能会出现问题,然后你去通知。 IE。假设你的活动堆栈是(最右边):

    [MainActivity] [SomeActivity]
    

    然后您单击ConversationActivity 的通知。你会得到:?

    [MainActivity] [SomeActivity] [MainActivity] [ConversationActivity]
    

    好吧,事实证明你神奇地得到了

    [MainActivity] [SomeActivity] [ConversationActivity]
    

    这是我想要的,但我不知道它是如何做到的。我没有对任何活动设置任何特殊选项。哦,好吧!

    【讨论】:

    • 遗憾的是,这似乎对我不起作用。我的 MainActivity 确实再次被推送到导航堆栈上,并且它只对一个通知有效一次(我不会自动关闭它们)。有什么想法吗?
    • @bompf,这可能是因为在PendingIntent.getActivities 中使用了PendingIntent.FLAG_ONE_SHOT。我建议改为PendingIntent.FLAG_CANCEL_CURRENT
    • 谢谢;这对我有用,而TaskStackBuilder 似乎没有用。但是,您的代码导致了一个奇怪的情况:如果我通过启动器打开MainActivity,然后从通知中打开操作,在按下后退按钮返回到MainActivity 后,按下后​​退按钮会导致它转到MainActivity 再次。像这样:[MainActivity] [MainActivity] [ConversationActivity]。我通过将您的第二行代码更改为 backIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK) 来修复它。
    • 太棒了! TaskStackBuilder 不适合我 (developer.android.com/guide/topics/ui/notifiers/…),但是懒惰就是懒惰......
    【解决方案2】:

    有一个关于如何做到这一点的新指南,它提出了一些与上述答案略有不同的做法:

    https://developer.android.com/guide/topics/ui/notifiers/notifications.html#NotificationResponse

    注意,实际上不要将0 用于getPendingIntent 中的requestCode。对我来说,任何不是 0 的数字都有效,但 0 会导致返回按钮进入启动器。

    【讨论】:

    • 这是唯一对我有用的解决方案,谢谢先生!
    • 这真的很有帮助。按照 Android 文档中的说明而不更改 requestCode 不起作用
    【解决方案3】:

    我知道实现此目的的两种方法:

    1. 从通知启动的活动中开始您的home activity。这可能会变得很棘手,因为您必须区分并跟踪各种可能的入口点。
    2. 你总是从home activity开始,它会检查是否被通知启动,然后启动notification activity。这确保了一致的入口点,并且当用户按下 Up 键时返回堆栈将在那里。

    问候。

    【讨论】:

      【解决方案4】:
      Intent displayIntent = new Intent(getApplicationContext(), TargetActivity.class);
      
      displayIntent.putExtra("extra_id", "extra_key");
      
      TaskStackBuilder stackBuilder = TaskStackBuilder.create(getApplicationContext());
      stackBuilder.addParentStack(TargetActivity.class);
      stackBuilder.addNextIntent(displayIntent);
      stackBuilder.editIntentAt(1).putExtra("extra_id", "extra_key");
      
      PendingIntent contentIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
      
      NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
              getApplicationContext(), "123").setSmallIcon(R.drawable.logo)
              .setContentTitle("GCM Notification")
              .setStyle(new NotificationCompat.BigTextStyle().bigText("Sample")).setContentText("sample text");
      
      mBuilder.setContentIntent(contentIntent);
      
      NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
      mNotificationManager.notify(456, mBuilder.build());
      stackBuilder.startActivities();
      

      除了上述代码之外,还要在您的AndroidManifest.xml 文件中提供适当的父类名称。

      【讨论】:

        【解决方案5】:

        这个解决方案非常适合这个问题

        android:noHistory="true"
        

        【讨论】:

        • 在哪里添加这个?
        【解决方案6】:
        【解决方案7】:

        不错。

        但请注意,它不适用于 3.0 之前(API 级别 11 之前)系统,因为 PendingIntent.getActivities() 在那里不可用。

        这对于构造一个 backstack 以从通知(通过 Intent)访问 Activity 并让后退按钮的行为与您的应用程序一致(例如,详细活动返回到列表活动)是相同的。

        【讨论】:

          【解决方案8】:

          活动与一个任务相关联,该任务不过是后台堆栈中的一组活动。当您在单击通知时打开新活动时,该活动将作为独立活动打开并放入新任务中。这意味着只有通知活动和父活动存在。

          只需在清单文件中将活动的启动模式指定为“标准”即可解决问题。

          Intent resultIntent = new Intent(getApplicationContext(),
                                  ResultActivity.class);
          
          PendingIntent resultPendingIntent =
              PendingIntent.getActivity(getApplicationContext(),0,resultIntent,PendingIntent.FLAG_UPDATE_CURRENT);
          
          mBuilder.setContentIntent(resultPendingIntent); 
          
          NotificationManager mNotificationManager = (NotificationManager)
              getSystemService(Context.NOTIFICATION_SERVICE);
          mNotificationManager.notify(notId, mBuilder.build());
          

          清单:

          <activity
                      android:name="com.mns.exercisenotifications.ResultActivity"
                      android:label="@string/app_name"
                      android:launchMode="standard" >  <---
                      <intent-filter>
                          <action android:name="com.mns.exercisenotifications.ResultActivity" />
                          <category android:name="android.intent.category.DEFAULT" />
                      </intent-filter>
          
           </activity>
          

          【讨论】:

            【解决方案9】:

            只需将此行添加到您的清单中。

            <activity
                android:name=".YourActivity"
                android:launchMode="singleTask"
                android:taskAffinity=""
                android:excludeFromRecents="true">
            </activity>
            

            如需完整指南,请参阅https://developer.android.com/training/notify-user/navigation

            【讨论】:

            • 我很确定 singleTask 不会阻止同一任务中的多个活动实例。
            【解决方案10】:

            我知道我迟到了,但这可能会对某人有所帮助。
            只需为要使用通知打开的活动创建一个意图。 然后将Intent.FLAG_ACTIVITY_NEW_TASKIntent.FLAG_ACTIVITY_CLEAR_TASK 设置为标志。
            然后您需要做的就是创建一个PendingIntent,并以您的意图作为参数。

            这是一个代码示例:

            Intent intent = new Intent(this, NotificationActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-12-31
              • 1970-01-01
              • 1970-01-01
              • 2013-02-17
              • 1970-01-01
              • 2016-09-20
              相关资源
              最近更新 更多