quinta-feira, 5 de julho de 2018

Rumo ao Certificado Android: Pending Intention e Notificações

O que é Pending Intention?

Pending Intention é uma Intention criada para dar para outros aplicativos, acesso a Activities, Services, etc do teu aplicativo, mesmo que o teu app não esteja em execução. Por exemplo, para uma notificação do Android abrir uma tela do seu aplicativo, uma Pending Intention pode ser criada e usada pelo serviço de notificação do Android.

Como criar uma Pending Intention?
Pending Intention usa uma Factory e vai depender do tipo de ação você quer, por exemplo, existe o getActivity, getService, getBroadcast, etc. Entretanto, todos eles terão 4 parâmetros:

  • Contexto: contexto da atividade que vai PendingIntention;
  • ID: um id para poder manipular o PendingIntention depois de criado. Garanta que cada PendingIntention tenha um id único, que vá permitir cancelar ou atualizar o mesmo no futuro;
  • Intent: o intent com a ação que deseja fazer;
  • Flag: flag indicando como deve tratar a Intention, por exemplo, FLAG_UPDATE_CURRENT irá tentar criar a PendingIntent, mas se a mesma já existir, atualizará os novos dados;
Exemplo do código:

PendingIntent.getService(context,
                         ID,
                         myIntent, 
                         FLAG_UPDATE_CURRENT);

Notificações
Para notificações, nós vamos criar uma classe específica para isso. Vamos primeiro criar um método para criar um PendingIntent para a nossa notificação. Nela, criamos uma intent que iniciará a atividade MainActivity, e então, usamos o getActivity para criar o PendingIntent.

01. public class NotificationUtils { 
02.   private static final int PENDING_INTENT_ID = 1;
03.   private static PendingIntent contentIntent(Context context) {

04.      Intent startActivityIntent = new Intent(context,                                                                           MainActivity.class);
05.      return PendingIntent.getActivity(context,
                                          PENDING_INTENT_ID,                       
                                          startActivityIntent,                     
                                          PendingIntent.FLAG_UPDATE_CURRENT);
06.   }

07. }


Para adicionar um ícone para a nossa notificação, adicione um ícone na pasta Drawable e vamos adicionar o método abaixo, onde pegamos o ícone no Resource e convertemos em bitmap.

01. private static Bitmap largeIcon(Context context) {            
02.     Resources res = context.getResources();    
03.     Bitmap largeIcon = BitmapFactory.decodeResource(res,  
                              R.drawable.ic_local_drink_black_24px);    
04.     return largeIcon;
05. }

Agora vamos criar a nossa notificação: começamos obtendo uma instância do NotificationManager usando o método getSystemService do contexto, passando como parâmetro, a constante NOTIFICATION_SERVICE (linha 04).

A partir do Android O (Oreo), nós devemos criar um canal de notificação. Por isso verificamos se o sistema do SDK é para Android O (linha 05) e se for, criamos um objeto NotificationChannel, com um ID do canal, o nome do canal, a prioridade (linha 06) e então mandamos para o notificationManager.(linha 07).

Então, vamos criar a notificação. Para isso, podemos usar um builder, que possui diversos métodos para configurar a aparência da notificação (linha 12). O principal dessa linha é o método setContentIntent, que recebe o PendingIntent que declaramos anteriormente e o setAutoCancel, para que o mesmo desapareça assim que for clicado.

O próximo trecho é a configuração de prioridade que existe a partir da versão Jelly Beam, mas antes do Oreo. Então fazemos esta verificação (linha 13) e se for verdadeira, setamos uma prioridade (linha 14).

Finalmente, na linha 16, usamos o notify para gerar a notificação.

01. private static final int NOTIFICATION_ID = 1138;
02. private static final String NOTIFICATION_CHANNEL_ID = "reminder_notification_channel";

03. public static void remindUserBecauseCharging(Context context) {
    
04.        NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
        
05.        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
06.            NotificationChannel mChannel = new NotificationChannel(
                    NOTIFICATION_CHANNEL_ID,
                    context.getString(R.string.main_notification_channel_name),
                    NotificationManager.IMPORTANCE_HIGH);
07.            notificationManager.createNotificationChannel(mChannel);
08.        }
        
12.        NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context,NOTIFICATION_CHANNEL_ID)
                .setColor(ContextCompat.getColor(context, R.color.colorPrimary))
                .setSmallIcon(R.drawable.ic_drink_notification)
                .setLargeIcon(largeIcon(context))
 .setContentTitle(context.getString(R.string.charging_reminder_notification_title))
 .setContentText(context.getString(R.string.charging_reminder_notification_body))
                .setStyle(new NotificationCompat.BigTextStyle().bigText(                        context.getString(R.string.charging_reminder_notification_body)))
                .setDefaults(Notification.DEFAULT_VIBRATE)
                .setContentIntent(contentIntent(context))
                .setAutoCancel(true);

13.        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN
                && Build.VERSION.SDK_INT < Build.VERSION_CODES.O) {
14.            notificationBuilder.setPriority(NotificationCompat.PRIORITY_HIGH);
15.        }

16.         notificationManager.notify(NOTIFICATION_ID, tificationBuilder.build());
17.    }

Ações nas Notificações
As vezes, não é prático a notificação abrir o aplicativo enquanto a escolha do que fazer pode ser implementado na própria notificação. E é isso que vamos permitir. O  Android permite atribuir até 3 ações em uma notificação. O Código abaixo mostra como se cria uma ação:

private static Action drinkWaterAction(Context context) {
        Intent incrementWaterCountIntent = new Intent(context, WaterReminderIntentService.class);
        incrementWaterCountIntent.setAction(ReminderTasks.ACTION_INCREMENT_WATER_COUNT);
        PendingIntent incrementWaterPendingIntent = PendingIntent.getService(
                context,
                ACTION_DRINK_PENDING_INTENT_ID,
                incrementWaterCountIntent,
                PendingIntent.FLAG_CANCEL_CURRENT);
        Action drinkWaterAction = new Action(R.drawable.ic_local_drink_black_24px,
                "I did it!",
                incrementWaterPendingIntent);
        
return drinkWaterAction;
 }

Basicamente ele cria um Intent para chamar um serviço e configura os parâmetros para o mesmo. Então adiciona-o em um PendingIntent;. Depois instancia-se um objeto Action com um ícone, uma mensagem e o PendingIntent que vai ser executado quando selecionado. Para adicionar o mesmo, no NotificationBuilder, use o método addAction para adicionar o objeto Action.


Limpar as Notificações
Dependendo das ações no aplicativo, também pode ser conveniente que devemos limpar as notificações quando as mesmas já não são mais necessárias. Para isso, podemos implementar o seguinte método:

public static void clearAllNotifications(Context context) {
   NotificationManager notificationManager =             (NotificationManager) context.getSystemService (Context.NOTIFICATION_SERVICE);
   notificationManager.cancelAll();
}

o método cancelAll do notificationManager limpa todas as notificações..

Nenhum comentário:

Postar um comentário