webentwicklung-frage-antwort-db.com.de

App wird nur gestartet, wenn sie gerade nicht läuft

Ich versende Push-Benachrichtigungen an Benutzer, die beim Anklicken die App öffnen.

Mein Problem ist, dass die App erneut gestartet wird, wenn die App bereits geöffnet ist.

Ich möchte nur, dass die App gestartet wird, wenn sie nicht bereits läuft.

In der Benachrichtigung verwende ich die ausstehende Absicht:

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

Ich habe Beiträge gesehen, in denen es heißt: 

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

aber die Sache ist, dass meine laufende App andere Aktivitäten ausführt als der Splash, der 7 Sekunden nach dem Start der App beendet ist. Wenn die App ausgeführt wird, ist Splash nicht die aktuelle Aktivität

29
Michael A

Verwenden Sie für Ihre App einen Start von Intent:

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

Ersetzen Sie "your.package.name" durch den Namen Ihres Pakets aus dem Android-Manifest.

Außerdem sollten Sie den speziellen launchMode="singleTask" aus Ihrem Manifest entfernen. Standardmäßiges Android-Verhalten wird tun, was Sie möchten.

26
David Wasser

Für diejenigen, die Xamarin.Android verwenden. Die Xamarin-Version von David Wasser 's Antwort ist unten:

        //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

Verwenden Sie Splash als Fragment anstelle von Aktivität. Splash-Fragment beibehalten (7 Sekunden), durch das gewünschte Fragment ersetzen (Zielseite).

Fügen Sie launchMode = "singleTask" zum Manifest hinzu.

Wie bereits von Rahul angegeben, wird onNewIntent() aufgerufen, wenn die Anwendung bereits ausgeführt wird, sonst onCreate()

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

ODER 

Geh mit David s Antwort, scheint vielversprechend.

1
Azhar Shaikh

Anstatt die Splash-Aktivität beim Benachrichtigungsklick anzuzeigen, zeigen Sie Ihre MainActivity an, da Ihre Splash-Aktivität nach einiger Zeit geschlossen wird 

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

Sie können dazu eine geordnete Sendung verwenden.

1) Ändern Sie Ihre PendingIntent, um eine BroadcastReceiver zu starten, die entscheidet, ob Sie die Aktivität starten oder nichts tun möchten:

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

2) Legen Sie die Entscheidung BroadcastReceiver an:

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) Erstellen Sie eine BroadcastReceiver in Ihrer Aktivität, die signalisiert, dass sie lebt:

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

wenn Sie auf die Benachrichtigung geklickt haben und Ihr Code zu Ihrem Wunschbildschirm weitergeleitet wurde, ersetzen Sie einfach diesen Code, indem Sie diese Methode aufrufen und zu einem bestimmten Bildschirm auf der Basis "true/false" umleiten.

    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

Starten Sie möglicherweise nicht die Splash-Aktivität, und öffnen Sie die MainActivity nicht erneut (in den Vordergrund). Aktualisieren Sie die Benutzeroberfläche mit einem Listener, der Ihnen mitteilt, dass Sie eine neue Benachrichtigung haben (mit einem Flag - boolean oder mit einem Interface, um einen Listener zu erstellen) .

0
Tazz