Como detectar que um pacote / grupo de notificação foi clicado no Android?

8

No Android Nougat e acima, as notificações por push do seu aplicativo são agrupadas automaticamente após o quarto.

O problema no Android é que clicar no pacote não expande a lista de notificações por push, mas abre o aplicativo.

Tenho o requisito de identificar usuários que abriram o aplicativo através de uma notificação por push. Para notificações individuais, isso é fácil, pois eu posso explorar extras de intenção. O problema com o pacote configurável é que os extras são nulos e a intenção parece exatamente a mesma, como se o usuário tivesse clicado no ícone do iniciador. Não tenho como detectar que a navegação foi feita a partir de uma notificação por push :(

Caso não esteja claro: não estou usando grupos de notificações push explicitamente, isso é feito automaticamente pelo Android. Não defini nenhuma chave de grupo para as notificações.

Estou usando o Firebase. Eu apenas construo a notificação por push usando NotificationCompatquando o aplicativo está em primeiro plano; essa lógica não é executada quando o aplicativo está em segundo plano ou fechado ( OnMessageReceivedé executado apenas com o aplicativo em primeiro plano).

EDITAR

Eu sei que poderia alterar a carga útil do PN para o evento que OnMessageReceivedestá sendo executado mesmo em segundo plano ou fechado. Eu gostaria de evitar isso, pois encontrei muitas pessoas reclamando sobre problemas com a PN não chegando neste caso.

http://github.com/firebase/quickstart-android/issues/368

http://github.com/firebase/quickstart-android/issues/219

Quero detectar um usuário tocando em um PN agrupado, mesmo que o aplicativo não o tenha criado.

PilhaOverflower
fonte
AFAIK, tocando no ícone da chevron do pacote deve expandir / recolher a lista de notificações.
Edric
@ Edric: está correto ... mas não posso forçar o usuário a fazer isso. Alguns usuários clicarão na notificação push recolhida e eu quero lidar com essa situação.
precisa
Com as notificações geradas no servidor e não no cliente, você quer dizer que está usando o FCM, certo? Mesmo nesse caso, você ainda está usando developer.android.com/reference/android/app/… , certo? Você poderia compartilhar algum trecho de código?
Arnab Saha
@ArnabSaha: Eu não posso porque o meu código para construir a notificação que é executado quando o aplicativo está no fundo ou fechado
Claudio Redi
Você sabe de antemão quando as notificações são agrupadas?
Natig Babayev

Respostas:

4

Solução 1: se você lida com a criação das notificações, tente as seguintes etapas:

Antes de tudo, sempre que você cria uma nova notificação, é possível agrupá-las pela mesma chave usando setGroup(...):

val newMessageNotification1 = NotificationCompat.Builder(applicationContext, ...)
    ...
    .setGroup("group_messages")
    .build()

Ao agrupar as notificações pelo mesmo ID ("group_messages") , agora você pode criar uma notificação resumida com intenção diferente:

val notifyIntent = Intent(this, ResultActivity::class.java).apply {
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
)

val summaryNotification = NotificationCompat.Builder(applicationContext, ...)
    .setSmallIcon(android.R.drawable.ic_btn_speak_now)
    .setContentIntent(notifyPendingIntent)
    .setContentTitle("Grouped notification title")
    .setContentText("Grouped notification text")
    .setGroup("group_messages")
    .setGroupSummary(true)
    .build()

Como última etapa, você pode ifverificar se possui mais de uma notificação com o mesmo grupo e depois notificá-la com a notificação do grupo:

val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

val notificationManagerCompat = NotificationManagerCompat.from(applicationContext)
notificationManagerCompat.notify(ID, newMessageNotification1)

val amountOfNotificationsInSameGroup = notificationManager.activeNotifications
                    // Here we filter notifications that are under same group
                    .filter { it.notification.group == "group_messages" }
                    .size

if (amountOfNotificationsInSameGroup >= 2) {
    // if we already have minimum of 2 notifications, we'll group them under summary notification
    notificationManagerCompat.notify(SUMMARY_NOTIFICATION_ID, summaryNotification)
}

Você pode combinar o código no seu onMessageReceivedmétodo. Como você pode ver, agora você pode ter uma intenção personalizada para lidar com notificações agrupadas. Você pode ler mais sobre notificações agrupadas aqui .

Solução 2: se você não deseja lidar com a criação de notificações e ainda deseja saber se as notificações estão agrupadas, tente a seguinte solução:

NotificationManagerpossui a função getActiveNotifications () que retornará notificações que foram postadas pelo aplicativo de chamada e que ainda não foram descartadas pelo usuário. Quando você clica em notificações agrupadas no Android, as notificações não serão descartadas. Portanto, você pode verificar o tamanho das notificações ativas na atividade do iniciador para detectar se o aplicativo foi iniciado clicando em notificações agrupadas / em conjunto:

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val notificationManager =
            applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

        if (notificationManager.activeNotifications.size >= 4) {
            // Notifications are grouped
            // Put your logic here

            // Do not forget to clear notifications
            NotificationManagerCompat.from(this).cancelAll()
        }
    }
}

