【问题标题】:Notification opens activity, back button pressed, main activity is opened?通知打开活动,按下后退按钮,打开主要活动?
【发布时间】:2011-11-28 16:33:16
【问题描述】:

我可以描述我的问题的最佳方式是这样的:

  1. 在启动时会创建一个通知(带有BroadcastReceiver)。
  2. 我的应用程序主活动已打开并按下主页按钮(应用程序仍在后台运行,直到系统关闭它)。
  3. 我拉下状态栏并按下之前在启动时创建的通知。
  4. 启动了一些不同于主要活动的活动。
  5. 我按下后退按钮并显示主要活动。

如何防止最后一步?我想要使​​用后退按钮回到原来的位置,即主屏幕(带有所有小部件和应用程序图标的桌面)。我的应用程序的主要活动应该在后台运行,为什么用返回按钮调用它?

如果相关,我创建通知的代码如下所示:

public void createNotification(int notifyId, int iconId, String contentTitle, String contentText) {
    Intent intent = new Intent(mContext, NewNoteActivity.class);
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    intent.putExtra(AgendaNotesAdapter.KEY_ROW_ID, (long)notifyId);

    PendingIntent contentIntent = PendingIntent.getActivity(mContext, notifyId, intent, 0);

    Notification notification = new Notification(iconId, contentTitle, 0);
    notification.setLatestEventInfo(mContext, contentTitle, contentText, contentIntent);

    mNotificationManager.notify(notifyId, notification);

我尝试向intent 添加更多标志组合,但它们都没有解决我的问题...建议?

【问题讨论】:

    标签: android notifications android-intent back-button android-pendingintent


    【解决方案1】:

    对于谁仍然可能需要答案。看起来这是您想要实现的目标:

    当您从通知启动Activity 时,您必须保留用户预期的导航体验。单击 Back 应该让用户通过应用程序的正常工作流程返回到主屏幕,单击 Recents 应该将 Activity 显示为单独的任务。

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

    你的情况是-Setting up a regular activity PendingIntent

    查看链接中的完整步骤。基本上你需要:
    1.在AndroidManifest.xml

    中定义Activity层次结构
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ResultActivity"
        android:parentActivityName=".MainActivity">
        <meta-data
            android:name="android.support.PARENT_ACTIVITY"
            android:value=".MainActivity"/>
    </activity>
    


    2.基于Intent创建一个back stack,它启动Activity

    ...
    Intent resultIntent = new Intent(this, ResultActivity.class);
    TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
    // Adds the back stack
    stackBuilder.addParentStack(ResultActivity.class);
    // Adds the Intent to the top of the stack
    stackBuilder.addNextIntent(resultIntent);
    // Gets a PendingIntent containing the entire back stack
    PendingIntent resultPendingIntent =
            stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
    ...
    NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setContentIntent(resultPendingIntent);
    NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(id, builder.build());
    

    【讨论】:

    • 这是最好的答案
    • 我在单击通知并打开活动并转到我的主屏幕时遇到问题,几秒钟后我发送新通知我将不再收到通知。使用上面的代码可以帮助我。谢谢!
    【解决方案2】:

    遇到了同样的问题。 对我有用的是在清单中为通知启动的活动设置以下属性:

    android:taskAffinity=""

    这基本上将通知活动的亲和性与主要活动分开,因此操作系统不需要“返回”到主要活动,而只是返回到之前的任何内容,例如“桌面”。

    【讨论】:

      【解决方案3】:

      我从您的问题中了解到,您的问题在于以下步骤

      1.启动完成后创建通知

      2.Main Activity 将在启动时调用

      3.你按下主页按钮,所以主要活动将停止但不会破坏

      4.您单击状态栏中的通知,以便您的application will be resume 以便您的后台堆栈中已经有主要活动,并且通知将创建新活动,就像您在问题中提到的那样 NewNoteActivity 活动将被推送到后台堆栈。所以在这一步you have two activities in back stack

      5.你按下后退按钮,last activity will be destroy 和你的main activity will be resume 但你想去主页屏幕。

      因此,我从您的问题中了解到,您的问题在于以下步骤

      1.启动完成后创建通知

      2.Main Activity 将在启动时调用

      3.你按下主页按钮,所以主要活动将停止但不会破坏

      4.您单击状态栏中的通知,以便您的application will be resume 以便您在后台堆栈中已经有主要活动,并且通知将创建新活动,就像您在问题中提到的那样 NewNoteActivity 活动将被推送到后台堆栈。所以在这一步you have two activities in back stack

      5.你按下返回按钮,last activity will be destroy 和你的main activity will be resume 但是你想在 NewNoteActivity 活动中按下返回按钮时打开主页活动。

      所以解决方案是,当您从 NewNoteActivityactivity 按下返回按钮时,您会使用 Intent.FLAG_ACTIVITY_CLEAR_TOP 标志再次启动主要活动,以便您的主要活动将重新创建并接收 onNewIntent() 方法,这样您就可以获得标志并完成主要活动

      例如

      @Override
          public void onBackPressed() {
              Intent i = new Intent(this, Main.class);
          i.putExtra("exit", true);
          i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
          startActivity(i);
          super.onBackPressed();
          }
      

      现在你必须在你的 Main Activity 中实现 onNewIntent() 方法

      在从 NewNoteActivity 活动按下后退按钮时,您的 Main 活动将调用 onNewIntent() 方法,因此在此方法中您必须获取从 NewNoteActivity 活动传递的标志变量。如果您获得标志并且如果它为真,则只需完成 Main活动,以便您获得主屏幕。

      编辑

      您是说您打开了来自 A、B 或 C 的任何活动,并且您按下了返回按钮,以便关闭此活动。如果当时您的堆栈中只有一个活动,您的应用程序将关闭意味着您将进入主屏幕。但是,如果您有多个活动并且按下后退按钮,则您在堆栈中至少有一个活动,现在您单击通知,这将打开一个与您的通知相关联的新活动,以便此活动将被推送到返回堆栈上。现在,如果您按下返回按钮,如果您没有修改该活动中的 onBackPressed() 方法,则与您的通知关联的最后一个活动将被关闭,然后如果有任何活动,它将检查返回堆栈在后台堆栈中,以便恢复活动,或者如果后台堆栈中没有活动,则您的应用程序将关闭,您将进入主屏幕

      【讨论】:

      • 差不多...问题是,我没有主页活动,你误会了。我的意思是我想回到主屏幕,桌面,那里有所有带有壁纸的小部件......
      • 这似乎可以工作,但它也看起来像一个肮脏的黑客。你说的都是有道理的,但我对这样的解决方案不满意,我不会使用它。但我相信它有效并解决了问题,因此我将其标记为已接受的答案。
      • 我实际上打算实施您的解决方案,但后来我意识到它并不能完全按照我的意愿工作。在上面的示例中,您使用Main.class,如果堆栈顶部活动不是“主要”怎么办?假设我有活动 A、B 和 C。如果这些活动中的任何一个被打开并且我按下后退按钮然后我单击通知并再次按下后退按钮,我不知道 A 中的哪一个, B 和 C 活动已打开以应用您发布的解决方法。还有其他解决方案吗?你会如何解决这个问题?
      【解决方案4】:

      我在我的应用程序中使用此解决方案。 覆盖 onBackPressed (在您从通知路由的活动中)并检查您的应用程序是否在堆栈中。如果没有,那么开始你的根活动。用户始终可以从您的根活动导航。这就是我在我的应用程序中所做的事情

      @Override
      public void onBackPressed() {
          if (isTaskRoot()) {
              Intent intent = new Intent(this,YourMainActivity.class);
              startActivity(intent);
              super.onBackPressed();
          }else {
              super.onBackPressed();
          }
      }
      

      【讨论】:

        【解决方案5】:

        它对我有用。试试这个:

        notifyIntent.setAction(Intent.ACTION_MAIN);
        notifyIntent.addCategory(Intent.CATEGORY_LAUNCHER);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-03-07
          相关资源
          最近更新 更多