web-dev-qa-db-ja.com

意図-アクティビティが実行中の場合、それを前面に表示し、そうでない場合は(通知から)新しいアクティビティを開始します

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

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

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

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

おかしなことに、それは時々機能し、時には機能しません...フラグのすべての組み合わせをすでに試したように感じます。

121
urSus

これを使用できます:

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

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

122
Franco

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

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

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

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

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

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

お役に立てれば。

よろしく!

42
Martin Cazares

必要なのは、singleTopActivityではなく、singleTasksingleInstanceであると思います。

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

ドキュメントに記載されている はあなたのニーズに完全に合っています:

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

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

24
Shlublu

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

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"と交換可能です。

6

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

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

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);
6
Raziza O

私はこれを試してみましたが、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());
3
nada

アクティビティがまだ開始されていない場合は開始したいということなので、再起動してもかまいません。意図についても多数の提案とフラグの組み合わせをテストしました。これにより、以前に関連付けられていた状態は保持されませんが、常に必要なアクティビティが前面に表示されます。

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

API11 +のみ。

2
Fat Shogun

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);
0
gattsbr