私は 4 つのアクティビティを含むアプリケーションを持っています。アプリケーション内で、ユーザーは常に 4 つのアクティビティをナビゲートしていることに気付くでしょう。アプリケーションにはバックグラウンドで進行中のサービスもあり、サービスはステータスバー通知を表示し、通知に表示されるコンテンツの変更をリッスンします。
現在、サービスは、ユーザーが通知の表示を必要とするアクションを開始するたびに通知を表示するため、アプリケーションを使用している場合でも通知が表示されます。望ましいシナリオは、ユーザーがアプリケーションから移動したときにのみ通知を表示することです。
次のようなライフサイクルメソッドをオーバーライドしようとしました:
@Override
protected void onPause() {
Intent intent = new Intent();
intent.setAction(MyService.ACTION_DISPLAY_PENDING_NOTIFICATION);
sendBroadcast(intent);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
Intent intent = new Intent();
intent.setAction(MyService.ACTION_CANCEL_NOTIFICATION);
sendBroadcast(intent);
}
サービスは次のようになります。
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals(ACTION_DISPLAY_PENDING_NOTIFICATION)) {
showNotification();
}
else if (action.equals(ACTION_CANCEL_NOTIFICATION)) {
mNotificationManager.cancel(mNotId);
}
}
これは、動作します。ただし、ユーザーがアクティビティから移動するたびにインテントが送信されるため、ユーザーが 4 つのアクティビティを移動すると、望ましくない動作とわずかなパフォーマンス ヒットが発生します。サービスは、アクティビティ A からアクティビティ B、または 4 つのアクティビティ内の任意の組み合わせに移動する場合でも、通知を表示しようとします。
新しいアクティビティ B が開始されると、 onResume 中にmNotificationManager.cancel (mNotifId) が呼び出されるため、通知はすぐにキャンセルされますが、アクティビティ A を離れるときにサービスがそうするように指示されたため、通知が作成され、ほんの一瞬だけ表示されました。この通知を不必要に構築して表示するのではなく、それが私が対処したい動作です。
ユーザーがいつアクティビティを別のアプリケーション、つまりホームページなどに残しているかを知る方法はありますか? しかし、アプリケーション自体の中ではありませんか?
編集:
明確にするために、アクティビティが onPause メソッド中にチェックする必要があることが 2 つあります。
a) フォアグラウンドで以前のアクティビティはありますか? なんで?ユーザーは [戻る] を押してアクティビティの外に移動できるため、スタックの最後のアクティビティが表示されることを意味します。これを確認するには、DennisDrew からの回答が機能します。次のように確認できます。
if(!ForegroundHelper.activityExistsInForeground()){
//show your notification
}
しかし、それがユーザーがアクティビティから移動できる唯一の方法ではありません。ユーザーは HomeKey を押すこともできます。その場合、activityExistsInForeground()
true または false のどちらに評価されても、通知が表示されます。
b) ユーザーはアプリケーション内の別のアクティビティに移動しますか? たとえば、ユーザーがアクティビティ A を使用していて、現時点では A がフォアグラウンドで唯一のアクティビティであり、ユーザーがアクティビティ B を起動する UI 要素をクリックすると、activityExistsInForeground()
false と評価されたにもかかわらず、ユーザーはアプリケーションを離れず、新しいインスタンスを起動しています以前は外界にいなかった活動の。
private boolean launchingNewActivity = false
デフォルトなどのフラグを追加しようとしましたがtrue
、たとえば、リストビューのアイテムをクリックしている間など、別のアクティビティに行くことがわかっているときにフラグを設定しました。
litview.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
launchingNewActivity = true
startActivity2(arg2);
}
});
次に、onPause 中にそれを確認します。
@Override
protected void onPause() {
if(!ForegroundHelper.activityExistsInForeground() && launchingNewActivity){
//show your notification
}
しかし、これを行うと、通知が表示されることはありません。どういうわけか、二重チェックは常にデフォルトで false になります。