1

这看起来与my previous question非常相似,因为它是某种跟进。我对所给出的唯一解决方案并不满意,此外,该解决方案与此问题稍有不同。因此,让我试着再次解释问题...通知打开活动,按回按钮,防止打开回栈活动?

  1. 通知在启动时创建(使用BroadcastReceiver)。
  2. 我的app主要活动被打开并且主页按钮被按下(活动将被发送到后退堆栈)。
  3. 我拉下状态栏并按下之前在启动时创建的通知。
  4. 这将开始一些活动,与主要活动不同。
  5. 我按下后退按钮,显示主要活动。

这与我以前的问题没什么不同......事情是,“主要活动”只是一个例子。我可以打开应用程序的主要活动,然后通过菜单选项打开有关活动并按下主页按钮。后端堆栈现在是MainActivity»AboutActivity。这意味着当在“某些活动”(通过按通知开始)中按下后退按钮时,我们将被带到返回栈的顶部,即关于活动。

基本上想要的是当我在“某些活动”(同样,通过按通知开始)时按下后退按钮时,防止打开任何其他活动。我希望被带到我所在的位置,这可能是桌面或其他应用程序的活动,但不是我的应用程序的MainActivityAboutAcitivity,这不是我所在的位置,那些位于后台堆栈中,在后台“睡眠”。

我已经想出了一个解决方案,但我认为它不是很优雅,我正在寻找更多,更好,更优雅的东西......如果您有任何其他建议,请告诉我。

无论如何,这是我提出的解决方案:

// I use this class for public static (or public static final) members and 
// methods 

public final class AppHelper { 
    public static final String KEY_RESUME_FROM_NOTIFICATION = "resumeFromNotification"; 

    private static boolean sResumeFromNotification = false; 

    public static boolean getResumeFromNotification() { 
     return sResumeFromNotification; 
    } 

    public static void setResumeFromNotification(boolean resumeFromNotification) { 
     sResumeFromNotification = resumeFromNotification; 
    } 
} 

public class MainActivity extends ListActivity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     (...) 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if(AppHelper.getResumeFromNotification()) { 
      AppHelper.setResumeFromNotification(false); 
      moveTaskToBack(true); 
     } 
    } 

} 

public class AboutActivity extends Activity { 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     (...) 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 

     if(AppHelper.getResumeFromNotification()) { 
      AppHelper.setResumeFromNotification(false); 
      moveTaskToBack(true); 
     } 
    } 

} 

public class SomeActivity extends Activity { 

    // This will be called when the notification is pressed and the activity is 
    // not opened yet 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     (...) 

     extractIntentExtras(intent); 
    } 

    // This will be called if the activity is already opened and the 
    // notification is pressed 

    @Override 
    protected void onNewIntent(Intent intent) { 
     extractIntentExtras(intent); 
     super.onNewIntent(intent); 
    } 

    private void extractIntentExtras(Intent intent) { 
     Bundle bundleExtras = intent.getExtras(); 

     if(bundleExtras != null) { 
      // These intent extras are set on the Intent that starts this activity 
      // when the notification is pressed 

      AppHelper.setResumeFromNotification(bundleExtras.getBoolean(
       AppHelper.KEY_RESUME_FROM_NOTIFICATION)); 

      mRowId = bundleExtras.getLong(AgendaNotesAdapter.KEY_ROW_ID); 
      populateNoteUpdateFields(); 
     } 
    } 

} 

我不知道,但这种方法看起来不是很优雅,我(但它的作品,因为我希望它),我期待作为替代方案或对我提议的解决方案提出强烈意见作为可接受的良好解决方案思考?

+0

你有任何特殊的标志,你用于你的活动? singleTop/singleInstance或类似的东西?我没有看到您提到的活动,因为通知应始终在新任务堆栈中开始您的活动(它们需要FLAG_ACTIVITY_NEW_TASK标志)。 –

+0

我在'MainActivity'(清单中)有'singleTop',没有别的。我一直对FLAG_ACTIVITY_NEW_TASK标志感到困惑。无论标志是否设置,通知开始的活动都可以工作。我应该使用它吗? –

+0

从我所了解的情况来看,应该始终为通知中的活动设置。在你的情况下,你一定希望它被设置,因为你不希望你的通知活动成为你正常任务堆栈的一部分。 –

回答

4

做一些更多的阅读后,也许这就是你需要标志的组合:

Intent intent = new Intent(mContext, SomeActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_MULTIPLE_TASK); 
startActivity(intent); 

我认为应该强制在一个完全新的任务将推出你的SomeActivity类。

+0

是的,这和我预期的完全一样。实际上,它需要一个额外的标志才能更好地工作,这就是'FLAG_ACTIVITY_SINGLE_TOP'。这只是当我打开一个通知然后打开另一个通知时,活动被重新加载而不是正在创建的新活动。我从来没有尝试多任务标志,因为[文档](http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_MULTIPLE_TASK)中的所有粗体“警告”。我真的应该使用它吗?我没有实现顶级启动器... –

+0

FLAG_ACTIVITY_SINGLE_TOP仅适用于当您不希望SomeActivity被打开时(如果它已经在最前面)。这是你的愿望吗?另外,我认为你是专门尝试创建一个完全脱离Main和About活动任务的任务。使用FLAG_ACTIVITY_MULTIPLE_TASK是确保发生的唯一方法。 –

+0

是的,我现在认识到,国旗是确保我所寻找的行为的唯一途径。我想我只是有点害怕关于该标志的文档警告。 –

-1

从通知启动活动时,您可以控制将要打开的活动如何放置在后退堆栈上以及与意向标志相关联的任务。您可以尝试类似:

Intent intent = new Intent(mContext, SomeActivity.class); 
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 
startActivity(intent); 

如果还是不行,请尝试设置几个other flags,直到你获得所需的行为。

+0

没有国旗做这项工作......我已经尝试了很多,很多组合,既不能解决问题。 –

+0

从您的启动Activity中移除singleTop。 –

+0

为什么?那会做什么? –

-1

你是否想过MainActivity留在历史中?如果没有,那么我简单粗略的解决方案就是在暂停时完成MainActivity。 (这个在您的MainActivity)

@Override 
public void onPause() { 
    finish(); 
} 

这将确保您的MainActivity从历史,当您导航远离它取出,并按下后退按钮时,会不会出现。 这也可以用于AboutActivity。