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