Android - 构建通知,TaskStackBuilder.addParentStack不能正常工作

问题描述 投票:50回答:11

我正在尝试从Android docs说明的通知中启动活动,但是当我打开通知然后按后退按钮时,HomeActivity(父)不会打开,而应用程序关闭。我究竟做错了什么?

    Intent resultIntent = new Intent(context, MatchActivity.class);;
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);

    // Adds the back stack for the Intent (but not the Intent itself)
    stackBuilder.addParentStack(MainActivity.class);

    stackBuilder.addNextIntent(resultIntent);
android notifications
11个回答
91
投票

您需要为要启动的活动添加父堆栈,而不是其父项。

更换:

stackBuilder.addParentStack(MainActivity.class);

有:

stackBuilder.addParentStack( MatchActivity.class );

这假设您已在Manifest(API 16+)中定义了父级:

<activity android:name=".MatchActivity"
    android:parentActivityName=".MainActivity"
    ... />

如果您正在使用API​​ 16进行开发,那么您必须将父级定义为:

<activity android:name=".MatchActivity">
    <meta-data
        android:name="android.support.PARENT_ACTIVITY"
        android:value=".MainActivity" />
</activity>

0
投票

如果在项目中使用代码生成(如Dagger),MainActivity.class应替换为MainActivity_.class(或者您的父活动名称)。花了我一整天来弄明白这一点。希望这可以拯救某人的一天。


0
投票

如果您在manifest中的活动有下一个launchMode,也会发生这种情况:

<activity android:name=".SecondActivity"
     ...
         android:launchMode="singleInstance"
         android:parentActivityName=".MainActiviy"
    ...
/>

66
投票

如果没有一个解决方案正在运行,并且您确定已经仔细地遵循了所有内容......那么您需要卸载该应用并重新安装它。为我工作!


9
投票
Intent resultIntent = new Intent(App.getContext(), TargetActivity.class);
Intent backIntent = new Intent(App.getContext(), ParentActivity.class);
backIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
final PendingIntent resultPendingIntent = PendingIntent.getActivities(
                                    App.getContext(), 0, 
               new Intent[]{backIntent, resultIntent}, PendingIntent.FLAG_ONE_SHOT);
mNotifyBuilder.setContentIntent(resultPendingIntent);

这解决了Notification Click上父堆栈的问题


7
投票

使用TaskStackBuilder并没有解决我的问题,只适用于Honeycomb和更高版本。所以我采取以下解决方案(请不要将我钉在十字架上):

  1. 调用MainActivity而不是MatchActivity,将MatchActivity作为参数传递(通过Intent)。
  2. MainActivity.onCreate中,如果参数可用,则启动MatchActivity

新代码:

Intent resultIntent = new Intent(context, MainActivity.class) //
        .putExtra(MainActivity.ACTIVITY_EXTRA, MatchActivity.class.getName()) //
        .putExtra("Pass extras to MatchActivity", "if you want! :)");

PendingIntent pendingIntent = PendingIntent.getActivity(context, visitId, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Notification notification = new NotificationCompat.Builder(context) //
            .setContentIntent(pendingIntent) //
            .build();

MainActivity

public static final String ACTIVITY_EXTRA = "activity";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    if (getIntent().getStringExtra(ACTIVITY_EXTRA) != null) {
        startActivity(new Intent(getIntent()).setClassName(this, getIntent().getStringExtra(ACTIVITY_EXTRA)));
    }
    ...
}

3
投票

对我来说,stackBuilder.addParentStack不起作用。

我最终这样做,希望这可以帮助你。

    Intent intent = new Intent(context, MatchActivity.class);

    TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
    // Adds the back stack for the Intent
    stackBuilder.addNextIntentWithParentStack(new Intent(context, MainActivity.class));
    stackBuilder.addNextIntent(intent);
    PendingIntent pendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);

2
投票

您是否查看了Android文档,特别是Notifications API指南。它详细描述了如何执行此操作。

请注意,如果您从通知开始的活动不是正常活动流程的一部分,那么它不应该转到应用程序的开始页面;相反,它应该转到主屏幕。


1
投票

如其他答案中所述,TaskStackBuilder不适用于Honeycomb以下的版本。

我的解决方案是覆盖活动的onBackPressed()方法。

@Override
public void onBackPressed() {
    NavUtils.navigateUpFromSameTask(this);
}

显然,如果你计划以其他方式完成活动,你也必须处理这个问题。 (虽然我认为压倒finish()会有一些意想不到的行为)。


1
投票

您应该将此添加到AndroidManifest上的MainActivity:

<activity
   android:name=".MainActivity"
   android:allowTaskReparenting="true" />

0
投票

我有同样的问题!解决:

切换到

PendingIntent resultPendingIntent = 

PendingIntent.getActivity( this, 0, resultIntent, PendingIntent.FLAG_UPDATE_CURRENT);

PendingIntent resultPendingIntent = 

stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
© www.soinside.com 2019 - 2024. All rights reserved.