Android Up Navigation Doesn't Work
I'm trying to implement navigation according to: http://developer.android.com/training/implementing-navigation/ancestral.html
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
// Respond to the action bar's Up/Home button
case android.R.id.home:
Intent upIntent = NavUtils.getParentActivityIntent(this);
if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
// This activity is NOT part of this app's task, so create a new task
// when navigating up, with a synthesized back stack.
TaskStackBuilder.create(this)
// Add all of this activity's parents to the back stack
.addNextIntentWithParentStack(upIntent)
// Navigate up to the closest parent
.startActivities();
} else {
// This activity is part of this app's task, so simply
// navigate up to the logical parent activity.
NavUtils.navigateUpTo(this, upIntent);
}
return true;
}
return super.onOptionsItemSelected(item);
}
but if (NavUtils.shouldUpRecreateTask(this, upIntent)) {
is returning FALSE always.
How is this code useful? In which cases it does return true?
On pre-Jelly Bean devices, per the source code of NavUtils, shouldUpRecreateTask
is:
public boolean shouldUpRecreateTask(Activity activity, Intent targetIntent) {
String action = activity.getIntent().getAction();
return action != null && !action.equals(Intent.ACTION_MAIN);
}
Which uses the Activity
's action (ie, ACTION_VIEW
, etc.) to determine if this Activity
was launched from an external source. On Jelly Bean+ devices, it uses Activity.shouldUpRecreateTask
(source code):
public boolean shouldUpRecreateTask(Intent targetIntent) {
try {
PackageManager pm = getPackageManager();
ComponentName cn = targetIntent.getComponent();
if (cn == null) {
cn = targetIntent.resolveActivity(pm);
}
ActivityInfo info = pm.getActivityInfo(cn, 0);
if (info.taskAffinity == null) {
return false;
}
return !ActivityManagerNative.getDefault()
.targetTaskAffinityMatchesActivity(mToken, info.taskAffinity);
} catch (RemoteException e) {
return false;
} catch (NameNotFoundException e) {
return false;
}
}
Which uses Task Affinity to determine if the given Activity
's affinity is the same as the affinity it was launched with (ie, if Gmail launches your Activity
, it would be given Gmail's affinity, rather than its own).
NavUtils.navigateUpTo
, in all cases, launches an Activity. If it isn't launching the appropriate Activity
, then you may need to look at what launch mode you are using and provide details on what platform version it isn't working.
I solved it by using the ActivityManager and checking for the backStack entries.
I hope it will be usefull for you all.
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
ActivityManager am = (ActivityManager) getApplicationContext().getSystemService(getApplicationContext().ACTIVITY_SERVICE);
List<RunningTaskInfo> runningTaskInfoList = am.getRunningTasks(10);
List<String> backStack = new ArrayList<String>();
Iterator<RunningTaskInfo> itr = runningTaskInfoList.iterator();
while(itr.hasNext()){
RunningTaskInfo runningTaskInfo = (RunningTaskInfo)itr.next();
String topActivity = runningTaskInfo.topActivity.getShortClassName();
backStack.add(topActivity.trim());
}
if(backStack!=null){
if(backStack.get(1).equals(".MainActivity")){
moveTaskToBack(true); // or finish() if you want to finish it. I don't.
} else {
Intent intent = new Intent(this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
finish();
}
}
break;
}
}
And I needed to use:
<uses-permission android:name="android.permission.GET_TASKS" />
in my Manifest.
It works perfectly, though it's not the solution I would have wanted. Unfortunately, android is still lacking of advanced built-in methods to achieve simple things, and we all have to find the way of everything.
链接地址: http://www.djcxy.com/p/72470.html上一篇: JQuery mCustomScrollbar autoScrollOnFocus
下一篇: Android向上导航不起作用