_ protected void displayNotification(String response) {
Intent intent = new Intent(context, testActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis());
notification.setLatestEventInfo(context, "Upload", response, pendingIntent);
nManager.notify((int)System.currentTimeMillis(), notification);
}
_
この関数は複数回呼び出されます。各notification
をクリックしてtestActivityを起動したいと思います。残念ながら、最初の通知のみがtestActivityを起動します。残りをクリックすると、通知ウィンドウが最小化されます。
追加情報:関数displayNotification()
はUploadManager
というクラスにあります。 Context
は、インスタンス化するUploadManager
からactivity
に渡されます。関数displayNotification()
は、AsyncTask
で実行されているUploadManagerの関数から複数回呼び出されます。
編集1:extra
として_Intent intent
_に文字列応答を渡していることを忘れていました。
_ protected void displayNotification(String response) {
Intent intent = new Intent(context, testActivity.class);
intent.putExtra("response", response);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
_
これは、通知が作成されたときのString応答を反映するために追加の「応答」が必要なため、大きな違いをもたらします。代わりに、_PendingIntent.FLAG_UPDATE_CURRENT
_を使用すると、余分な「応答」は、displayNotification()
への最後の呼び出しでのString応答を反映します。
これが_FLAG_UPDATE_CURRENT
_のドキュメントを読んでいる理由を知っています。ただし、現時点では回避方法がわかりません。
PendingIntent.getActivityにIntent.FLAG_ACTIVITY_NEW_TASK
を使用しないで、代わりに FLAG_ONE_SHOT を使用してください
コメントからコピー:
次に、Intentにダミーアクションを設定します。設定しない場合、余分なものは削除されます。例えば
intent.setAction(Long.toString(System.currentTimeMillis()))
RemoteViews
ウィジェットの各Intents
とButton
といくつかの異なるHomeScreen
に苦労していました。これらを追加したときに機能しました:
1。intent.setAction(Long.toString(System.currentTimeMillis()));
2。PendingIntent.FLAG_UPDATE_CURRENT
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(context, MyOwnActivity.class);
intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value");
intent.setAction(Long.toString(System.currentTimeMillis()));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent);
それぞれにPendingIntentがアタッチされた複数のウィジェットがあります。更新されるたびに、すべて更新されます。フラグは、まったく同じPendingIntentsで何が起こるかを説明するためにあります。
FLAG_UPDATE_CURRENTの説明の読み方が大幅に改善されました。
作成中の同じPendingIntentが既に存在する場合は、古いものをすべて、作成中の新しいPendingIntentに更新します。
まったく同じ定義は、エクストラを除くPendingIntent全体を調べます。したがって、各インテントに異なるエクストラがあったとしても(私にとってはappWidgetIdを追加していました)、Androidに同じものがあります。
.setActionにダミーの一意の文字列を追加すると、OSに通知されます。これらは完全に異なり、何も更新しません。最後に、各ウィジェットに独自の構成インテントが付加された、思い通りに機能する実装を示します。
Intent configureIntent = new Intent(context, ActivityPreferences.class);
configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
ブロードキャストを使用している場合のさらに優れたソリューション。一意のPendingIntentsも一意のリクエストコードによって定義されます。私のソリューションは次のとおりです。
//Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r
int dummyuniqueInt = new Random().nextInt(543254);
PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context,
dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);
回答は表示されますが、説明は表示されません。また、すべての可能な解決策に対処する回答はないため、それを明確にしようとします。
ドキュメント:
複数の個別のPendingIntentオブジェクトを同時にアクティブにする必要がある場合(両方が同時に表示される2つの通知として使用する場合など)、それらを異なるものに関連付けるには、何か異なるものがあることを確認する必要がありますPendingIntents。これは、Intent.filterEqualsで考慮されるIntent属性のいずれか、またはgetActivity(Context、int、Intent、int)、getActivities(Context、int、Intent []、int)、getBroadcast(Context、int 、Intent、int)、またはgetService(Context、int、Intent、int)。
問題の原因:
2つの保留中のインテントを持つ2つの通知を作成します。保留中の各インテントは、インテントに関連付けられています。
_Intent intent = new Intent(context, testActivity.class);
_
ただし、これら2つのインテントは等しいため、2番目の通知が到着すると、最初のインテントが起動されます。
解決策:
保留中のインテントが等しくならないように、各インテントを一意にする必要があります。インテントをユニークにする方法は? putExtra()
で追加したものではありません。エキストラが異なる場合でも、意図は同じである可能性があります。各インテントを一意にするには、インテントアクション、データ、タイプ、クラス、カテゴリ、またはリクエストコードに一意の値を設定する必要があります:(いずれも機能します)
intent.setAction(...)
intent.setData(...)
intent.setType(...)
intent.setClass(...)
intent.addCategory(...)
PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);
注:System.currentTimeMillis()
がlongを返すため、intが必要なため、一意の要求コードを設定するのは難しい場合があります。つまり、いくつかの数字が削除されます。したがって、categoryまたはactionを使用して、一意の文字列を設定することをお勧めします。
私も同じ問題を抱えていましたが、フラグを次のように変更することで修正できました。
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
文書によると、一意のリクエストコードを使用します:
複数の個別のPendingIntentオブジェクトを同時にアクティブにする必要がある場合(両方が同時に表示される2つの通知として使用する場合など)、それらを異なるものに関連付けるには、何か異なるものがあることを確認する必要がありますPendingIntents。これは、Intent.filterEqualsで考慮されるIntent属性のいずれか、またはgetActivity(Context、int、Intent、int)、getActivities(Context、int、Intent []、int)、getBroadcast(Context、int 、Intent、int)、またはgetService(Context、int、Intent、int)。
ちなみに、私はPendingIntent.FLAG_CANCEL_CURRENT
よりもPendingIntent.FLAG_UPDATE_CURRENT
。
私は同じ問題を抱えていたので、以下の手順で修正しました
1)インテントのフラグをクリアします
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
2)以下のコードでintent.setActionを挿入します
intent.setAction(Long.toString(System.currentTimeMillis()));
3)Pendingintentの場合、以下のコードを挿入します
PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
私はあなたと働きたい
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntentには、2番目と最後の2つのintパラメーターがあります。 2つ目は「リクエストコード」であり、一意の番号(たとえば、通知のID)でなければなりません。
// Use pending Intent and also use unique id for display notification....
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager) sqlitewraper.context.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(id, builder.build());
私は同じ問題を抱えており、 PendingIntent.html.FLAG_UPDATE_CURRENT を使用して修正します。
ソースコードを確認しました。 ActivityManagerService.Java では、キーメソッドは次のとおりです。フラグがPendingIntent.FLAG_UPDATE_CURRENTで、updateCurrentがtrueの場合。一部のエクストラは新しいものに置き換えられ、置き換えられたPendingIntentが取得されます。
IIntentSender getIntentSenderLocked(int type, String packageName,
int callingUid, int userId, IBinder token, String resultWho,
int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
Bundle bOptions) {
// ... omitted
final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
|PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntentRecord.Key key = new PendingIntentRecord.Key(
type, packageName, activity, resultWho,
requestCode, intents, resolvedTypes, flags, bOptions, userId);
WeakReference<PendingIntentRecord> ref;
ref = mIntentSenderRecords.get(key);
PendingIntentRecord rec = ref != null ? ref.get() : null;
if (rec != null) {
if (!cancelCurrent) {
if (updateCurrent) {
if (rec.key.requestIntent != null) {
rec.key.requestIntent.replaceExtras(intents != null ?
intents[intents.length - 1] : null);
}
if (intents != null) {
intents[intents.length-1] = rec.key.requestIntent;
rec.key.allIntents = intents;
rec.key.allResolvedTypes = resolvedTypes;
} else {
rec.key.allIntents = null;
rec.key.allResolvedTypes = null;
}
}
return rec;
}
rec.canceled = true;
mIntentSenderRecords.remove(key);
}
データを正しく送信するには、保留中のインテントで次のような通知IDを送信する必要があります。PendingIntent pendingIntent = PendingIntent.getActivity(context、(int)System.currentTimeMillis()、intent、PendingIntent.FLAG_UPDATE_CURRENT);