Tutorials with advanced 'difficulty' and more Lines of Code.


Postby paller » Thu Jan 17, 2008 12:39 am


Similar Tutorials:

You can access the crosslinked version of the entry here

This tutorial is about 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.

You can find the example program here.

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).

Syntax: [ Download ] [ Hide ]
Using xml Syntax Highlighting
  1. <receiver class=".PhoneIntentReceiver">
  2.   <intent-filter>
  3.      <action android:value="android.intent.action.PHONE_STATE" />
  4.    </intent-filter>
  5. </receiver>
Parsed in 0.001 seconds, using GeSHi

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:

adb shell
#cd /data/data/
# sqlite3 contacts.db sqlite3 contacts.db SQLite version 3.5.0
Enter ".help" for instructions
sqlite> .dump
CREATE TABLE calls (_id INTEGER PRIMARY KEY,number TEXT,number_key TEXT,number_type TEXT,date INTEGER,duration INTEGER,type INTEGER,person INTEGER,new INTEGER);
INSERT INTO "calls" VALUES(1,'+44444','44444+','Home',1200263250247,0,3,NULL,0); INSERT INTO "calls" VALUES(2,'+4444445','5444444+','Home',1200263859817,5,2,NULL,1); INSERT INTO "calls" VALUES(3,'+1234','4321+','Home',1200263990161,2,2,NULL,1);

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 even without installing any own call handling 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 successfully from the call log by running adb logcat after the call was finished.
Posts: 29
Joined: Mon Dec 31, 2007 2:33 am
Location: London


Re: Phonecalls

Postby iamshrini » Tue Nov 16, 2010 5:28 pm

Dear Pallar,
May I have the latest test code for phone listners.
Once Poster
Once Poster
Posts: 1
Joined: Tue Nov 16, 2010 4:04 pm


Return to Advanced Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest