Ao iniciar uma atividade em uma notificação, é necessário preservar a experiência de navegação esperada pelo usuário. Tocar no botão "Voltar" precisa levar o usuário de volta pelo fluxo de trabalho normal do app até a tela inicial, e abrir a tela "Recentes" precisa mostrar a atividade como uma tarefa separada. Para preservar essa experiência de navegação, inicie a atividade em uma nova tarefa.
A abordagem básica para definir o comportamento de toque da notificação é descrita em
Criar uma notificação
básica.
Esta página descreve como configurar uma
PendingIntent
para a ação da
notificação de modo que ela crie uma nova tarefa e uma backstack. A maneira de fazer isso
depende do tipo de atividade que você está iniciando:
- Atividade comum
- Essa é uma atividade que existe como parte do fluxo de UX normal do app. Quando o usuário chega na atividade pela notificação, a nova tarefa precisa incluir uma backstack completa, permitindo que o usuário toque no botão "Voltar" para navegar pela hierarquia do app.
- Atividade especial
- O usuário só verá essa atividade se ela for iniciada a partir de uma notificação. Basicamente, essa atividade estende a IU da notificação fornecendo informações difíceis de mostrar na própria notificação. Esta atividade não precisa de uma backstack.
Configurar uma atividade normal PendingIntent
Para iniciar uma atividade normal pela notificação, configure o PendingIntent
usando TaskStackBuilder
para que ele crie uma nova backstack, conforme mostrado a seguir.
Definir a hierarquia de atividades do app
Defina a hierarquia natural das atividades adicionando o atributo
android:parentActivityName
a cada elemento <activity>
no arquivo de manifesto do app. Confira este exemplo:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <!-- MainActivity is the parent for ResultActivity. --> <activity android:name=".ResultActivity" android:parentActivityName=".MainActivity" /> ... </activity>
Criar um PendingIntent com uma pilha de retorno
Para iniciar uma atividade que inclua uma backstack de atividades, crie uma
instância de TaskStackBuilder
e chame
addNextIntentWithParentStack()
,
transmitindo o Intent
para a
atividade que você quer iniciar.
Contanto que você defina a atividade mãe para cada atividade, conforme descrito
anteriormente, é possível chamar
getPendingIntent()
para receber um PendingIntent
que inclua toda a backstack.
Kotlin
// Create an Intent for the activity you want to start. val resultIntent = Intent(this, ResultActivity::class.java) // Create the TaskStackBuilder. val resultPendingIntent: PendingIntent? = TaskStackBuilder.create(this).run { // Add the intent, which inflates the back stack. addNextIntentWithParentStack(resultIntent) // Get the PendingIntent containing the entire back stack. getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE) }
Java
// Create an Intent for the activity you want to start. Intent resultIntent = new Intent(this, ResultActivity.class); // Create the TaskStackBuilder and add the intent, which inflates the back // stack. TaskStackBuilder stackBuilder = TaskStackBuilder.create(this); stackBuilder.addNextIntentWithParentStack(resultIntent); // Get the PendingIntent containing the entire back stack. PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
Se necessário, adicione argumentos a objetos Intent
na pilha chamando
TaskStackBuilder.editIntentAt()
.
Às vezes, isso é necessário para garantir que uma atividade na backstack
mostre dados significativos quando o usuário navegar até ela.
Em seguida, transmita o PendingIntent
para a notificação normalmente:
Kotlin
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(resultPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(resultPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
Configurar uma atividade especial PendingIntent
Como uma atividade especial que é iniciada por uma notificação não precisa de uma backstack, você pode criar a PendingIntent
chamando
getActivity()
.
No entanto, defina as opções de tarefa adequadas no manifesto.
-
No manifesto, adicione os atributos abaixo ao elemento
<activity>
.-
android:taskAffinity=""
-
Combinada com a sinalização
FLAG_ACTIVITY_NEW_TASK
usada no código, defina esse atributo em branco para garantir que essa atividade não entre na tarefa padrão do app. Nenhuma tarefa existente que tiver a afinidade padrão do app será afetada. -
android:excludeFromRecents="true"
- Exclui a nova tarefa da tela "Recentes" para que o usuário não navegue acidentalmente de volta a ela.
Isso é mostrado neste exemplo:
<activity android:name=".ResultActivity" android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity>
-
-
Crie e emita a notificação:
-
Crie uma
Intent
que inicie aActivity
. -
Defina o
Activity
para iniciar em uma tarefa nova e vazia, chamandosetFlags()
com as sinalizaçõesFLAG_ACTIVITY_NEW_TASK
eFLAG_ACTIVITY_CLEAR_TASK
. -
Crie um
PendingIntent
chamandogetActivity()
.
Isso é mostrado neste exemplo:
Kotlin
val notifyIntent = Intent(this, ResultActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } val notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE )
Java
Intent notifyIntent = new Intent(this, ResultActivity.class); // Set the Activity to start in a new, empty task. notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Create the PendingIntent. PendingIntent notifyPendingIntent = PendingIntent.getActivity( this, 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE );
-
Crie uma
- Transmita
PendingIntent
para a notificação normalmente:Kotlin
val builder = NotificationCompat.Builder(this, CHANNEL_ID).apply { setContentIntent(notifyPendingIntent) ... } with(NotificationManagerCompat.from(this)) { notify(NOTIFICATION_ID, builder.build()) }
Java
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID); builder.setContentIntent(notifyPendingIntent); ... NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this); notificationManager.notify(NOTIFICATION_ID, builder.build());
Para mais informações sobre as várias opções de tarefa e como a backstack funciona, consulte Tarefas e a backstack.