Mostrando postagens com marcador Notificação. Mostrar todas as postagens
Mostrando postagens com marcador Notificação. Mostrar todas as postagens

terça-feira, 12 de agosto de 2014

TechVideo: Android Wear

Olá povo,

O CESAR.EDU está com um projeto chamado TechVideo que tem o objetivo de disseminar o conhecimento técnico da instituição com a comunidade. Com isso, você ficará por dentro dos assuntos mais atuais do mercado com os professores do CESAR.EDU que também são colaboradores do C.E.S.A.R..
O primeiro vídeo foi comigo, e o assunto é "Android Wear", o sistema operacional do Google para dispositivos "vestíveis".
Quem não viu meus outros posts sobre o Android Wear, pode clicar aqui, aqui e aqui.

4br4ç05,
nglauber

terça-feira, 8 de julho de 2014

Android Wear - Notifications

Olá povo,

No post anterior, falamos de como configurar o ambiente para iniciar um emulador do Android Wear e como conecta-lo ao smartphone/tablet. Também vimos que as notificações disparadas nos handhelds (smatphones/tablets) ficam sincronizadas no smartwatch. Nesse post vou mostrar como se comportam as notificações nos Android Wear.

Crie um novo projeto no Android Studio 0.8 (ou superior), defina o nome do projeto e seu respectivo pacote e clique em Next. A janela abaixo será exibida, então marque apenas a opção "Phone and Tablet" (spoiler: o próximo post será sobre apps exclusivas para wearables).
Adicione uma Activity em branco ao projeto e conclua o assistente.
Nosso projeto será simples, terá uma Activity principal e outra (DetalheActivity) que receberá uma mensagem vinda do relógio. Na MainActivity, adicione os dois métodos abaixo que usaremos mais adiante.
private NotificationCompat.Builder
    criarNotificacao(String title, String text) {

    return new NotificationCompat.Builder(this)
        .setSmallIcon(R.drawable.ic_like)
        .setContentTitle(title)
        .setContentText(text)
        .setAutoCancel(true)
        .setDefaults(NotificationCompat.DEFAULT_ALL);
}

private void dispararNotificacao(
    Notification notification, int id) {

    NotificationManagerCompat notificationManager =
        NotificationManagerCompat.from(this);

    notificationManager.notify(id, notification);
}
Nada especial nesses dois métodos. O primeiro cria objeto NotificationCompat.Builder que constrói uma notificação com as propriedades mais comuns: título, texto, ícone, cor do led, som e vibração padrão (isso é feito na chamada ao setDefaults). O segundo dispara a notificação usando a classe NotificationManagerCompat. Mas o importante aqui é que essa classe está na versão 20 da API de compatibilidade, então certifique-se de que no seu arquivo build.gradle esteja com o appcompat-v7:20. Outra detalhe é que se você não estiver rodando no emulador do Android L, use o compileSdkVersion com o valor 'android-19' conforme abaixo.
apply plugin: 'com.android.application'

