2011-03-31 26 views
49

Quiero reanudar mi aplicación desde una notificación de barra de estado de la misma manera que cuando el usuario toca su icono en el iniciador.Reanudar solicitud y apilar de notificación

Es decir: quiero que la pila esté en el mismo estado que antes de que el usuario la dejara.

El problema al establecer un intento pendiente en la notificación es que siempre se dirige a una actividad específica. No quiero esto Necesito reanudar la aplicación como lo hace el iniciador.

Entonces, si el usuario está en la actividad A, quiero reanudar la actividad A. Si ha lanzado la actividad B desde la actividad A, entonces quiero que se muestre B cuando el usuario toca la notificación y la pila que se restaurará para que A se reanude cuando el usuario toque el botón Atrás en B.

Hay otras preguntas de preguntas con títulos similares, pero ninguna aborda mi problema.

+0

posibles duplicados: http://stackoverflow.com/questions/3356095/how-to-bring-android-existing-activity-to-front-via-notification, http://stackoverflow.com/questions/4047683/ android-how-to-resume-a-app-from-a-notification – Philipp

Respuesta

128

sólo tiene que utilizar los mismos filtros intención que utiliza Android cuando se lance la aplicación:

final Intent notificationIntent = new Intent(context, YourActivity.class); 
notificationIntent.setAction(Intent.ACTION_MAIN); 
notificationIntent.addCategory(Intent.CATEGORY_LAUNCHER); 
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); 

A medida que el Intent que ha creado para abrir su Activity de la barra de notificaciones es el mismo que Android utiliza para el lanzamiento de su aplicación, se mostrará el Activity previamente abierto en lugar de crear uno nuevo.

+0

Gracias! Funciona genial. Probado en Moto Droid, X10 Mini y Samsung S. – olivierg

+2

Solo una pregunta: ¿qué ocurre si un lanzador particular/alternativo utiliza una intención ligeramente diferente? Tal vez con algunos otros extras o categorías. ¿Crees que debería almacenar en caché el intento original con el que se inició mi aplicación (como lo recuperó Activity.getIntent()), y usar eso tal como está para crear mi intención pendiente? – olivierg

+0

Funciona como yo esperaba. Muchas gracias. – sunghun

-4

Podría haber una manera más simple, pero podría almacenar los datos en la base de datos sqlite y cada vez que reinicie la aplicación cualquiera sea el estado que haya guardado en la base de datos puede recuperar y establecer sus valores en lo que necesitan .

+0

No, no, no. Simplemente no;) – finki

0

Esto es muy simple abrir su archivo de manifiesto y establecer el modo de lanzamiento atributo singleTop en su actividad atribuyen

+0

¿En qué API has probado esto? No parece funcionar en la API 23. Al presionar 'atrás' y luego hacer clic en la notificación se inicia una segunda instancia de la actividad – behelit

2

Creación de una actividad y luego establecer las categorías y unas respectivas banderas ... Esta fue la forma en que este trabajado para mí, tuve que hacerlo de esta manera porque yo hice para apoyar Api lvl 8

intent.addCategory(Intent.ACTION_MAIN); 
intent.addCategory(Intent.CATEGORY_LAUNCHER); 
intent.setClass(this, YourActivity.class); 

intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT| 
       Intent.FLAG_ACTIVITY_SINGLE_TOP); 

PendingIntent pi = PendingIntent.getActivity(this, 0, intent, 
        PendingIntent.FLAG_UPDATE_CURRENT); 

y en el AndroidManifest

android:launchMode="singleTask" 

Entonces, ¿qué hizo el truco fue el Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT junto con la línea establecida en el manifiesto.

Espero que ayude a otras personas.

+0

Parece que no funciona si se presiona atrás. (API 23) – behelit

3

También tuve el mismo problema y tratar de resolver el problema como la respuesta de @ Grand:

final Intent notificationIntent = new Intent(context,YourActivity.class); 
Intent intent = new Intent(Intent.ACTION_MAIN); 
intent.addCategory(Intent.CATEGORY_LAUNCHER); 

Esto funciona, no hay dudas al respecto, pero el problema es cuando se establece su intención como ACTION_MAIN. Entonces no podrás configurar ningún paquete para la intención. Es decir, tus datos primitivos no se recibirán de la actividad objetivo porque ACTION_MAIN no puede contener datos adicionales.

En lugar de esto, puede establecer sus actividades como singleTask y llamar a su intento normalmente sin establecer ACTION_MAIN y recibir la intención del método onNewIntent() de su actividad de destino.

Pero beaware si llama, super.onNewIntent (intención); luego se creará una segunda instancia de la actividad.

-1
<uses-permission android:name="android.permission.GET_TASKS" /> 
<uses-permission android:name="android.permission.REORDER_TASKS" /> 

private void bringApplicationToForeground(){ 
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); 

    if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 

     List<ActivityManager.AppTask> tasksList = am.getAppTasks(); 
     for (ActivityManager.AppTask task : tasksList){ 
     task.moveToFront(); 
     } 
    }else{ 

     List<ActivityManager.RunningTaskInfo> tasksList = am.getRunningTasks(Integer.MAX_VALUE); 
     if(!tasksList.isEmpty()){ 
     int nSize = tasksList.size(); 
     for(int i = 0; i < nSize; i++){ 
      if(tasksList.get(i).topActivity.getPackageName().equals(getPackageName())){ 
      am.moveTaskToFront(tasksList.get(i).id, 0); 
      } 
     } 
     } 
    } 
} 
+0

¿Qué está haciendo este código? donde debería usar? –

7

Para situaciones en las que no desea/puede código no dura la actividad lanzador esta solución funciona

Intent i = getPackageManager() 
    .getLaunchIntentForPackage(getPackageName()) 
    .setPackage(null) 
    .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED); 

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, i, 0); 

return new NotificationCompat.Builder(context) 
     ... 
     .setContentIntent(pendingIntent) 
     .build(); 

La parte setPackage (nulo) fue clave en mi caso ya que sin ella la aplicación no volvió a la tarea anterior. Comparé mi intención con la intención del iniciador de Android y noté que el paquete no estaba allí, así que así fue como se me ocurrió eliminar el nombre del paquete del intento.

Mi situación particular era que la notificación se había creado en una biblioteca, por lo que no podía saber cuál sería la actividad del iniciador.

+0

Realmente bueno, ¡justo lo que necesitaba! – iaindownie

Cuestiones relacionadas