0. Instead of entry
Periodically (when I have a free evening, and our “club” organizes the game) I play rugball. The “Club” is organized in such a way that on the day of the game all participants receive an SMS of the following type:
! 19-30. №30: . , 20. . . 8 (951) ***-**-**.
And so I thought - why not write a small application that will catch these messages, and fill them in the Google calendar. What for? Yes, basically, just for fun, because I’m not so busy a person that I need automatic secretaries.
So, the application will be able to do the following:
- Monitor incoming messages. If a message came from the addressee of RM FIGHT, then you need to verify the text of the message with the template, and, if it’s the same, create an event in the Google calendar. If the text of the message with the template does not match (for example, just some news came), then save the message in the database so that you can read it later.
- Show messages from this addressee that do not fall into the “Game Alert” category (news, advertising, etc.).
As part of this article, I believe that the reader has a basic knowledge of how to create a project, what a Manifest file is, and where to start development for android in general - there are a lot of different tutorials on this subject, and we will not dwell on this here. At the same time, the article is not intended for advanced android developers, it will deal with fairly basic things, such as monitoring and processing SMS, working with a database, connecting via HTTP.
So let's get started. By the way, the SDK version used is 14 (Android 4.0).
')
1. We intercept SMS
To monitor incoming SMS, we first need to request permission to receive them. To do this, you need to add an entry to the AndroidManifest.xml file:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
The next step is to implement the monitor to listen for incoming messages. To do this, register the
receiver in the manifest file:
<receiver android:name="SMSMonitor"> <intent-filter android:priority="100"> <action android:name="android.provider.Telephony.SMS_RECEIVED"/> </intent-filter> </receiver>
Here we set the priority to 100, so that our application can access the incoming SMS before the standard SMS handler, which has zero priority. After our application processes the message, it makes no sense to give it to the system, and put it in the Inbox.
Now create a class that extends
BroadcastReceiver
:
public class SMSMonitor extends BroadcastReceiver { private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED"; @Override public void onReceive(Context context, Intent intent) { } }
This class implements the abstract
onReceive()
method, which is called by the system each time a message is received. In the method we write:
if (intent != null && intent.getAction() != null && ACTION.compareToIgnoreCase(intent.getAction()) == 0) { Object[] pduArray = (Object[]) intent.getExtras().get("pdus"); SmsMessage[] messages = new SmsMessage[pduArray.length]; for (int i = 0; i < pduArray.length; i++) { messages[i] = SmsMessage.createFromPdu((byte[]) pduArray[i]); } }
Here we get a message using the
intent.getExtras().get("pdus")
, which returns an array of objects in the PDU format — we then
SmsMessage
these objects to the
SmsMessage
type using the
createFromPdu()
method.
Now attention. What we do after receiving the message must be executed
quickly . Broadcast receiver receives a high priority in the system, but it runs in the background and must be executed in a short time, so our capabilities are limited. For example, we can generate a notification or start a service to continue processing in it. Therefore, we will check the sender of the message, and if this is a notification about the game, we will pull out the text of the message and start the service, in which we will already process this message.
We add in the
onReceive()
method:
String sms_from = messages[0].getDisplayOriginatingAddress(); if (sms_from.equalsIgnoreCase("RM FIGHT")) { StringBuilder bodyText = new StringBuilder(); for (int i = 0; i < messages.length; i++) { bodyText.append(messages[i].getMessageBody()); } String body = bodyText.toString(); Intent mIntent = new Intent(context, SmsService.class); mIntent.putExtra("sms_body", body); context.startService(mIntent); abortBroadcast(); }
Here we compose the message text (in the case when the message was long and came in several SMS
messages[i]
, each separate part is stored in
messages[i]
) and call the
abortBroadcast()
method to prevent further processing of the message by other applications.
2. We process SMS
In the previous paragraph, we stopped at the fact that we start the service for processing SMS using the
startService()
method. Actually, what services are and what they are eaten with is well described on the
official site , therefore we will not dwell on this here.
Create the
SmsService
class that extends the
Service
class:
public class SmsService extends Service { @Override public IBinder onBind(Intent intent) { return null; } }
Since we have a local service, the onBind () method returns null.
To display notifications, we need the showNotification () helper method:
private void showNotification(String text) { PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), 0); Context context = getApplicationContext(); Notification.Builder builder = new Notification.Builder(context) .setContentTitle("Rugball") .setContentText(text) .setContentIntent(contentIntent) .setSmallIcon(R.drawable.ic_launcher) .setAutoCancel(true); NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE); Notification notification = builder.getNotification(); notificationManager.notify(R.drawable.ic_launcher, notification); }
In the
onStartCommand()
method
onStartCommand()
write:
@Override public int onStartCommand(Intent intent, int flags, int startId) { String sms_body = intent.getExtras().getString("sms_body"); showNotification(sms_body); return START_STICKY; }
It remains, in fact, to implement the
smsProcess()
method, which will add SMS to the database and form an event in the Google calendar. We will deal with this in the next part of the article.
UPDATE: posted the code on
github . I don’t have time with the second part of the article, I’m too busy at work. I hope to deal with this issue in the near future.