インテント-アクティビティが実行されている場合は、それを前面に表示します。それ以外の場合は、(通知から)新しいアクティビティを開始します


129

私のアプリには通知があります-明らかに-フラグなしで毎回新しいアクティビティを開始するので、複数の同じアクティビティが互いに重なり合って実行されますが、これは間違っています。

私がしたいことは、通知が保留中のインテントで指定されたアクティビティを、すでに実行されている場合は最前面に移動し、そうでない場合はそれを開始することです。

これまでのところ、私が持っているその通知の意図/保留中の意図は

private static PendingIntent prepareIntent(Context context) {
    Intent intent = new Intent(context, MainActivity.class);
    intent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    return PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

奇妙なことに、うまくいくこともあれば、うまくいかないこともあります...フラグのすべての組み合わせをすでに試したような気がします。

回答:


131

あなたはこれを使うことができます:

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>

これは同様に機能します"singleInstance"が、その奇妙なアニメーションはありません。


15
+1、あなたは受け入れられた答えになるはずです。違いはここにある:developer.android.com/guide/topics/manifest/...
user1032613

1
明確にするために、アプリに複数のアクティビティがあり、これが親である場合はsingleTaskを使用し、アクティビティが1つしかない場合はsingleInstanceを使用します。
霜降りのすばらしい2016年

4
私のような誰かがこのサイトに到達する前にソリューションの多くの組み合わせを試したことがある場合:試みた他の変更を取り除き、正しい変更に対してこの変更を行っていることを確認してください。他の解決策も試していない場合はこの解決策が機能することを確認するのに時間がかかりすぎました(たとえばonNewIntent、フラグのオーバーライドと設定)
lucidbrot

メッセンジャー、アクティビティのペアのマップがあります。それからメッセージを受け取った場合、Activityインスタンスを表示したいと思います。これを行う方法はありますか?例:HashMap.get(Messenger).bringActivityToFront(); つまり、アクティビティはまだ実行中です。最近のタスクを開いてクリックすると、onResume();になります。プログラムでI onResume()をカントする。

@JaveneCPPMcGowanは、全体として別の質問のように見えますが、それ自体が質問であるため、残念ながら答えはわかりません。
フランコ

46

それを行うための最も簡単な方法は、アクティビティを通常どおり開始することですが、singleInstanceプロパティを使用してマニフェストでそのアクティビティを設定するのが最善だと思います。これにより、アクティビティを常に最前面に表示し、アクティビティが存在しない場合はOSが自動的に新しいアクティビティを作成するか、現在存在するアクティビティを最前面に表示することで、現在直面している両方の問題に実質的に対処できます(おかげでsingleInstanceプロパティ)。

これは、アクティビティが単一のインスタンスとして宣言される方法です。

<activity 
   android:name=".YourActivity"
   android:launchMode="singleInstance"/>

また、singleInstanceを介して起動するときに途切れ途切れのアニメーションを回避するには、代わりに「singleTask」を使用できます。どちらも非常に似ていますが、違いはGoogleのドキュメントに従ってここで説明されています。

<activity 
   android:name=".YourActivity"
   android:launchMode="singleTask"/>

singleInstanceは「singleTask」と同じですが、システムがインスタンスを保持するタスクに他のアクティビティを起動しない点が異なります。アクティビティは常に、そのタスクの唯一のメンバーです。

お役に立てれば。

よろしく!


4
動作しているようですが、singleIntent MainActivityから起動する他のすべての新しいアクティビティは、通常のフェードとスケールではなく、この奇妙なアーキングアニメーションを再生します
urSus

毎回新しいアクティビティを起動しましたが、実行中の他のすべてのインスタンスをクリアした場合、それは可能でしょうか?
urSus 2013

まあ、あなたが言及しているアニメーションは「singleInstance」プロパティとは関係がないと思います。既存のインスタンスを再利用するだけです。おそらく、あなたが話しているアニメーションはまったく別の問題です...
Martin Cazares

1
さて、私は今それをテストしています。すべてのインテントフラグを削除し、マニフェストでlaunchMode = "singleInstance"を設定するだけで、変なアニメーションが表示されます。削除すると、通常に戻ります
urSus

はい、Androidのドキュメントによると、アクティビティが初期化されておらず、再利用されているため、「init」アニメーションがいつものようになくなっているようです...
Martin Cazares 2013

26

私はあなたが必要なのであると考えsingleTop Activityではなく、singleTasksingleInstance

<activity android:name=".MyActivity"
          android:launchMode="singleTop"
          ...the rest... >

どのようなドキュメントが言う完全にあなたのニーズに合うん。

[...]「singleTop」アクティビティの新しいインスタンスを作成して、新しいインテントを処理することもできます。ただし、ターゲットタスクのスタックの最上位にアクティビティの既存のインスタンスが既にある場合、そのインスタンスは(onNewIntent()呼び出しで)新しいインテントを受け取ります。新しいインスタンスは作成されません。その他の状況-たとえば、「singleTop」アクティビティの既存のインスタンスがターゲットタスクにあるがスタックの最上部にない場合、またはスタックの最上部にあるがターゲットタスクにはない場合-新しいインスタンスが作成され、スタックにプッシュされます。

その上(しゃれたことは意図されていません)、私はあなたとまったく同じニーズを持っていました。私はすべてのlaunchModeフラグをテストして、実際にどのように動作するかを確認しました。その結果singleTop、実際にはこれに最適です。奇妙なアニメーションはなく、アプリは最近のアプリケーションリストに1回表示されます(singleInstance実際には2回表示されるのとは異なります)。 t他の人Activityがそのタスクの一部になることを許可します)、ターゲットがActivity既に存在するかどうかに関係なく、適切な動作を行います。


