PendingIntentはIntentエキストラを送信しません


127

MainActicityRefreshServiceと呼ばれるエキストラIntentがあるで始まります。booleanisNextWeek

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` MainActivityでを直接開始するとIntent

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

すべてが正常に機能し、trueいつになるかわかりisNextWeekます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


2
PendingIntent.FLAG_CANCEL_CURRENTは私のために機能しました、ありがとう
Pelanes

1
たくさんの時間を節約できました。正解!
TharakaNirmana 14

あなたは質問と解決策を持っています:D素晴らしい。質問への回答として追加する必要があると思います。+10秒は+5秒より優れています;)
Muhammed Refaat 2017


同じPendingIntentがウィジェットで再利用されたため、FLAG_UPDATE_CURRENTは私の場合には不十分でした。私はめったに発生しないアクションにFLAG_ONE_SHOTを使用してしまい、ウィジェットのPendingIntentはそのまま残しました。
EIR

回答:


29

PendingIntent.FLAG_CANCEL_CURRENTの使用は、メモリの非効率的な使用のため、適切な解決策ではありません。代わりにPendingIntent.FLAG_UPDATE_CURRENTを使用してください

Intent.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)イベントハンドラーを実装してみてください。 これにより、アクティビティに対して呼び出された新しいインテントにアクセスできます(これはgetIntent()を呼び出すだけではなく、常に起動した最初のインテントを返します)あなたの活動。

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

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

21

アクティビティで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);        
}

編集:

これは、インテントを受け取ったときにアクティビティがすでに開始されている場合にのみ必要です。あなたの活動が意図によって開始された(そして再開されただけではない)場合、問題は別の場所にあり、私の提案はそれを修正しないかもしれません。


これは、アクティビティが閉じられ、その後通知で開かれた場合にも表示されます。
maysi 2013

3

次のコードは動作するはずです:-

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");
}

new Notification(icon, message, when);は非推奨
maysi 2013

とにかくCLEAR_TOPなしでそれを行うには?
Richard
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.