studio programacion para libros libro edición desarrollo desarrollar aprende aplicaciones android notifications push-notification android-pendingintent

android - programacion - Iniciar la aplicación solo si no está funcionando actualmente



manual de programacion android pdf (11)

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

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

Estoy enviando una notificación de inserción a los usuarios, que al hacer clic en ella abre la aplicación.

Mi problema es que cuando la aplicación ya está abierta, haga clic en la notificación para volver a iniciarla.

Solo quiero que inicie la aplicación si aún no se está ejecutando.

Estoy usando la intención pendiente en la notificación:

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

Vi mensajes que dicen usar:

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

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


En primer lugar, establezca una tarea predeterminada de android:taskAffinity="com.example.testp.yourPreferredName" en su elemento de 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() (por un segundo pensamiento, no se recomienda onResume ()) - 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 .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, necesita usar AppTask , esto le ahorrará líneas de código adicionales ya que no estará en un Loop para encontrar su Task .

Espero eso ayude


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


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) Cree un BroadcastReceiver en su actividad que indique 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); }


Usa Splash como Fragmento en lugar de Actividad. Mantenga el fragmento de Splash (7 segundos), reemplace el mismo con el deseado (página de destino).

Agregue launchMode = "singleTask" al manifiesto.

Como ya lo dijo Rahul , onNewIntent() se llama si la aplicación ya se está ejecutando else onCreate()

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

O

Ve con la respuesta de David , parece prometedor.


Use un " Intent lanzamiento" para su aplicación, como este:

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

Reemplace "your.package.name" con el nombre de su paquete del manifiesto de Android.

Además, debes eliminar el launchMode="singleTask" de tu manifiesto. El comportamiento estándar de Android hará lo que quieras.


cuando se hace clic en la notificación y su código que redirige a su pantalla deseada simplemente reemplace ese código llamando a este método y redireccione a una pantalla en particular sobre la base de resultados "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; }


intente agregar esto a su intención de llevar la actividad al frente si se ejecuta 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);


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


Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT

Y tal vez no inicie la Actividad de Splash y vuelva a abrir (traiga al frente) MainActivity y actualice la interfaz de usuario con un oyente que le indique que tiene una nueva notificación (con una bandera - boolean o con una Interfaz para hacer un oyente) .


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