I want to write a service in Android that will track outgoing calls and SMS in the background. Whenever an outgoing call event or outgoing SMS message is received, I want to receive data, such as phone number, date, call duration (in case of outgoing call) and cost of call or SMS. I want to save this data in a local database.
I tried to use the broadcast receiver with the services, but I canβt calculate the actual duration of the call. And for SMS, I found out that we need to check the SMS folder after a certain period of time, whether it will be updated. Are there any events that will be notified after sending SMS.
Below is the code I have already tried -
My MainActivity.java
public class MainActivity extends Activity { TextView call = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); call = (TextView) findViewById(R.id.call); Intent intent = new Intent(this, HelloService.class); startService(intent); } }
My class of service
public class HelloService extends Service { CallDurationReceiver receiver = null; @Override public void onCreate() { receiver = new CallDurationReceiver(); IntentFilter filter = new IntentFilter(); filter.addAction("android.provider.Telephony.SMS_RECEIVED"); filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED); registerReceiver(receiver, filter); HandlerThread thread = new HandlerThread("ServiceStartArguments"); thread.start(); } @Override public int onStartCommand(Intent intent, int flags, int startId) { Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
My Broadcast Receiver -
public class CallDurationReceiver extends BroadcastReceiver { // instance variables of sharedpreferences SharedPreferences mSharedPrefernce; Editor e; // String variables for number,date,time,calltype String number, date, time, calltype; long startTime, endTime; @Override public void onReceive(final Context context, Intent intent) { Log.v("info", "calls info...."); // initialising the sharedpreferences mSharedPrefernce = context.getSharedPreferences("MyPref", 0); e = mSharedPrefernce.edit(); Bundle bundle = intent.getExtras(); if (bundle == null) return; // initialising the variables number = null; startTime = 0; endTime = 0; // getting incoming call details String state = bundle.getString(TelephonyManager.EXTRA_STATE); if ((state != null) && (state .equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING))) { Log.v("info", "Phone Ringing.."); number = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); Log.v("info", "Incomng Number: " + number); calltype = "Incoming"; Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); date = today.monthDay + "-" + (today.month + 1) + "-" + today.year; time = today.format("%k:%M:%S"); // putting the values into the SharedPreferences e.putString("number", number); e.putString("Type", calltype); e.putString("date", date); e.putString("time", time); e.commit(); Toast.makeText( context, "Detect Calls sample application\nIncoming number: " + number, Toast.LENGTH_SHORT).show(); } // getting outgoing call details else if (state == null) { number = bundle.getString(Intent.EXTRA_PHONE_NUMBER); Log.v("info", "Outgoing Number: " + number); calltype = "Outgoing"; Time today = new Time(Time.getCurrentTimezone()); today.setToNow(); date = today.monthDay + "-" + (today.month + 1) + "-" + today.year; time = today.format("%k:%M:%S"); // putting the values into the SharedPreferences e.putString("number", number); e.putString("Type", calltype); e.putString("date", date); e.putString("time", time); e.commit(); Toast.makeText( context, "Detect Calls sample application\nOutgoing number: " + number, Toast.LENGTH_SHORT).show(); } // called when the call is answered else if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_OFFHOOK)) { Log.v("info", "Call Ansered.."); startTime = System.currentTimeMillis(); e.putLong("start", startTime); e.commit(); } // called when the call is ended else if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_IDLE)) { Log.v("info", "Call Ended.."); String phonenumber=null, type=null, date1=null, time1=null, duration=null; // getting the values from the SharedPreferences phonenumber = mSharedPrefernce.getString("number", ""); type = mSharedPrefernce.getString("Type", ""); date1 = mSharedPrefernce.getString("date", ""); time1 = mSharedPrefernce.getString("time", ""); long start=0; start = mSharedPrefernce.getLong("start", 0); Log.v("info", "startTime=" + start); // clearing the SharedPreferences mSharedPrefernce.edit().clear(); endTime = System.currentTimeMillis(); Log.v("info", "endTime=" + endTime); long totalTime =0; totalTime = endTime - start; DateFormat df = new SimpleDateFormat("HH':'mm':'ss"); df.setTimeZone(TimeZone.getTimeZone("GMT+0")); duration = df.format(new Date(totalTime)); System.out.println("GOT SOMETHING - "+phonenumber + " " + date1 + " " + time1 + " " + duration + " " + type); Toast.makeText(context, phonenumber + " " + date1 + " " + time1 + " " + duration + " " + type, Toast.LENGTH_LONG).show(); } } }
and the manifest file is
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="17" /> <uses-permission android:name="android.permission.READ_CONTACTS" /> <uses-permission android:name="android.permission.WRITE_CALL_LOG" /> <uses-permission android:name="android.permission.READ_LOGS" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <uses-permission android:name="android.permission.RECEIVE_SMS" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.sumasoft.mb.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name="com.sumasoft.mb.HelloService" > </service> <receiver android:name=".CallDurationReceiver"> <intent-filter> <action android:name="android.intent.action.NEW_OUTGOING_CALL" /> </intent-filter> </receiver> </application>
I even tried to extract the latest outgoing call data from the call log, but I get all the calls, I only need the last outgoing call.
here is the code -
private String getCallDetails() { StringBuffer sb = new StringBuffer(); Cursor managedCursor = MainActivity.managedCursor; int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER ); int type = managedCursor.getColumnIndex( CallLog.Calls.TYPE ); int date = managedCursor.getColumnIndex( CallLog.Calls.DATE); int duration = managedCursor.getColumnIndex( CallLog.Calls.DURATION); sb.append( "Call Details :"); while ( managedCursor.moveToNext() ) { String phNumber = managedCursor.getString( number ); String callType = managedCursor.getString( type ); String callDate = managedCursor.getString( date ); Date callDayTime = new Date(Long.valueOf(callDate)); String callDuration = managedCursor.getString( duration ); String dir = null; int dircode = Integer.parseInt( callType ); switch( dircode ) { case CallLog.Calls.OUTGOING_TYPE: dir = "OUTGOING"; break; case CallLog.Calls.INCOMING_TYPE: dir = "INCOMING"; break; case CallLog.Calls.MISSED_TYPE: dir = "MISSED"; break; } sb.append( "\nPhone Number:--- "+phNumber +" \nCall Type:--- "+dir+" \nCall Date:--- "+callDayTime+" \nCall duration in sec :--- "+callDuration ); sb.append("\n----------------------------------"); } managedCursor.close(); return sb.toString(); }
Thanks in advance.