Android Tutorial: Build a Smart Dialer

PCQ Bureau
New Update

You use a smartphone. If you use any phone, you will use it to dial a number. But if you use a smartphone, should you dial the number? Now a days, you do not dial the number. Even with most feature phones, you specify the contact and the phone picks up the number and dials. But if the phone is smart, do you even need to specify the contact? You spend so much time with your phone, and your phone should know so much about your habits, your needs and your tasks that it should be able to guess who you want to dial, locate the contact, dial the number, and there you go. What I am saying is, you press the same button, and depending on the requirement then, the phone dials a different person.


That, now, is a tall order. Let us develop an application that will take only one step closer to a real smart dialer. This dialer now will follow a simple logic. It will work out who you want to dial by looking at who you dialed around this time yesterday. It will do that by checking your call log, and dial the same number again. To be more specific, it will go to your call log, work out 24 hours backwards, and locate the number you dialed closest to 24 hours back. And then it will dial that number for you. If you generally dial specific people at approximately specific times in a day, you would find this application handy.

We would be developing an Android application. I expect you are comfortable with programming in general. If you are not comfortable with Android programming, check some of my previous articles in PCQuest.

The Solution

Open Eclipse and create a new Android project. In the activity class, create a class level variable that calculates how many milliseconds are there in a day of 24 hours.

private final long DAY_IN_MILLIS = 24 * 60 * 60 * 1000;


Create a function as below, I have explained in the comments.

privatelong AbsoluteDifference(long lngTime) {

return (Math.abs(System.currentTimeMillis() - DAY_IN_MILLIS - lngTime));

/* Current time minus DAY_IN_MILLIS gives us this time yesterday. We are interested in the time

* difference between this time yesterday and the call log entry time



The onCreate() code will use the above function. I am writing the function, and commenting with explanations.


protectedvoid onCreate(Bundle savedInstanceState) {



ListView lstContacts;

/* This list view shows the contacts to be dialed in case the logic comes up with more than one number */

Cursor curCallLog;

/* This cursor will store the call log */

long lngDelta = Long.MAX_VALUE;

long lngMatchTime = 0;

String<> strProjection = {CallLog.Calls._ID, CallLog.Calls.NUMBER, CallLog.Calls.DATE};

String<> strFrom = {CallLog.Calls.NUMBER, CallLog.Calls.DATE};

int<> intLayout = {,};

String strWhere = CallLog.Calls.TYPE + " = " + CallLog.Calls.OUTGOING_TYPE;

/* We are interested only in the numbers you dialed. If it was an incoming call yesterday, most likely

* you would not want to dial that number today. If your logic is different from mine, you can skip

* this filter.


lstContacts = (ListView) findViewById(;

/* You need to create this list view in your

layout */

curCallLog = getContentResolver().query(CallLog.Calls.CONTENT_URI, strProjection, strWhere, null, null);

/* We expect there is a call log which finds at least one outgoing call

* If that will not be the case, we need to properly handle exception. I have not done that in this

* tutorial



while(!curCallLog.isAfterLast()) {

/* Loop through the call log to locate where the difference between the call log time and

* yesterday this time is the minimum


if (lngDelta > AbsoluteDifference(curCallLog.getLong(curCallLog.getColumnIndex(CallLog.Calls.DATE)))) {

lngDelta = AbsoluteDifference(curCallLog.getLong(curCallLog.getColumnIndex(CallLog.Calls.DATE)));

lngMatchTime = curCallLog.getLong(curCallLog.getColumnIndex(CallLog.Calls.DATE));

/* We also capture the time in the call log where the difference is the minimum */




strWhere = CallLog.Calls.DATE + " = " + lngMatchTime;

/* We will now locate the entry in the call log where the time is the calculated minimum time */

curCallLog = getContentResolver().query(CallLog.Calls.CONTENT_URI, strProjection, strWhere, null, null);

if (curCallLog.getCount() == 1) {


Intent itnDial = new Intent(Intent.ACTION_CALL, Uri.parse("tel:" + curCallLog.getString(curCallLog.getColumnIndex(CallLog.Calls.NUMBER))));

/* We have identified the number we want to dial, so let us dial now */



/* We have finished with our objective, so let us terminate the application */


SimpleCursorAdapter scaCallLog = new SimpleCursorAdapter(this, R.layout.callloglist, curCallLog, strFrom, intLayout, SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);


/* If the cursor returned more than one value, display the results in the list view */


I have provided explanations for my logic only. I have not explained core Android concepts. Read some of my previous articles if you need help, or check them out using your favorite search engine. You would also have to give appropriate permissions to the application in your manifest as applicable.

That completes the application. You can extend the application to go behind more than one day in the call log to check what number in the call log the user may be interested in dialing now.