Wednesday, January 16, 2008

Phonecalls

Again, there was a bit of a break in the blog. One reason is personal: I moved to London to take a new job. The other reason is that this time I went into the hairy issue which is call handling in Android.

I worked with the m3-rc37a version of the emulator and I can tell you that emulator crashes are really common if you play with the telephony stuff in this version. Don't be surprised if the example program distributed with this blog entry does not show the behaviour I promise but crashes instead. It just happens with this emulator version.

The task I gave myself is catching incoming and outgoing calls which is easy. There needs to be just an IntentReceiver defined in the manifest and the onReceiveIntent method implemented in the intent receiver class. The manifest entry declares the filter for the IntentReceiver (again, the XML is mangled due to limitations of the blog engine).

PHONE_STATE is a general intent for signalling all sorts of phone events. The example program dumps the event bundle when the event comes in. In case of outgoing call, the event is delivered with state=OFFHOOK when the call starts then state=IDLE when the call finishes (state is a key in the intent bundle ("extras") and its string values are OFFHOOK and IDLE). In case of the incoming call (you can simulate it by telnet localhost 5554 then issuing the gsm call phone_number command on the console) the state transition is RINGING then IDLE again.

So far so good. Having a notification on incoming and outgoing calls is less useful, however, if the caller or the called number is not known. This turned out to be a really hairy issue for which I did not find the answer (just desperate help requests). I remembered the good old Series60 days and went for the call log.

The call log is surprisingly co-located in the database of the Contacts application. Try this:

There is the log. Unfortunately (or fortunately? :-)) Android enforces strict database separation for applications so the Contacts database cannot be accessed from within another Android application. Luckily, the Contacts application decided to share the data as Content Provider. There is even a facilitator class: CallLog.Calls. Dumping the call log is relatively easy after that (look at the PhoneIntent class which is an Activity that makes this dump on pressing a button).

Now the only thing remained to see how the database is updated with regards to phone calls. It turned out that the number is not visible when the call goes out or comes in (RINGING or OFFHOOK state) but is accessible through the content provider when the IDLE transition event comes in. I was not able, therefore, to capture the number of the currently ongoing call but I was able to capture the number of the call that has just finished.

Testing the example application was a pain for me. When working with calls, the emulator tended to crash on my PC without installing any applications. In order to monitor the event transitions, you have to bring up the phone application because it does not come to the front by itself. You can do that by pressing some digits at the emulator's opening screen. If you don't bring the phone app to front manually, you won't be able to answer or reject the call.

I propose that you don't run adb logcat while the call goes on - it tends to increase the chance of emulator crash. You can examine whether the number was retrieved succesfully from the call log by running adb logcat after the call was finished.

Your code helped me a lot in simulating the Phone calls,but iam getting only as call log empty.Can you please tell me how to simulate the calls.Can you please tell me the steps.My gmail id is ssasikr@gmail.com

Hello Gabor Paller, This code really helped me a lot. Now i am trying to make the same thing for SMS. Please tell me any good source of info or provide any sample code. I also figured out that there is a little bit of prob in ur logic as it prints on one entry. U should modify it and should return array of strings or vector in place of just one string. Then before printing convert it to a single string with '\n' inserted for each entry.

I tried to configure you code with android SDK 1.1 and android 1.5 but it is giving errors at some points. What could be wrong in it ? It seems it does not have android.net.ContentURI; so it is giving error there.

So now 4 years have passed yet I still see no apps out there that do anything with this info. There are 1,000 area code lookup apps -- that's a no-brainer -- but I want to see where the call is coming from BEFORE I answer it! And I know others have had the same thought.

But that would require two things, that ought to be fairly simple in an open source o/s: notice of inbound call (with number) and a way to write to the display while the phone is ringing. Yet with a reportedly unprecedented number of people developing for this platform, so far as I've seen this has yet to be accomplished. WTF?

So this is supposed to be the future of mobile phones? Screw that, I say bring back HDML!

Anonymous, there are two separate issues here.1. Whether the functionality your are looking for is possible through some hack.2. Whether it SHOULD be possible.

Regarding question #1, it is definitely possible. For example these guys have done it (disclaimer: my ex-employers). They implemented the feature in a variety of devices, usually exploiting some bug in the platform. Then we arrive to question #2: the implementors are normally silent about the method used because intercepting calls before the platform dialler does is considered a serious security flaw and they don't want the platform manufacturer to figure it out and patch the hole.

i want to make application which will be able to pick the phone can anyone send me the code for answering phone call with a button. my email id is vishaljha.amc@gmail.com.please if anyone know please help me

HiDo you have any idea about how to modify incoming and outgoing call screen view in android. I want a custom incoming and outgoing call screen If yes, please share this with me. My email address is shinupeter@tataelxsi.co.in

About the blog

This blog is a personal diary about my adventures with the Google Android platform. I write it in the hope that others may find my experiences useful but please, beware. The blog is created as I gain experience about the platform myself so errors, omissions, etc. may be found in the entries.