2
金曜日の夜の午後10時まで作業します。これが私が望むことです...悲しい開発者生活。
felixwcf

私の時間の多くを節約しました!ありがとうございました!
hetsgandhi

13

これは古いスレッドですが、まだ答えを求めているすべての人のために、ここに私の解決策があります。それはマニフェスト設定なしで純粋にコードにあります:

private static PendingIntent prepareIntent(Context context) {
  Intent intent = new Intent(context, MainActivity.class);
  intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);      
  return PendingIntent.getActivity(context, NON_ZERO_REQUEST_CODE, intent, 
    PendingIntent.FLAG_UPDATE_CURRENT);
}

ここでFLAG_ACTIVITY_SINGLE_TOPは、既存のアクティビティがタスクスタックの一番上にある場合にそれを開きます。一番上ではなくスタック内にある場合、FLAG_ACTIVITY_CLEAR_TOPはターゲットアクティビティの上にあるすべてのアクティビティを削除して表示します。アクティビティがタスクスタックにない場合、新しいアクティビティが作成されます。言及すべき非常に重要なポイント-PendingIntent.getActivity()の2番目のパラメーター、つまりrequestCodeはゼロ以外の値でなければなりません(私のスニペットではNON_ZERO_REQUEST_CODEと呼んでもいます)。そうでない場合、これらのインテントフラグは機能しません。どうしてこんなふうになっているのか分からない。フラグFLAG_ACTIVITY_SINGLE_TOPは、マニフェストのアクティビティタグのandroid:launchMode = "singleTop"と交換可能です。


これらのフラグを使用して何時間も戦い、私の意図するフラグを変更しても何も変更されないのかと思っていました。ゼロ以外の要求コード...言及すべき非常に重要なポイント!!! 今すぐ機能します!ありがとうございました!
Max Power

9

古いことは知っていますが、上記のいずれも私のアプリケーションに適していませんでした。

マニフェストやその他の構成を変更せずに、アプリを前面に戻す、または閉じたときにアプリを開くためのコードを次に示します

Intent notificationIntent = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName());
notificationIntent.setPackage(null); // The golden row !!!
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);

これが本当の答えです!
アジズベキアン2018年

2
いいえ、機能していません-現在のアクティビティの上に新しいアクティビティを追加します。
Tobliug

3

私はこれを試しました、そしてIDEがコードについて不平を言っていたにもかかわらずそれはうまくいきました

Intent notificationIntent = new Intent(THIS_CONTEXT, MainActivity.class);
    notificationIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
    PendingIntent intent = PendingIntent.getActivity(THIS_CONTEXT, 0, notificationIntent, Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);

    NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(THIS_CONTEXT)
            .setSmallIcon(R.drawable.cast_ic_notification_0)
            .setContentTitle("Title")
            .setContentText("Content")
            .setContentIntent(intent)
            .setPriority(PRIORITY_HIGH) //private static final PRIORITY_HIGH = 5;
            .setAutoCancel(true)
            /*.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_LIGHTS)*/;
    NotificationManager mNotificationManager = (NotificationManager) THIS_CONTEXT.getSystemService(Context.NOTIFICATION_SERVICE);
    mNotificationManager.notify(0, mBuilder.build());

2
<activity android:name = "。MainActivity" android:launchMode = "singleTask">
nada

Intent.FLAG_ACTIVITY_REORDER_TO_FRONTの有効なフラグではありませんPendingINtent.getActivity
rds

@rdsソースをリンクできますか?
Louis CAD

@LouisCADすみません、もうソースコードにアクセスできません
nada

@rds私はソースコードを求めているのでIntent.FLAG_ACTIVITY_REORDER_TO_FRONTはなく、あなたが読んだ場所のリンクを求めているので、これをとして使用する場合は有効なフラグではありませんPendingIntent。または、getActivityメソッドに渡すことは有効Intentではないが、フラグとして使用することは有効であり、PendingIntent
ルイCAD

2

まだ開始されていないアクティビティを開始したいと言っているので、それを再開してもかまいません。インテントの大量の提案とフラグの組み合わせもテストしました。これにより、以前に関連付けられた状態は保持されませんが、常に必要なアクティビティが前面に表示されます。

intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK|Intent.FLAG_ACTIVITY_NEW_TASK);

API11 +のみ。


0

Androidトレーニングサイトにある通知を追加した後、同様の問題が発生しました。ここで他の答えはどれも私にとってはうまくいきませんでしたが、この答えは私にとってはうまくいきました。概要:

final Intent notificationIntent = new Intent(context, YourActivity.class);
notificationIntent.setAction(Intent.ACTION_MAIN);
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.