Your smartphone is more than just a phone which you use for making and receiving calls mostly. You can program your smartphone for how you want to make calls, receive calls and so on. Android provides a rich set of libraries to help you do so. In this article we will create an Android application that will auto-send message to the callers in your sleep time.
The Requirement
I want to send an SMS notification to anyone who calls me when I am sleeping. To the best of my knowledge till now there is no way my phone can figure out if I am sleeping. Let us go with timings. If the time is between 10 PM and 6AM, I should be sleeping under normal circumstances, and if anyone calls me in between those hours, they will get an SMS requesting them to be more considerate about the time of the call.
You do not actually need to write your own application here. There are some applications available in the Google Play Store that cater to similar requirements. I tried the No Disturb application and what I got is that the phone does not ring during the indicated hours as it goes into silent mode. That is not what I want. I want the phone to ring leaving it to decide if I want to pick the call. We need to factor in emergencies. But the caller should still get the SMS. I could not find any setting that would do that. I also did not find an application that does what I want, though there could be some. I decided to write my own application, and I am sharing that with you here.
I expect you to be reasonably comfortable with Android programming to follow along. Alternatively, if you are comfortable with programming and have gone through my articles carried in last two issues, you would be able to comfortably follow along.
The Solution
Create a new Android project called Sleep Time. Create a new class derived from BroadcastReceiver and call it CallReceiver. In the manifest, grant yourself the permission android.permission.READ_PHONE_STATE. Register the receiver in the manifest and in the intent filter add the action android.intent.action.PHONE_STATE. Add the following code to the onReceive() method of the receiver:
String strState = intent.getStringExtra(TelephonyMa
nager.EXTRA_STATE);
if (strState.equals(TelephonyManager.EXTRA_
STATE_RINGING)) {
String strPhoneNo = intent.getStringExtra(Telephony
Manager.EXTRA_INCOMING_NUMBER);
}
The receiver will be triggered when there is a change to the phone state. If the phone is ringing, we are extracting the phone number of the caller to be used later. Grant the permission android.permission.SEND_SMS. At this stage all callers will get SMS independent of time. Create a new service derived class called SleepService.In the service, create a class level variable to store the telephony manager.
TelephonyManager tmgSleep;
Create the onCreate() for the service and instantiate
the telephony manager.
@Override
public void onCreate() {
super.onCreate();
tmgSleep = (TelephonyManager)getSystemServ
ice(Context.TELEPHONY_SERVICE);
}
Define the following constant in the receiver class.
public static String PHONE_NUMBER = "Phone Number";
In the onReceive() of the receiver class, add the following
code to the ‘if' condition.
Intent itnStart = new Intent(context, SleepService.
class);
itnStart.putExtra(PHONE_NUMBER, strPhoneNo);
context.startService(itnStart);
Create the listener at the class level for the service.
PhoneStateListener pslSleep = new PhoneStateListener()
{
public void onCallStateChanged(int state, String
incomingNumber) {
switch(state) {
case TelephonyManager.CALL_STATE_IDLE:
sendSMS();
break;
default:
break;
}
}
It is not a good idea to send an SMS while the phone state is ringing. We are waiting for the state to turn to idle and then we will send the SMS. We will be defining the function sendSMS() later.
We have added the phone number as an extra to an intent and starting the service. Register the phone state listener in the onStartCommand() of the service.
tmgSleep.listen(pslSleep, PhoneStateListener.LISTEN_
CALL_STATE);
Define a class level variable in the service to store the phone number.
private String strTo;
Extract the phone number in the onStartCommand() from the intent before registering the sleep listener. This intent comes as a parameter to onStartCommand().
Bundle bunSMS = intent.getExtras();
strTo = bunSMS.getString(CallReceiver.
PHONE_NUMBER);
In the service class add a constant to store the message
text for the SMS.
private final String MESSAGE = "This message is
from Sleep Time, an application created by Amaresh
" +
"and running on his mobile. Next time please
be more considerate of the calling hours";
Add a new method to send SMS and stop the service.
private void sendSMS() {
SmsManager smsSleep = SmsManager.getDefault();
smsSleep.sendTextMessage(strTo, null, MESSAGE,
null, null);
stopSelf();
}
Register the service in the manifest and run the application. You can exit the activity, still if the phone receives a call it should send an SMS to the caller. Unregister the listener in before calling stopSelf() in sendSMS().
tmgSleep.listen(pslSleep, PhoneStateListener.LISTEN_
NONE);
In the service, define the following class level constants
to define the do not disturb time slot.
private final int STARTTIME = 22;
private final int ENDTIME = 6;
In the onStartCommand() of the service, find out
the time and set the message to be send only during
the do not disturb slot. Here is the complete code for
the method.
@Override
public int onStartCommand(Intent intent, int flags,
int startId) {
int intHour;
super.onStartCommand(intent, flags, startId);
intHour = Calendar.getInstance().get(Calendar.
HOUR_OF_DAY);
if (intHour < ENDTIME || intHour >= STARTTIME)
{
Bundle bunSMS = intent.getExtras();
strTo = bunSMS.getString(CallReceiver.
PHONE_NUMBER);
tmgSleep.listen(pslSleep, PhoneStateListener.
LISTEN_CALL_STATE);
return START_STICKY;
}
else {
stopSelf();
return START_NOT_STICKY;
}
}
You can try the application with different start and end times, and if everything is working fine, you can customize the message to something suiting your taste. As there is nothing of significance in the activity, you can call finish() in the onCreate() of the activity. That completes the application. If you want, you can exclude certain important numbers to whom the SMS will not be sent irrespective of whatever time of the day or night they call. I will leave that as an exercise for you.