web-dev-qa-db-ja.com

現在実行されていない場合にのみアプリを起動する

ユーザーにプッシュ通知を送信します。ユーザーは、クリックするとアプリを開きます。

私の問題は、アプリが既に開いているときに、通知をクリックするとアプリが再び起動することです。

まだ実行されていない場合にのみ、アプリを起動するようにします。

私は通知で保留中の意図を使用しています:

PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, Splash.class), 0);

私は使用するという投稿を見ました:

<activity 
Android:name=".Splash"
Android:launchMode="singleTask"

しかし、問題は、実行中のアプリが他のアクティビティを実行しており、アプリの開始から7秒後に終了するスプラッシュであるため、アプリの実行中はスプラッシュは現在のアクティビティではありません

29
Michael A

次のように、アプリに「launch Intent」を使用します。

PackageManager pm = getPackageManager();
Intent launchIntent = pm.getLaunchIntentForPackage("your.package.name");
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, launchIntent, 0);

「your.package.name」をAndroidマニフェストのパッケージ名に置き換えます。

また、マニフェストから特別なlaunchMode="singleTask"を削除する必要があります。標準Android動作はあなたが望むことをします。

26
David Wasser

Xamarin.Androidを使用する場合。 XamarinバージョンのDavid Wasserの答えは以下のとおりです。

        //Create notification
        var notificationManager = GetSystemService(Context.NotificationService) as NotificationManager;
        Intent uiIntent = PackageManager.GetLaunchIntentForPackage("com.company.app");

        //Create the notification
        var notification = new Notification(Android.Resource.Drawable.SymActionEmail, title);

        //Auto-cancel will remove the notification once the user touches it
        notification.Flags = NotificationFlags.AutoCancel;

        //Set the notification info
        //we use the pending intent, passing our ui intent over, which will get called
        //when the notification is tapped.
        notification.SetLatestEventInfo(this, title, desc, PendingIntent.GetActivity(this, 0, uiIntent, PendingIntentFlags.OneShot));

        //Show the notification
        notificationManager.Notify(0, notification);
3
chris hu
String appPackageName = "";

private void isApplicationInForeground() throws Exception {
    ActivityManager am = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Lollipop) {
        final List<ActivityManager.RunningAppProcessInfo> processInfos = am
                .getRunningAppProcesses();
        ActivityManager.RunningAppProcessInfo processInfo = processInfos
                .get(0);
        // for (ActivityManager.RunningAppProcessInfo processInfo : processInfos) {
        if (processInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
            // getting process at 0th index means our application is on top on all apps or currently open 
            appPackageName = (Arrays.asList(processInfo.pkgList).get(0));
        }
        // }
    }
    else {
        List<ActivityManager.RunningTaskInfo> taskInfo = am.getRunningTasks(1);
        ComponentName componentInfo = null;
        componentInfo = taskInfo.get(0).topActivity;
        appPackageName = componentInfo.getPackageName();
    }
}

private void notifyMessage(String text) {
    if (appPackageName.contains("com.example.test")) {
        // do not notify
    }
    else {          
        // create notification and notify user  
    }
}
3
Haris Qureshi

アクティビティの代わりにスプラッシュをフラグメントとして使用します。スプラッシュフラグメント(7秒)を保持し、同じものを目的のもの(ランディングページ)に置き換えます。

LaunchMode = "singleTask"をマニフェストに追加します。

Rahul 、で既に述べたように、onNewIntent()は、アプリケーションがすでに実行されている場合に呼び出されますelse _onCreate()

@Override
protected void onNewIntent(Intent intent) 
{   
    super.onNewIntent(intent);
}

OR

David の答えで行くと、有望に思えます。

1
Azhar Shaikh

スプラッシュアクティビティはしばらくすると閉じますが、MainActivityは開いたままになるため、通知クリック時にスプラッシュアクティビティを表示する代わりに、MainActivityを表示します。

<activity 
Android:name=".MainActivity"
Android:launchMode="singleTask"
1
Kartheek

これを実現するには、順序付けられたブロードキャストを使用できます。

1)PendingIntentを変更して、アクティビティを開始するか何もしないかを決定するBroadcastReceiverを開始します。

PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, new Intent(this, DecisionReceiver.class), 0);

2)決定BroadcastReceiverを作成します。

public class DecisionReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        context.sendOrderedBroadcast(new Intent(MainActivity.NOTIFICATION_ACTION), null, new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (getResultCode() == MainActivity.IS_ALIVE) {
                    // Activity is in the foreground
                }
                else {
                    // Activity is not in the foreground
                }
            }
        }, null, 0, null, null);
    }
}

3)アクティビティに、生きていることを知らせるBroadcastReceiverを作成します。

public static final String NOTIFICATION_ACTION = "com.mypackage.myapplication.NOTIFICATION";
public static final int IS_ALIVE = 1;
private BroadcastReceiver mAliveReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        setResultCode(IS_ALIVE);
    }
};

// Register onResume, unregister onPause
// Essentially receiver only responds if the activity is the foreground activity
@Override
protected void onResume() {
    super.onResume();
    registerReceiver(mAliveReceiver, new IntentFilter(NOTIFICATION_ACTION));
}

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(mAliveReceiver);
}
0
tachyonflux

notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

notificationIntent.putExtras(bundle);
PendingIntent pintent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
0
Rahul

通知がクリックされ、希望の画面にリダイレクトするコードがこのメソッドを呼び出してそのコードを置き換えるだけで、「true/false」結果ベースで特定の画面にリダイレクトされます。

    private boolean isAppOnForeground(Context context) {
    ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
    List<RunningAppProcessInfo> appProcesses = activityManager.getRunningAppProcesses();
    if (appProcesses == null) {
      return false;
    }
    final String packageName = context.getPackageName();
    for (RunningAppProcessInfo appProcess : appProcesses) {
      if (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_FOREGROUND && appProcess.processName.equals(packageName)) {
        return true;
      }
    }
    return false;
  }
0
krunal shah
Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT

そして、おそらくスプラッシュアクティビティを開始してMainActivityを再度開き(前面に移動)、新しい通知があることを通知するリスナーを使用してUIを更新しないでください(フラグ-ブール値またはリスナーを作成するためのインターフェイスを使用) 。

0
Tazz