Technè

Tecnologia & Experiência do Usuário no C.E.S.A.R

Android: Comunicação entre aplicações e Broadcast Receivers

Posted by Felipe Ferraz On janeiro - 15 - 2011

* Este post foi redigido pela equipe C.E.S.A.R. Sorocaba

Em Android existem duas formas de comunicação entre aplicações e também entre seus componentes: Intent e Notification. Cada aplicação é gerenciada por apenas uma máquina virtual. O Intent, conforme já discutido no post anterior, é responsável por realizar uma chamada de sistema podendo, por exemplo, estabelecer a comunicação entre duas ou mais maquinas virtuais Dalvik.
Ao utilizar Intent, devemos ter ciência que cada um envia uma mensagem em broadcast para todas as aplicações e as suas correspondentes máquinas virtuais. Logo, é possível que qualquer aplicação intercepte estas informações. Para evitar essa situação, existe o conceito de IntentFilter, o qual consiste num mecanismo de criação de filtros que apenas determinadas aplicações reconheçam , através do uso de tags.
Sabemos que o conceito de Activity é necessário para construção de aplicações com interação gráfica, entretanto, existem algumas funcionalidades que não necessitam de tal recurso. Por isso, devemos usar o conceito de Broadcast Receiver. Com ele conseguimos capturar, em segundo plano, mensagens enviadas na forma de Intents.
Ao declarar uma Broadcast Receiver é necessário adicionar todos os Intent Filters com os respectivos valores das tags ação e categoria. Segue abaixo o trecho de código responsável por declarar um Broadcast Receiver (Intercept) e seus Intent Filters.

< receiver android:name=”Intercept”>
<intent-filter>
<action android:name=”android.provider.Telephony.SMS_RECEIVED” />
<category android:name=”android.intent.category.LAUNCHER” />
</intent-filter>
</receiver>

O segundo modo de comunicação é o Notification, que consiste em informar ao usuário que alguma tarefa no sistema foi realizada. Além disso, uma notificação pode carregar um Intent que representa a ação a ser executada quando o usuário clica sobre ela. Para criá-la é necessário utilizar um Notification Manager que é um componente que gerencia as notificações.
Segue abaixo um trecho de código responsável por declarar um Broadcast Receiver. É importante frisar que toda classe que compreende um Broadcast Receiver deve herdar da super classe Broadcast Receiver e sobreescrever, pelo menos, o método onReceive();

1
 public class Intercept extends BroadcastReceiver {
1
 
1
2
3
4
 @Override
public void onReceive(Context c, Intent intent) {
}
}

Neste post, vamos exemplificar como interceptar o recebimento de um sms e realizar diferentes ações de acordo com o conteúdo do mesmo. Para isso, devemos declarar um Broadcast Receiver que observa a ação “android.provider.Telephony.SMS_RECEIVED”. Além disso, no método onReceive() , através do Intent recebido como paramêtro temos acesso ao conteúdo do sms. Portanto, basta implementar as ações desejadas. No código abaixo existem 3 situações:
1. Se a mensagem contiver a estrutura “LIGAR ”, onde deve ser o número para o qual será efetuado uma ligação automaticamente;
2. Se a primeira palavra da mensagem for “LOCALIZACAO”, o sistema irá enviar uma mensagem para o remetente com a latitude e longitude do dispositivo atual;
3. Caso contrário, será exibida uma notificação personalizada informando que uma mensagem foi recebida.

1
2
@Override
public void onReceive(Context arg0, Intent arg1) {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
LocationManager locationManager = (LocationManager) arg0.getSystemService(arg0.LOCATION_SERVICE);

final Context context = arg0;

LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {

}

public void onStatusChanged(String provider, int status, Bundle extras) {}

public void onProviderEnabled(String provider) {}

public void onProviderDisabled(String provider) {}
};

locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

Sms sms = new Sms();
SmsMessage msg = sms.receberMensagem(arg1);
String celular = msg.getDisplayOriginatingAddress();
String mensagem = msg.getDisplayMessageBody();

Toast.makeText(arg0, "Recebi uma mensagem", Toast.LENGTH_SHORT).show();

if(mensagem.toUpperCase().compareTo("LOCALIZACAO") == 0) {
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
String msgEnvio;

msgEnvio = "Latitude: " + location.getLatitude() + "\nLongitude: " + location.getLongitude();

sms.enviarSms(context, celular, msgEnvio);
} else {

String mQuebrada[] = mensagem.split("\\s");
boolean flag = true;
if(mQuebrada.length == 2) {
if(mQuebrada[0].toUpperCase().compareTo("LIGAR") != 0) {
flag = false;
}
for(int i = 0; ((i &lt; mQuebrada[1].length()) &amp;&amp; flag); i++) {
if(!Character.isDigit(mQuebrada[1].charAt(i))) {
flag = false;
}
}
} else {
flag = false;
}
if(flag) {
Intent it = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + mQuebrada[1]));
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
arg0.startActivity(it);
} else {
exibeNotificacao("Mensagem", "Mensagem Recebida", arg0);
}
}
}

private void exibeNotificacao(String titulo, String conteudo, Context context) {
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

int icon = R.drawable.icon;
CharSequence tickerText = "Mensagem: Nova notificação";
long when = System.currentTimeMillis();

Notification notification = new Notification(icon, tickerText, when);

CharSequence contentTitle = titulo;
CharSequence contentText = conteudo;
Intent notificationIntent = new Intent();

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

mNotificationManager.notify(1, notification);
1
 }

Todas as classes relacionadas a Location fazem parte da API de localização do Android e foram utilizadas para recuperar a latitude e longitude do disposivito atual. Além disso, foi utilizada uma classe chamada Sms que é responsável por enviar e receber sms , disponivel em http://pastebin.com/gfd6HN1L.

Categorias: Geral

3 Responses to “Android: Comunicação entre aplicações e Broadcast Receivers”

  1. Excelente texto. Precisei fazer algo parecido e haviam poucas fontes na web, nenhuma com explicação tão detalhada…
    Fico na dúvida se com esta abordagem será necessário adicionar a permissão de leitura de SMS no manifesto.

  2. Katharina says:

    Oi Artur,

    É necessário adicionar a permissão sim no Manifest. Seria a permissão de RECEIVE_SMS para a aplicação conseguir identificar que uma mensagem foi recebida.

  3. [...] através de um Intent-Filter para ACTION_BATTERY_CHANGED, também programamos um Broadcast( Ok, vcs já sabem oq achar aqui ) para ser executado quando essa Intent for disparada, e registramos esse Receiver para que possa [...]

Leave a Reply