Pessoalmente, eu prefiro a primeira solução, mas de acordo com os problemas que você postou, você também pode usar a segunda opção, mas observe que não será possível diferenciar se o aplicativo foi iniciado a partir do iniciador ou clicando em notificação agrupada.

Com a segunda solução, pode haver as seguintes perguntas:

T1: como diferenciar o clique normal de notificação do grupo um na mesma atividade?

- Simplesmente, você pode definir click_actione encaminhar cliques de notificação normais para atividades diferentes. Verifique os documentos .

Se você deseja substituir as notificações anteriores, também pode definir o mesmo tagno JSON da sua notificação no lado de back-end. Dessa forma, as notificações não serão agrupadas porque as notificações mais recentes substituirão as antigas pela mesma tag. Verifique os documentos .

Espero que minha resposta ajude.

Natig Babayev
fonte
Apenas creste o PN quando o aplicativo está em primeiro plano. O método OnMessageReceived não é executado quando o aplicativo está fechado. Vi uma documentação afirmando que, mesmo que eu consiga fazer o aplicativo lidar com PN quando o aplicativo estiver fechado ou em segundo plano, isso não funcionará muito bem.
precisa
Isso funciona. Provavelmente você não o usa corretamente. Você poderia colocar seu código e fazer referência a documentos que afirmam que não é possível criar notificações manualmente?
Natig Babayev 30/12/19
@StackOverflower, você pode usar mensagens de dados no firbebase e, dessa maneira, criar suas notificações, mesmo quando o aplicativo for morto no método
onMessageReceived
Os links que você compartilhou não dizem que não é recomendado e parece que o problema está acontecendo em alguns dispositivos. Como você implementou as notificações no seu aplicativo?
Natig Babayev 30/12/19
0

Responder por @Natig Babayev está bem explicado. No entanto, na segunda parte, ele não explicou como distinguir se o aplicativo foi aberto clicando no ícone do iniciador ou no Push Notification Bundle (considere o caso de cinco notificações agrupadas automaticamente, mas o usuário inicia o aplicativo clicando no iniciador de aplicativos e não no pacote de notificações.)

Uma solução poderia ser desativar automaticamente as notificações de agrupamento . No entanto, isso não é possível . Consulte esta pergunta e esta também

Eu pesquisei muitas opções diferentes e descobri que a melhor solução seria agrupar as notificações antes que o sistema Android o faça ou limitar o número de notificações ao máximo de notificações desagrupadas , removendo notificações mais antigas ou agrupando-as em um pacote separado.

Você também pode consultar as seguintes

  1. https://stackoverflow.com/a/47073575/9640177
  2. https://stackoverflow.com/a/34961716/9640177
mayank1513
fonte