挂起意图不发送意图额外信息

我的 MainActicityIntent开始 RefreshServiceIntent还有一个额外的 boolean,称为 isNextWeek

我的 RefreshService制作了一个 Notification,当用户点击它时,它就会启动我的 MainActivity

这个看起来像这样:

    Log.d("Refresh", "RefreshService got: isNextWeek: " + String.valueOf(isNextWeek));


Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);


Log.d("Refresh", "RefreshService put in Intent: isNextWeek: " + String.valueOf(notificationIntent.getBooleanExtra(MainActivity.IS_NEXT_WEEK,false)));
pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);


builder = new NotificationCompat.Builder(this).setContentTitle("Title").setContentText("ContentText").setSmallIcon(R.drawable.ic_notification).setContentIntent(pendingIntent);
notification = builder.build();
// Hide the notification after its selected
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(NOTIFICATION_REFRESH, notification);

正如你可以看到的 notificationIntent应该有 boolean额外的 IS_NEXT_WEEK与价值的 isNextWeek是放在 PendingIntent

当我现在点击这个 Notification时,我总是得到 false作为 isNextWeek的值

这是我得到 MainActivity值的方法:

    isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);

日志:

08-04 00:19:32.500  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity sent: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService got: isNextWeek: true
08-04 00:19:32.510  13367-13573/de.MayerhoferSimon.Vertretungsplan D/Refresh: RefreshService put in Intent: isNextWeek: true
08-04 00:19:41.990  13367-13367/de.MayerhoferSimon.Vertretungsplan D/Refresh: MainActivity.onCreate got: isNextWeek: false

当我用一个带有 ìsNextValue 的 Intent直接启动 MainActivity时,像这样:

    Intent i = new Intent(this, MainActivity.class);
i.putExtra(IS_NEXT_WEEK, isNextWeek);
finish();
startActivity(i);

一切正常,当 isNextWeektrue时,我得到 true

我犯了什么错误,总是有一个 false值?

更新

这就解决了问题: Https://stackoverflow.com/a/18049676/2180161

语录:

我的怀疑是,因为唯一改变意图的是 额外的,PendingIntent.getActivity(...)工厂的方法是 简单地重用旧的意图作为优化。

在 RefreshService 中,请尝试:

PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT);

参见:

Http://developer.android.com/reference/android/app/pendingintent.html#flag_cancel_current

更新2

请参阅 回答如下为什么使用 PendingIntent.FLAG_UPDATE_CURRENT更好。

47943 次浏览

下面的代码应该可以工作:-

int icon = R.drawable.icon;
String message = "hello";
long when = System.currentTimeMillis();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification(icon, message, when);


Intent notificationIntent = new Intent(context, MainActivity.class);
notificationIntent.putExtra("isNexWeek", true);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, title, message, pIntent);
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, notification);

在 MainActivity onCreate:

if (getIntent().getExtras() != null && getIntent().getExtras().containsKey("isNextWeek")) {
boolean isNextWeek = getIntent().getExtras().getBoolean("isNextWeek");
}

我认为你需要更新的 Intent当你收到一个新的通过覆盖你的活动的 onNewIntent(Intent)。在你的活动中加入以下内容:

@Override
public void onNewIntent(Intent newIntent) {
this.setIntent(newIntent);


// Now getIntent() returns the updated Intent
isNextWeek = getIntent().getBooleanExtra(IS_NEXT_WEEK, false);
}

编辑:

只有当接收到意图时,您的活动已经启动时,才需要这样做。如果您的活动是由意图启动的(而不仅仅是恢复的) ,那么问题在其他地方,我的建议可能无法解决它。

使用 PendingInent.FLAG _ CANCEL _ CURRENT 不是一个好的解决方案,因为它没有充分利用内存。

还可以使用 < a href = “ https://developer.android.com/reference/android/content/Inent.html? hl = ru # FLAG _ ACTIVITY _ SINGLE _ TOP”rel = “ noReferrer”> Inent.FLAG _ ACTIVITY _ SINGLE _ TOP (如果活动已经在历史堆栈顶部运行,则不会启动该活动)。

Intent resultIntent = new Intent(this, FragmentPagerSupportActivity.class).
addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
resultIntent.putExtra(FragmentPagerSupportActivity.PAGE_NUMBER_KEY, pageNumber);


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

然后:

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


int startPageNumber;
if ( savedInstanceState != null)
{
startPageNumber = savedInstanceState.getInt(PAGE_NUMBER_KEY);
//so on

现在应该可以了。


如果您仍然没有预期的行为,尝试实现 void onNewIntent(Intent intent)事件处理程序,这样您就可以访问为该活动调用的新意图(这不同于仅仅调用 getInent ()) ,这将总是返回启动您的活动的第一个意图。

@Override
protected void onNewIntent(Intent intent) {
int startPageNumber;


if (intent != null) {
startPageNumber = intent.getExtras().getInt(PAGE_NUMBER_KEY);
} else {
startPageNumber = 0;
}
}

因此,实际的原因是,如果意图仅在其附加值上有所不同,PendingInant 将缓存先前的意图。在我的情况下,没有 PendingIntent.FLAG_UPDATE_CURRENTPendingIntent.FLAG_CANCEL_CURRENT的组合可以解决这个问题,因为要么旧的意图将被替换,要么新的意图将与最初的意图保持不变。 您需要确保 Android 无法缓存 PendingInent 背后的意图。对我来说,解决方案是使它们在 data属性上有所不同。

因此,在原始的海报代码,你需要确保 data属性是唯一的每个组合的额外,你是附加。

    Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.putExtra(MainActivity.IS_NEXT_WEEK, isNextWeek);
notificationIntent.setData(Uri.parse("myapp://nextWeek/" + (isNextWeek ? "1" : "0"))

或者,您也可以向 data uri 添加 uuid (然而,如果您有很多很多的通知,那么缓存它们可能会更好