Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NavUtils.navigateUpTo() does not start any Activity

I have two activities

  • MainActivity
  • DeepLinkActivity

I set up everything to use the NavUtils for navigating up like advised here, here and here.

What I want to achieve is:

  1. Start DeepLinkActivity via a deep link
  2. Press up
  3. Go to MainActivity

Everything works nicely as long as there is any task of my app in the recent apps.

However, when I swipe away my app from the recent apps, it behaves like this:

  1. Swipe away my app from recent apps
  2. Start DeepLinkActivity via a deep link
  3. Press up
  4. My app closes, like when pressing back

I debugged the code, and found out, that NavUtils.shouldUpRecreateTask() returns false. upIntent has everything set to normal, like my Component set. But still, NavUtils.navigateUpTo() behaves just like a call to finish(). No log statement, nothing.

Any ideas, how to fix that?

AndroidManifest.xml

<activity     android:name=".DeepLinkActivity"     android:parentActivityName="my.package.MainActivity">     <meta-data         android:name="android.support.PARENT_ACTIVITY"         android:value="my.package.MainActivity"/>     <intent-filter>         <!-- Some intent filter -->     </intent-filter> </activity> 

DeepLinkActivity.java

@Override public boolean onOptionsItemSelected(final MenuItem item) {     switch (item.getItemId()) {         case android.R.id.home:             Intent upIntent = NavUtils.getParentActivityIntent(this);             if (NavUtils.shouldUpRecreateTask(this, upIntent)) {                 // create new task                 TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent)                         .startActivities();             } else {                 // Stay in same task                 NavUtils.navigateUpTo(this, upIntent);             }             return true;         default:             return super.onOptionsItemSelected(item);     } } 

----- Edit -----

I realized that a few Google Apps are broken in the same way. If you jump e.g. to Contacts from search, press up in AB and you'll find yourself on the home screen instead of the contacts app. (API19/cm11)

like image 594
flx Avatar asked Nov 15 '13 11:11

flx


2 Answers

My solution to OPs problem:

public void navigateUp() {     final Intent upIntent = NavUtils.getParentActivityIntent(this);     if (NavUtils.shouldUpRecreateTask(this, upIntent) || isTaskRoot()) {         Log.v(logTag, "Recreate back stack");         TaskStackBuilder.create(this).addNextIntentWithParentStack(upIntent).startActivities();     } else {         NavUtils.navigateUpTo(this, upIntent);     } } 

isTaskRoot() will return true if DeepLinkActivity is the root of a task (initial launch of application or application was previously terminated through task manager). This way I'm not loosing existing back stack if activity was launched through link when applications task was already in the foreground.

like image 161
Sokolov Avatar answered Sep 30 '22 06:09

Sokolov


I think that method is bugged. I've read support library source code, and that method check for intent's action. It only works when your App was previously created..as you've described, if you kill it from Apps preview, shouldUp method stops working.

I've fixed this using my own "shouldUpRecreateTask". When I receive a Notification that creates directly an Activity (Like your behaviour), I send from my BroadCastReceiver a custom Action inside the intent. Then, in my Method I do the next thing:

private final boolean shouldUpRecreateTask(Activity from){     String action = from.getIntent().getAction();     return action != null && action.equals(com.xxxxxx.activities.Intent.FROM_NOTIFICATION); } 

..........................

 if (shouldUpRecreateTask(this)) {       TaskStackBuilder.create(this)        .addNextIntentWithParentStack(upIntent)        .startActivities();  } else {        fillUpIntentWithExtras(upIntent);        NavUtils.navigateUpTo(this, upIntent);  } 
like image 45
noni Avatar answered Sep 30 '22 06:09

noni