android {
    compileSdkVersion 'android-19'
    buildToolsVersion "20.0.0"

    defaultConfig {
        applicationId "nglauber.android.testewear"
        minSdkVersion 10
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            runProguard false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:20.+'
}
Então se dispararmos uma notificação simples podemos utilizar o método abaixo.
private void notificacaoSimples() {
    Intent viewIntent = 
        new Intent(this, MyActivity.class);

    PendingIntent viewPendingIntent =
        PendingIntent.getActivity(
            this, 0, viewIntent, 0);

    NotificationCompat.Builder notificationBuilder =
        criarNotificacao("Título", "Texto")
            .setContentIntent(viewPendingIntent);

    dispararNotificacao(
        notificationBuilder.build(), 1);
}
A notificação aparecerá no handheld e no relógio que ficará como abaixo.
Como podemos ver, não fizemos nada de especial do wear, então se você já fez seu aplicativo com notificações, elas estarão integradas com o wearable automaticamente (se eles estiverem pareados, óbvio). Outra coisa que podemos fazer em handhelds e que é ótimo nos relógios são as ações. Vamos ver como adicionar uma...
private void notificacaoComAcao() {
    Intent mapIntent = new Intent(Intent.ACTION_VIEW);
    Uri geoUri = Uri.parse(
        "geo:0,0?q=" + Uri.encode("Av.Caxangá"));
    mapIntent.setData(geoUri);

    PendingIntent mapPendingIntent =
        PendingIntent.getActivity(
            this, 0, mapIntent, 0);

    NotificationCompat.Builder notificationBuilder =
        criarNotificacao("Localização", "Av. Caxangá")
        .setContentIntent(mapPendingIntent)
        .addAction(R.drawable.ic_map, 
            "Abrir mapa", mapPendingIntent);

    dispararNotificacao(
        notificationBuilder.build(), 1);
}
Uma notificação similar a anterior será exibida no relógio, mas se fizermos o swipe para esquerda, veremos essa ação.
Ao clicarmos nessa ação, o aplicativos de mapa (Google Maps ou Waze, por exemplo) será iniciado no smartphone/tablet. Esse exemplo também não usa nada especial do Android Wear :(
Então vou deixar de enrolação e mostrar algo que só funcione no wear: responder uma notificação a partir do relógio como é feito no Gmail.
private void notificacaoComResposta() {
    RemoteInput remoteInput = new RemoteInput.Builder(
        DetalheActivity.EXTRA_VOICE_REPLY)
        .setLabel("Diga a resposta")
        .build();

    Intent replyIntent = new Intent(
        this, DetalheActivity.class);

    PendingIntent replyPendingIntent =
        PendingIntent.getActivity(
            this, 0, replyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT);

    NotificationCompat.Action action =
        new NotificationCompat.Action.Builder(
            R.drawable.ic_reply, "Responder", 
                replyPendingIntent)
            .addRemoteInput(remoteInput)
            .build();

    NotificationCompat.WearableExtender nwe =
        new NotificationCompat.WearableExtender();    

    Notification notification =
        criarNotificacao(
            "Título", "Passe a página p/ responder")
            .extend(nwe.addAction(action))
            .build();
    dispararNotificacao(notification, 1);
}
Quando a notificação for disparada, ao deslizar para a esquerda, teremos a ação de responder.

Ao clicarmos na ação, a tela do comando de voz será exibida, então podemos falar nossa resposta (ou digitar se você estiver usando o emulador).

Como podemos observar, disparamos uma Intent para DetalheActivity (que você deve criar), e nela podemos capturar o texto falado no relógio utilizando o código abaixo.
private CharSequence obterTextoFalado(Intent intent) {
    Bundle remoteInput = RemoteInput
        .getResultsFromIntent(intent);
    if (remoteInput != null) {
        return remoteInput
            .getCharSequence(EXTRA_VOICE_REPLY);
    }
    return null;
}
Muito simples não? Espero que todos os aplicativos de troca de mensagens (como WhatsApp) implementem isso, pois é muito legal! :)
Mas além de ações, podemos adicionar páginas que podem ser visualizadas fazendo o swipe para esquerda.
private void notificacaoComPaginas() {
    Intent viewIntent = new Intent(
        this, MyActivity.class);
    PendingIntent viewPendingIntent =
        PendingIntent.getActivity(
            this, 0, viewIntent, 0);

    NotificationCompat.Builder nb =
        criarNotificacao("Título", "Página1")
        .setContentIntent(viewPendingIntent);

    NotificationCompat.BigTextStyle pagesStyle =
        new NotificationCompat.BigTextStyle()
            .setBigContentTitle("Página 2")
            .bigText("Um monte de texto aqui...");

    Notification secondPageNotification =
        new NotificationCompat.Builder(this)
            .setStyle(secondPageStyle)
            .build();

    Notification twoPageNotification =
        new NotificationCompat.WearableExtender()
            .addPage(pagesStyle)
            .extend(nb)
            .build();

    dispararNotificacao(
        twoPageNotification, 1);
}


Assim, podemos ter um conteúdo maior na notificação utilizando páginas.

É isso aí povo. Nós como desenvolvedores agora temos que pensar que as notificações disparadas no seu aparelho também aparecerão nos smartwatches. Então não perca a oportunidade de fazer sua aplicação funcionar bem também nos relógios com Android Wear.

Qualquer dúvida, deixem seus comentários.

4br4ç05,
nglauber

Fonte: http://developer.android.com/training/wearables/notifications/index.html

domingo, 31 de outubro de 2010

Notificações personalizadas no Android

Olá povo,

A barra de notificações do Android permite chamar a atenção do usuário sem interromper o que ele possa estar fazendo. Por padrão, criamos uma notificação que exibe um texto quando ela é disparada, e outros dois quando a barra de notificações é expandida. Para tal, podemos executar o código abaixo:
// Cria a intent que será excutada ao clicar na notificação
Intent it = new Intent("UMA_ACTIVITY");
PendingIntent pi = 
  PendingIntent.getActivity(context, 0, it, 0);
   
// Criando Notificação
Notification notificacao = new Notification();
notificacao.icon = R.drawable.icon;
notificacao.tickerText = "Chegou uma notificação";
notificacao.when = System.currentTimeMillis();
notificacao.flags = Notification.FLAG_AUTO_CANCEL;

notificacao.setLatestEventInfo(context,
  "Mensagem Superior", "Detalhes", pi);
   
NotificationManager nm = (NotificationManager)
  context.getSystemService(
    Context.NOTIFICATION_SERVICE);
nm.notify(1234, notificacao);

Com isso teremos o resultado abaixo:

Porém, se quisermos personalizar a notificação podemos faze-lo criando um arquivo de layout e definindo-o como view da notificação. Vou exemplificar isso utilizando um exemplo bem comum: barra de progresso. Quando baixamos um arquivo do browser ou do Android market é possível ver a barra de notificação exibindo uma barra de progresso. Segue abaixo o código que faz isso.
Arquivo res/layout/minha_notificao.xml
<RelativeLayout
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/layout_id"
  android:orientation="horizontal"
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:padding="3dp">
 
<ImageView
  android:src="@drawable/icon"
  android:id="@+id/icone"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content"
  android:layout_marginRight="10dp"/>

<ProgressBar
  android:id="@+id/barraDeProgresso"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_toRightOf="@+id/icone"
  style="@android:style/Widget.ProgressBar.Horizontal" />
 
<TextView
  android:id="@+id/textoDeProgresso"
  android:layout_width="fill_parent"
  android:layout_height="wrap_content"
  android:layout_toRightOf="@+id/icone"
  android:layout_below="@+id/barraDeProgresso"/>
</RelativeLayout>

Agora vejamos como criar a notificação personalizada:
Intent it = new Intent("UMA_ACTIVITY");
PendingIntent pi = 
  PendingIntent.getActivity(this, 0, it, 0);
    
final Notification notificacao = new Notification();
notificacao.icon = R.drawable.icon;
// Não usaremos setLatestEventInfo, ao invés
// definimos a pending intent da notificação
notificacao.contentIntent = pi;

// Carrega as views a partir do arquivo de layout
final RemoteViews contentView = new RemoteViews(
  getPackageName(), R.layout.minha_notificacao);

// Define as views remotas como view da notificação
notificacao.contentView = contentView;

// Obtém a referência do NotificationManager
final NotificationManager nm = (NotificationManager)
  getSystemService(Context.NOTIFICATION_SERVICE);

// Dispara a notificação
nm.notify(1234, notificacao); 

// Simulando uma tarefa para atualizar a notificação
new Thread(){
  public void run(){
    for (int i = 0; i <= 100; i+=5) {
      // Simula uma tarefa
      try {
         Thread.sleep(1000);
      } catch (InterruptedException e) {
      }

      // Atualiza as views remotas       
      contentView.setProgressBar(
        R.id.barraDeProgresso, 100, i, false);

      contentView.setTextViewText(
        R.id.textoDeProgresso, i+"% concluído");

      // Reenvia a notificação
      nm.notify(1234, notificacao);
    }
  } 
}.start(); 


A utilização de views remotas (RemoteViews) se dá quando queremos acessar views que pertencem a outro processo. No nosso exemplo estamos acessando views que pertencem a aplicação de Notificação. Para atualizar a view, utilizamos uma thread para simular uma tarefa. Entretanto esse trabalho ficaria a cargo de um Service.

O resultado ficará como abaixo:


[Editado em 11/11/2010]
Uma funcionalidade legal da notificação é a possibilidade de tocar um som e acender o led do telefone.
/* 
É possível passar um som personalizado usando:
notificacao.sound = 
   Uri.parse("file:///sdcard/meu.mp3");

Abaixo usamos o som padrão de notificação do telefone
*/
notificacao.defaults = Notification.DEFAULT_SOUND;

// Ativa a flag para habilitar o led do telefone
notificacao.flags |= Notification.FLAG_SHOW_LIGHTS;

// Define o RGB da cor do led 
// (o hardware deixará aproximado)
notificacao.ledARGB = Color.YELLOW;

// Tempo ligado em milisegundos
notificacao.ledOnMS = 1000;

// Tempo desligado em milisegundos
notificacao.ledOffMS = 1000;

Editado em 31/10/2012
O construtor da classe Notification está deprecated. Devemos usar a classe NotificationCompat.Builder para criar as notificações em versões anteriores a 3.0.
PendingIntent pit =
  PendingIntent.getActivity(
    context, 0, new Intent(), 0);

Notification notificacao = 
  new NotificationCompat.Builder(context)
    .setTicker("Chegou uma mensagem do GCM")
    .setContentTitle("Nova mensagem")
    .setContentIntent(pit)
    .setContentText(extras.getString("mensagem"))
    .setSmallIcon(R.drawable.ic_launcher)
    .setAutoCancel(true)
    .build();

NotificationManager manager = (NotificationManager)
  getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(1, notificacao);

Qualquer dúvida, deixem seus comentários,

4br4ç05,
nglauber