Ao iniciar uma atividade em uma notificação, é preciso preservar a experiência de navegação que o usuário espera. O toque em Voltar deve levar o usuário de volta no fluxo de trabalho normal do app até a tela inicial, e a abertura da tela Recentes deve mostrar a atividade como uma tarefa separada. Para preservar essa experiência de navegação, inicie a atividade em uma nova tarefa.
Embora a abordagem básica para definir o comportamento de toque da notificação esteja descrita em Criar uma notificação, esta página descreve como configurar um PendingIntent
para a ação da notificação, para que ela crie uma nova tarefa e uma pilha de retorno.
No entanto, a maneira exata de fazer isso depende do tipo da atividade iniciada:
- Atividade comum
- Essa é uma atividade que existe como parte do fluxo de UX normal do app. Assim, quando o usuário chega até a atividade a partir da notificação, a nova tarefa precisa incluir uma pilha de retorno completa, permitindo que ele pressione Voltar e navegue na hierarquia do app.
- Atividade especial
- O usuário só verá essa atividade se ela for iniciada a partir de uma notificação. De certa forma, essa atividade estende a IU da notificação, disponibilizando informações difíceis de serem exibidas na própria notificação. Por isso, não é necessário incluir uma pilha de retorno nesse caso.
Configurar uma atividade normal PendingIntent
Para iniciar uma "atividade normal" a partir da sua notificação, configure o PendingIntent
usando TaskStackBuilder
para que ele crie uma nova pilha de retorno, conforme mostrado a seguir.
Definir a hierarquia de atividades do app
Defina a hierarquia natural das suas atividades adicionando o atributo android:parentActivityName
a cada elemento <activity>
no arquivo de manifesto do app. Por 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 pilha de retorno de atividades, é necessário criar uma instância de TaskStackBuilder
e chamar addNextIntentWithParentStack()
, passando a ele a Intent
da atividade que você quer iniciar.
Contanto que você tenha definido a atividade pai de cada atividade, conforme descrito acima, pode chamar getPendingIntent()
para receber uma PendingIntent
que inclui toda a pilha de retorno.
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) }
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);
Se necessário, você pode adicionar argumentos a objetos Intent
na pilha chamando TaskStackBuilder.editIntentAt()
. Em alguns casos, isso é necessário para garantir que uma atividade na pilha de retorno mostre dados significativos quando o usuário navegar até ela.
Em seguida, você pode passar PendingIntent
para a notificação como de costume:
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" iniciada a partir de uma notificação não precisa de uma pilha de retorno, é possível criar PendingIntent
chamando getActivity()
. No entanto, verifique se você definiu as opções de tarefa apropriadas no manifesto.
-
No manifesto, adicione os atributos a seguir ao elemento
<activity>
.-
android:taskAffinity=""
-
Combinada com a sinalização
FLAG_ACTIVITY_NEW_TASK
que você usará no código, a configuração desse atributo em branco garante que essa atividade não entre na tarefa padrão do app. As tarefas existentes que tiverem a afinidade padrão do app não serão afetadas. -
android:excludeFromRecents="true"
- Exclui a nova tarefa de Recentes, para que o usuário não navegue por engano de volta a ela.
Por exemplo:
<activity android:name=".ResultActivity" android:launchMode="singleTask" android:taskAffinity="" android:excludeFromRecents="true"> </activity>
-
-
Compilar e emitir a notificação:
-
Crie uma
Intent
que inicie aActivity
. -
Defina a
Activity
para iniciar em uma tarefa nova e vazia, chamandosetFlags()
com os sinalizadoresFLAG_ACTIVITY_NEW_TASK
eFLAG_ACTIVITY_CLEAR_TASK
. -
Crie um
PendingIntent
chamandogetActivity()
.
Por 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 )
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 );
-
Crie uma
- Em seguida, passe o
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 sobre como a pilha de retorno funciona, leia Tarefas e pilha de retorno. Para ver o exemplo de código que usa notificações, consulte o Exemplo de notificações do Android (em inglês).