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.
- Los dispositivos Android 4.x reciben mensajes GCM, pero los dispositivos Android 2.3
- ¿Debo solicitar un nuevo token cada vez que lance mi aplicación para Android?
- ADB empuja varios archivos con la misma extensión con un solo comando
- Notificación incorrecta enviada desde el paquete, no se pudo expandir RemoteViews
- Haga clic en notificación para ingresar mi aplicación en android
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
- MQTT Eclipse Paho cliente en Android, desconectar se bloquea y nunca termina
- Registro de identificación del dispositivo directamente con Amazon SNS
- No se puede establecer el sonido de notificación push en android
- Android OnNewIntent no se llama
- Notificaciones push en la plataforma Android
- FCM push notification issue: - "error": "NotRegistered"
- Anular el registro del cliente android desde el servidor de empuje unificado aerogear
- Notificaciones push iOS y código nativo cliente-cliente de Android
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
- Fragmento sin una vista se bloquea en el cambio de configuración
- Prevenga onPause de la basura OpenGL Context