* 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 < mQuebrada[1].length()) && 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.

home
blog de design do c.e.s.a.r.
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.
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.
[...] 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 [...]