Iniciar la aplicación sólo si no está en ejecución

Estoy enviando una notificación push a los usuarios que al hacer clic en ella se abre la aplicación.

Mi problema es que cuando la aplicación ya está abierta, al hacer clic en la notificación, vuelve a iniciar la aplicación.

Solo quiero que inicie la aplicación si no está funcionando.

Estoy utilizando Pendiente de intención en la notificación:

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

Vi mensajes que dicen uso:

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

Pero la cosa es que mi aplicación en ejecución está ejecutando otra actividad, a continuación, el splash que se termina después de 7 segundos desde el inicio de la aplicación, por lo que cuando la aplicación está ejecutando Splash no es la actividad actual

Utiliza una " Intent lanzamiento" para tu aplicación, así:

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

Reemplace "your.package.name" por el nombre de su paquete desde el manifiesto de Android.

Además, debe quitar el special launchMode="singleTask" de su manifiesto. El comportamiento estándar de Android hará lo que quiera.

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

En lugar de mostrar la actividad de Splash en el clic de notificación, muestre su MainActivity porque su actividad de splash se cerrará después de algún tiempo, pero MainActivity permanecerá abierta y

 <activity android:name=".MainActivity" android:launchMode="singleTask" 

Utilice Splash como Fragmento en lugar de Actividad. Mantenga el fragmento Splash (7 segundos), sustituya el mismo por el deseado (página de destino).

Agregue launchMode = "singleTask" al manifiesto.

Como ya se ha dicho por Rahul , onNewIntent() se llama si la aplicación ya está ejecutando onCreate()

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

O

Ve con la respuesta de David , parece prometedor.

Para aquellos que usan Xamarin.Android . La versión de Xamarin de la respuesta de David Wasser está abajo:

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

Cuando la notificación chasqueada y su código que redirigir a su pantalla del deseo apenas substituya ese código llamando a este método y redirigir a la pantalla particular en base del resultado "verdadero / falso".

  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 

Y tal vez no inicie la actividad Splash y vuelva a abrir la interfaz MainActivity y actualice la interfaz de usuario con un oyente que le diga que tiene una nueva notificación (con un indicador – booleano o con una interfaz para hacer un escucha) .

Puede utilizar una emisión ordenada para lograr esto.

1) Cambie su PendingIntent para iniciar un BroadcastReceiver que decidirá si iniciar la actividad o no hacer nada:

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

2) Crear la decisión 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) Crear un BroadcastReceiver en su actividad que señalará que está vivo:

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

Intente agregar esto a su intención de llevar la actividad al frente si se está ejecutando en segundo plano

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

En primer lugar, establezca un Task android:taskAffinity="com.example.testp.yourPreferredName" defecto android:taskAffinity="com.example.testp.yourPreferredName" en su elemento Application en el archivo Manifest. Mantenga su android:launchMode="singleTask" en su SplashActivity . Ahora, ya que su SplashActivity es su entrada principal, agregue este código a onResume() , onNewIntent() y onCreate() (en un segundo pensamiento onResume () no se recomienda) -siga los comentarios en el código

 //Note these following lines of code will work like magic only if its UPVOTED. //so upvote before you try it.-or it will crash with SecurityException ActivityManager am = (ActivityManager) this.getSystemService(ACTIVITY_SERVICE); List< ActivityManager.RunningTaskInfo > taskInfo = am.getRunningTasks(1000); for(int i =0; i< taskInfo.size(); i++){ String PackageName = taskInfo.get(i).baseActivity.getPackageName(); if(PackageName.equals("packagename.appname")){// suppose stackoverflow.answerer.Elltz //if the current runing actiivity is not the splash activity. it will be 1 //only if this is the first time your <taskAffinity> is be called as a task if(taskInfo.get(i).numActivities >1){ //other activities are running, so kill this splash dead!! reload!! finish(); // i am dying in onCreate..(the user didnt see nothing, that's the good part) //about this code. its a silent assassin } //Operation kill the Splash is done so retreat to base. break; } } 

Este código no funcionará en api 21+ ; Para que funcione necesitas usar AppTask , esto te ahorrará líneas adicionales de código, ya que no estarás en un Loop para encontrar tu Task .

Espero eso ayude

  • Cómo dar contador si hay más de una notificación
  • Notificación de Parse Push no enviando desde Android al Canal
  • Enviar notificaciones cuando la aplicación esté cerrada
  • ¿Es una práctica común preguntar a los usuarios si desean recibir notificaciones push?
  • ¿Son confiables las notificaciones push de Android?
  • Apertura del navegador en la notificación push
  • Despierta Android Phone / tablet?
  • Android, notificación Push mediante parse.com, inicia automáticamente la aplicación
  • Notificación de cancelación automática no funciona para Android Lollipop
  • Error al empujar el elemento (s). En android
  • Cordova PushPlugin - No se puede recibir notificación de GCM en android si la aplicación no se está ejecutando
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.