Thursday, December 15, 2011

Calling log & SMS monitor (Android)


1, Monitor incoming calls




1: class DiagPhoneStateListener extends PhoneStateListener
   2: {        
   6:     @Override
   7:     public void onCallStateChanged(int state, String incomingNumber)
   8:     {        
   9:         switch(state)
  10:         {
  11:             case TelephonyManager.CALL_STATE_IDLE: //phone status goes to idle
  12:                 Logger.d(TAG, "phone call state -> idle");
  13:                 m_bIncomingFlag = false;   
  14:                 break;
  15:             case TelephonyManager.CALL_STATE_RINGING: 
  16:                 m_bIncomingFlag = true;                                                
  17:                 Logger.d(TAG, "incoming call ringing, " + incomingNumber);
  18:                 break;
  19:             case TelephonyManager.CALL_STATE_OFFHOOK: 
  20:                 if (m_bIncomingFlag) //if coming call
  21:                 {                        
  22:                     m_startTime = new Date();
  23:                     Logger.d(TAG, "incoming accept");
  24:                 }
  25:                 break;
  26:         }
  27:     }
  28:   }
  29:  
  30: TelephonyManager m_telMan = (TelephonyManager)m_context.getSystemService(Context.TELEPHONY_SERVICE);
  31: m_telMan.listen(m_diagCallingReceiver, PhoneStateListener.LISTEN_CALL_STATE | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);

additional permission


   1: <uses-permission android:name="android.permission.READ_PHONE_STATE" />
   2: <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /



2, Monitor outgoing calls


   1: class OutCallReceiver extends BroadcastReceiver 
   2: {    
   3:     public void onReceive(Context context, Intent intent) 
   4:     {
   5:         String action = intent.getAction();
   6:         if (action.equals(Intent.ACTION_NEW_OUTGOING_CALL)) //call others
   7:         {
   8:             //an outgoing call
   9:         }
  10:     }
  11: }
  12: IntentFilter filter = new IntentFilter();
  13: filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY); 
  14: filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);                
  15: m_context.registerReceiver(m_ocReceiver, filter);

[Important]

on some devices, manufactures use their own Calling App instead of the standard Google one. Their own calling app might not broadcast “Intent.ACTION_NEW_OUTGOING_CALL”, so you might can not catch the outgoing call intent.

e.g. You can catch the intent on Nexus One, Nexus S, while the receiver not working on HTC My Touch.



3, Monitor incoming SMS


   1: class SMSReceiver extends BroadcastReceiver 
   2: {    
   3:     public void onReceive(Context context, Intent intent) 
   4:     {
   5:         String action = intent.getAction();
   6:         Logger.e(TAG, "coming action: " + action);
   7:         
   8:         if (action.equals(ACTION_SMS_RECEIVED))
   9:         {
  10:             Bundle extras = intent.getExtras();
  11:             if (extras == null)9
  12:                 return;                
  13:             
  14:             Object messages[] = (Object[]) extras.get("pdus");
  15:             SmsMessage smsMessage[] = new SmsMessage[messages.length];
  16:             for (int n = 0; n < messages.length; n++) 
  17:             {
  18:                 smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
  19:                 
  20:                 String msgBody = smsMessage[n].getMessageBody();
  21:                 String msgAddress = smsMessage[n].getOriginatingAddress();
  22:                 String msgTime = String.valueOf(smsMessage[n].getTimestampMillis());
  23:             }                          
  24:         }                
  25:     }
  26: }
  27:  
  28: IntentFilter filter = new IntentFilter();
  29: filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
  30: filter.addAction(ACTION_SMS_RECEIVED);    
  31: m_context.registerReceiver(m_smsRec, filter);

additional permission


   1: <uses-permission android:name="android.permission.RECEIVE_SMS" />

4, Monitor outgoing SMS

Sorry, I didn’t find a similar solution like monitor incoming SMS. But I have another solution descripting below.

---------------------------------



5, Simplest solution

OK, here comes the simplest solution!

Monitor both incoming/outgoing calls and SMS by ContentObserver

[Important]

When observing to SMS, you should call moveToLast() to get the latest SMS event.

But please call moveToNext() to get latest calling event.


   1: class CalllogObserver extends ContentObserver
   2: {       
   3:     public CalllogObserver(Handler handler) 
   4:     {
   5:             super(handler);
   6:         }
   7:  
   8:         public void onChange(boolean bSelfChange)
   9:     {    
  10:         super.onChange(bSelfChange);
  11:         
  12:                 Cursor c = m_context.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, null);
  13:                 c.moveToLast(); //point to latest message! different to the sms, the latest call log was appened at the end of list
  14:                 
  15:                 String callStartTime = c.getString(c.getColumnIndex("date"));
  16:                 String callDuration = c.getString(c.getColumnIndex("duration"));
  17:                 String callType = c.getString(c.getColumnIndex("type")); // 1,incoming; 2,outgoing; 3,missed
  18:                 String callTarget = c.getString(c.getColumnIndex("number"));
  19:         }
  20: }
  21:  
  22: ContentResolver contentResolver = m_context.getContentResolver();
  23: Handler handler = new Handler();
  24: ContentObserver m_CalllogObserver = new CalllogObserver(handler);
  25: contentResolver.registerContentObserver(CallLog.Calls.CONTENT_URI, true, m_CalllogObserver);


   1: class SMSObserver extends ContentObserver
   2: {       
   3:     public SMSObserver(Handler handler) {
   4:         super(handler);
   5:     }
   6:  
   7:     public void onChange(boolean bSelfChange)
   8:     {    
   9:         super.onChange(bSelfChange);
  10:         Logger.e(TAG, "sms db changed");  
  11:  
  12:         String strUriInbox = "content://sms/";
  13:         Uri uriSms = Uri.parse(strUriInbox); 
  14:         Cursor c = m_context.getContentResolver().query(uriSms, null, null, null, null);
  15:         c.moveToNext(); //point to latest message!
  16:  
  17:         
  18:         int smsType = Integer.valueOf(c.getString(c.getColumnIndex("type")));
  19:         
  20:         if (smsType == 1 || smsType == 2) //inbox and sent
  21:         {
  22:             boolean bReceived = (smsType == 1) ? true : false;            
  23:             String smsTime = c.getString(c.getColumnIndex("date"));
  24:             String smsBody = c.getString(c.getColumnIndex("body"));
  25:             String smsAddress = c.getString(c.getColumnIndex("address"));
  26:         }
  27:         else
  28:         {
  29:             //DO NOTHINg
  30:             Logger.d(TAG, "skip non-inbox non-sent");
  31:         }
  32:         c.close();
  33:     }
  34: }
  35:  
  36: ContentResolver contentResolver = m_context.getContentResolver();
  37: Handler handler = new Handler();
  38: ContentObserver m_SMSObserver = new SMSObserver(handler);
  39: contentResolver.registerContentObserver(Uri.parse("content://sms/"), true, m_SMSObserver);

6 comments:

  1. hi

    i'm very interested with your code - Monitor outgoing SMS.

    can you send me the full version of it

    thanks

    syahaz@gmail.com

    ReplyDelete
  2. Nice Thread Tutorial, i am new in android , its help me a lot ...

    I have got some good links

    here
    at androidexample.com
    Incomming SMS Broadcast Receiver

    ReplyDelete
  3. Can you give me the screen shots of output of
    monitor outgoing and incoming sms

    ReplyDelete
  4. hi~~
    i'm very interested with your code - Monitor outgoing SMS.
    can you send me the full version of it
    thanks!
    my mail:fiona.chengad@gmail.com

    ReplyDelete
  5. Hi.
    Very nice job. Helped me lot.
    Please send me the code for monitoring outgoing calls.

    ReplyDelete
  6. Hello!
    I should say that I was fortunate enough to find app a monitoring SMS, call history and audio, camera, locations hoverwatch.com and besides, there is no need to open Notepad ++ and to dig into the code, so understandable interface and even my seven-year-old daughter can use this application if she wants)

    ReplyDelete