In my app i am getting the all call log by using this code.it return me all the call log in my android phone.
public class CallLogHelper {
public static Cursor getAllCallLogs(ContentResolver cr) {
// reading all data in descending order according to DATE
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Uri callUri = Uri.parse("content://call_log/calls");
Cursor curCallLogs = cr.query(callUri, null, null, null, strOrder);
return curCallLogs;
}
public static void insertPlaceholderCall(ContentResolver contentResolver,
String name, String number) {
ContentValues values = new ContentValues();
values.put(CallLog.Calls.NUMBER, number);
values.put(CallLog.Calls.DATE, System.currentTimeMillis());
values.put(CallLog.Calls.DURATION, 0);
values.put(CallLog.Calls.TYPE, CallLog.Calls.OUTGOING_TYPE);
values.put(CallLog.Calls.NEW, 1);
values.put(CallLog.Calls.CACHED_NAME, name);
values.put(CallLog.Calls.CACHED_NUMBER_TYPE, 0);
values.put(CallLog.Calls.CACHED_NUMBER_LABEL, "");
Log.d("Call Log", "Inserting call log placeholder for " + number);
contentResolver.insert(CallLog.Calls.CONTENT_URI, values);
}
}
But my problem is this i want to get the call log from specific date, not all call log. I have no idea how to use the query to get the call log from specific date.
Help me Thanks
String[] strFields = {
android.provider.CallLog.Calls.NUMBER,
android.provider.CallLog.Calls.TYPE,
android.provider.CallLog.Calls.CACHED_NAME,
android.provider.CallLog.Calls.DATE,
android.provider.CallLog.Calls.DURATION,
};
// Defines a string to contain the selection clause
String mSelectionClause = android.provider.CallLog.Calls.DATE+ " >= ?";
// Initializes an array to contain selection arguments
String[] mSelectionArgs = { createDate(2013,1,1).toString() };
Cursor mCallCursor = currentContext.getContentResolver().query(
android.provider.CallLog.Calls.CONTENT_URI,
strFields,
mSelectionClause,
mSelectionArgs,
null
);
return mCallCursor;
public static Long createDate(int year, int month, int day)
{
Calendar calendar = Calendar.getInstance();
calendar.set(year, month, day);
return calendar.getTimeInMillis();
}
StringBuffer sb = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Uri callUri = Uri.parse("content://call_log/calls");
Calendar calendar = Calendar.getInstance();
calendar.set(2014, Calendar.MAY, 25);
String fromDate = String.valueOf(calendar.getTimeInMillis());
calendar.set(2014, Calendar.MAY, 30);
String toDate = String.valueOf(calendar.getTimeInMillis());
String[] whereValue = {fromDate,toDate};
Cursor cur = cr.query(callUri, null, android.provider.CallLog.Calls.DATE+" BETWEEN ? AND ?", whereValue, strOrder);
//Cursor cur = cr.query(callUri, null, android.provider.CallLog.Calls.DATE+" >= ?", whereValue, strOrder);
// loop through cursor
while (cur.moveToNext()) {
String callNumber = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callName = cur
.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
String callDate = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.DATE));
SimpleDateFormat formatter = new SimpleDateFormat(
"dd-MMM-yyyy HH:mm");
String dateString = formatter.format(new Date(Long
.parseLong(callDate)));
String callType = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.TYPE));
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;
}
String isCallNew = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.NEW));
String duration = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.DURATION));
sb.append("\nPhone Number:--- " + callNumber + " \nName:--- "+ callName +" \nCall Type dir:--- " + dir + " \nCall Date:--- " + dateString + " \n duration in sec :--- " + duration);
sb.append("\n----------------------------------");
}
The call log that returned is between 25/05/2014 & 30/05/2014. The returned value is all stored in sb variable, you can set this value in a TextView for testing
Related
I am trying to get the calls count for missed/incoming/outgoing calls for a specific date
Got the below code working fine but its getting all the calls count overall (for every date)
String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE;
Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
m.moveToFirst();
String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE;
Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming, null, null);
i.moveToFirst();
String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE;
Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing, null, null);
o.moveToFirst();
String numberOfIn = String.valueOf(i.getCount());
String numberOfOut = String.valueOf(o.getCount());
String numberOfMiss = String.valueOf(m.getCount());
inCalls.setText(numberOfIn);
outCalls.setText(numberOfOut);
missCalls.setText(numberOfMiss);
I cant wrap my head on how to get the count of calls for example todays date can anyone provide me with atleast hints on where shall i look or what i am missing
i tried this solution but it returns the calls as 0 which is not
String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + "=" + datetoday.getDate();
Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
m.moveToFirst();
Alrighty,
Problem is the Date objects you are comparing in your SQL statements are completely different.
CallLog.Calls.DATE is returning the date the call occured, in milliseconds since the epoch.
And the datetoday.getDate() is returning YYYY-MM-DD hh:mm:ss.mmm format.
Well you caught me bored, so something like this works:
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TextView mCallView = (TextView) findViewById(R.id.call);
/*checkPermission(Manifest.permission.READ_CALL_LOG, 100);
checkPermission(Manifest.permission.WRITE_CALL_LOG, 101);
checkPermission(Manifest.permission.READ_CONTACTS, 102);*/
Date date1 = new Date(calculateMilliSince1970("2020-05-28"));
Date date2 = new Date(calculateMilliSince1970("2020-05-29"));
mCallView.setText(getCallDetails(date1,date2));
}
long calculateMilliSince1970(String date)
{
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try
{
Date mDate = sdf.parse(date);
long timeInMilliseconds = mDate.getTime();
Log.d("TAG","Date in milli :: " + timeInMilliseconds);
return timeInMilliseconds;
}
catch (ParseException e)
{
e.printStackTrace();
}
return 0;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 100) {
// Checking whether user granted the permission or not.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Showing the toast message
Toast.makeText(MainActivity.this,
"Permission Granted",
Toast.LENGTH_SHORT)
.show();
}
else {
Toast.makeText(MainActivity.this,
"Permission Denied",
Toast.LENGTH_SHORT)
.show();
}
}
}
public void checkPermission(String permission, int requestCode) {
// Checking if permission is not granted
if (ContextCompat.checkSelfPermission(
MainActivity.this,
permission)
== PackageManager.PERMISSION_DENIED) {
ActivityCompat
.requestPermissions(
MainActivity.this,
new String[] { permission },
requestCode);
}
else {
Toast
.makeText(MainActivity.this,
"Permission already granted",
Toast.LENGTH_SHORT)
.show();
}
}
private StringBuffer getCallDetails(Date date1, Date date2) {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery( CallLog.Calls.CONTENT_URI,null, null,null, null);
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.parseLong(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;
}
if (isWithinRange(callDayTime, date1, date2)) {
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n------------------------------------------------------------------------------------------------------------------------------");
}
}
managedCursor.close();
return sb;
}
boolean isWithinRange(Date testDate, Date startDate, Date endDate) {
Log.i("TAG", "isWithinRange: "+ "Test date is "+ testDate+ " start date is "+ startDate +" compare is "+testDate.before(startDate));
return !(testDate.before(startDate) || testDate.after(endDate));
}
}
After looking into the answer provided by #forthelulx and getting to know that the CallLog.Calls.DATE is returning the date in milliseconds.
got it working exactly as intended and returning the number of the type of calls for the day
Here is the code if anyone requires it
Date c = Calendar.getInstance().getTime();
System.out.println("Current time => " + c);
SimpleDateFormat df = new SimpleDateFormat("dd-MM-yy");
final String formattedDate = df.format(c);
long timeInMilliseconds = c.getTime();
long timeInMiliDayBefore = timeInMilliseconds - 86400000;
String[] projectionMissed = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereMissed = CallLog.Calls.TYPE+"="+CallLog.Calls.MISSED_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
Cursor m = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionMissed,whereMissed, null, null);
m.moveToFirst();
String[] projectionIncoming = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereIncoming = CallLog.Calls.TYPE+"="+CallLog.Calls.INCOMING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
Cursor i = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionIncoming,whereIncoming , null, null);
i.moveToFirst();
String[] projectionOutgoing = { CallLog.Calls.CACHED_NAME, CallLog.Calls.CACHED_NUMBER_LABEL, CallLog.Calls.TYPE };
String whereOutgoing = CallLog.Calls.TYPE+"="+CallLog.Calls.OUTGOING_TYPE+ " AND " + CallLog.Calls.DATE + ">=" + timeInMiliDayBefore;
Cursor o = getContentResolver().query(CallLog.Calls.CONTENT_URI, projectionOutgoing,whereOutgoing , null, null);
o.moveToFirst();
String numberOfIn = String.valueOf(i.getCount());
String numberOfOut = String.valueOf(o.getCount());
String numberOfMiss = String.valueOf(m.getCount());
inCalls.setText(numberOfIn);
outCalls.setText(numberOfOut);
missCalls.setText(numberOfMiss);
I have a method in which i am trying to get call logs of a phone. but because of deprecated ManagedQuery() i am not able to get that. Please help how can i modify that to meet my needs.
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
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 Log :");
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();
textView.setText(sb);
}
Unfortunately the compiler show me a problem on:
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
Because managedQuery() is deprecated.
How could I rewrite this method without using managedQuery()?
You can replace your managedQuery with it :
Cursor managedCursor = getContentResolver().query(
CallLog.Calls.CONTENT_URI, null, null, null, null);
I found my answer here..
LoaderManager.LoaderCallbacks
Thanks everyone for the help!!!
Do your UI update from the strings accordingly..
String[] details = new String[]{CallLog.Calls.NUMBER,
CallLog.Calls.TYPE,
CallLog.Calls.DURATION,
CallLog.Calls.CACHED_NAME,
CallLog.Calls._ID};
Cursor cursor;
cursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI, details, null, null, CallLog.Calls._ID + " DESC");
if(cursor.getCount()!=0){
cursor.moveToFirst();
String number = cursor.getString(0);
String type=cursor.getString(1);
String duration=cursor.getString(2);
String name=cursor.getString(3);
String id=cursor.getString(4);
String dir = null;
switch (Integer.parseInt(type)) {
case CallLog.Calls.OUTGOING_TYPE:
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
}
cursor.close();
I have created an android app, in that I wants last call detail of the number.
Using CallLog.Calls.DURATION I get the last call detail.
My code is-
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, null);
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 :");
if(managedCursor.moveToFirst())
{
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
String callDuration = managedCursor.getString(duration);
int calld=Integer.parseInt(callDuration);
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 :--- " + calld);
sb.append("\n----------------------------------");
}
managedCursor.close();
System.out.println(sb);
In one device I get last call detail using managedCursor.moveToFirst() and in another device I get last call detail using managedCursor.moveToLast().
How to achieve it using single code?
You can add an ORDER BY clause to the query to order them descending by the time of the call.
Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, CallLog.Calls.DEFAULT_SORT_ORDER);
OR
Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, CallLog.Calls.DATE + " DESC");
I am looking for an easiest way to get call duration of last dialed number. So for e.g if I have made a call to my mom once I cut the call a notification with the duration should come up.
I am trying out the following but the problem is that it comes with a full list of duration. incoming, outgoing, missed.
How do I differentiate it:
I tried the following:
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Cursor cur = getContentResolver().query( CallLog.Calls.CONTENT_URI,null, null,null, android.provider.CallLog.Calls.DATE + " DESC");
int number = cur.getColumnIndex( CallLog.Calls.NUMBER );
int duration = cur.getColumnIndex( CallLog.Calls.DURATION);
sb.append( "Call Details : \n");
while ( cur.moveToNext() ) {
String phNumber = cur.getString( number );
String callDuration = cur.getString( duration );
String dir = null;
sb.append( "\nPhone Number:--- "+phNumber +" \nCall duration in sec :--- "+callDuration );
sb.append("\n----------------------------------");
}
cur.close();
call.setText(sb);
}
You need to use limit clause in your content query to get the last call details.
So your content query will become
Cursor cur = getContentResolver().query( CallLog.Calls.CONTENT_URI,
null, null, null, android.provider.CallLog.Calls.DATE + " DESC limit 1;");
Try below code:
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = context.getContentResolver().query(contacts, null, null, null, null);
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()) {
HashMap rowDataCall = new HashMap<String, String>();
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
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();
System.out.println(sb);
You will get Call Type in below line:
int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
This is my code and works perfectly fine for last outgoing call.
private String getCallDetails() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null,
null, null, null);
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);
managedCursor.moveToLast();
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;
}
if(dir.equals("OUTGOING")){
//whatever you want here
return "yes";
}
managedCursor.close();
return "no";
}
Get Last call duration and not previous try giving a delay
private Handler finishedCall = new Handler();
finishedCall.postDelayed(new Runnable() {
#Override
public void run() {
String dura = LastCall();
}, 1000);
And Call the Lastcall function
public String LastCall() {
String callDura = "0";
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
callDura = null;
}
else {
Cursor managedCursor = getApplicationContext().getContentResolver().query(
contacts, null, null, null, android.provider.CallLog.Calls.DATE + " DESC limit 1;");
int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int duration1 = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
if (managedCursor.moveToFirst() == true) {
String phNumber = managedCursor.getString(number);
callDura = managedCursor.getString(duration1);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
String dir = null;
Log.e("DUR", "\nPhone Number:--- " + phNumber + " \nCall duration in sec :--- " + callDura + " \nCall Date in sec :--- " + callDayTime);
}
managedCursor.close();
}
return callDura;
}
This code works fine for me.......
void retriveCallSummary() {
Log.i("*****retriveCallSummary******","Call retrive method worked");
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = mContext.getContentResolver().query(
contacts, null, null, null, null);
int number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
int duration1 = managedCursor.getColumnIndex( CallLog.Calls.DURATION);
if( managedCursor.moveToFirst() == true ) {
String phNumber = managedCursor.getString( number );
String callDuration = managedCursor.getString( duration1 );
String dir = null;
sb.append( "\nPhone Number:--- "+phNumber +" \nCall duration in sec :--- "+callDuration );
sb.append("\n----------------------------------");
Log.i("*****Call Summary******","Call Duration is:-------"+sb);
}
managedCursor.close();
}
This code it work 100% i used
public String LastCall() {
StringBuffer sb = new StringBuffer();
Cursor cur = getContentResolver().query( CallLog.Calls.CONTENT_URI,null, null,null, android.provider.CallLog.Calls.DATE + " DESC");
int number = cur.getColumnIndex( CallLog.Calls.NUMBER );
int duration = cur.getColumnIndex( CallLog.Calls.DURATION);
sb.append("Call Details : \n");
while ( cur.moveToNext() ) {
String phNumber = cur.getString( number );
String callDuration = cur.getString( duration );
sb.append( "\nPhone Number:"+phNumber);
break;
}
cur.close();
String str=sb.toString();
return str;
}
Here is code for getting the last call duration.Try it,it works. The last call duration is fetched from the call logs.
public void getCallLog() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
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 :");
Log.e("total count", "" + managedCursor.getCount());
//managedCursor.moveToPosition(managedCursor.getCount() - 1);
int currentCount = 0, lastPosition = 0;
while (managedCursor.moveToNext()) {
currentCount++;
//managedCursor.moveToPosition(managedCursor.getCount() - 1);
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:
// lastPosition = currentCount;
dir = "OUTGOING";
break;
case CallLog.Calls.INCOMING_TYPE:
dir = "INCOMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
lastPosition = currentCount;
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
Log.e("test", sb.toString());
}
lastPosition--;
managedCursor.moveToPosition(lastPosition);
int requiredNumber = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
int durations = managedCursor.getColumnIndex(CallLog.Calls.DURATION);
String phNumber = managedCursor.getString(requiredNumber);
String dur = managedCursor.getString(durations);
textView.setText(phNumber);
textDuration.setText(dur);
Log.e("last position number ", phNumber);
Log.e("last call Duration ", dur);
managedCursor.close();
}
public class Home extends Activity {
TextView textView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.home_activity);
textView = (TextView) findViewById(R.id.textview_call);
getCallDetails();
}
private void getCallDetails() {
Context context;
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
try {
Cursor managedCursor = getContentResolver().query( CallLog.Calls.CONTENT_URI,null, null,null, android.provider.CallLog.Calls.DATE + " DESC limit 1;");
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()) {
HashMap rowDataCall = new HashMap<String, String>();
String phNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
String callDayTime = new Date(Long.valueOf(callDate)).toString();
// long timestamp = convertDateToTimestamp(callDayTime);
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();
System.out.println(sb);
textView.setText(sb);
}
catch (SecurityException e)
{
System.out.println();
// lets the user know there is a problem with the code
}
}
}
Use the following sort order:
CallLog.Calls.DATE " + " + CallLog.Calls.DURATION + " * 1000 desc "
I would like to receive the call log. For example the number of calls made by the user, number of minutes called, etc.
How do I achieve this in android?
This is for accessing phone call history:
As of Jellybean (4.1) you need the following permission:
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Code:
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
String num= c.getString(c.getColumnIndex(CallLog.Calls.NUMBER));// for number
String name= c.getString(c.getColumnIndex(CallLog.Calls.CACHED_NAME));// for name
String duration = c.getString(c.getColumnIndex(CallLog.Calls.DURATION));// for duration
int type = Integer.parseInt(c.getString(c.getColumnIndex(CallLog.Calls.TYPE)));// for call type, Incoming or out going.
This is method used to get the Call log. Just put this method in you class and get the List of the Call Log.
Check out this
private String getCallDetails() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null,
null, null, null);
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();
}
the output looks
use this method from everywhere with a context
private static String getCallDetails(Context context) {
StringBuffer stringBuffer = new StringBuffer();
Cursor cursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI,
null, null, null, CallLog.Calls.DATE + " DESC");
int number = cursor.getColumnIndex(CallLog.Calls.NUMBER);
int type = cursor.getColumnIndex(CallLog.Calls.TYPE);
int date = cursor.getColumnIndex(CallLog.Calls.DATE);
int duration = cursor.getColumnIndex(CallLog.Calls.DURATION);
while (cursor.moveToNext()) {
String phNumber = cursor.getString(number);
String callType = cursor.getString(type);
String callDate = cursor.getString(date);
Date callDayTime = new Date(Long.valueOf(callDate));
String callDuration = cursor.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;
}
stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- "
+ dir + " \nCall Date:--- " + callDayTime
+ " \nCall duration in sec :--- " + callDuration);
stringBuffer.append("\n----------------------------------");
}
cursor.close();
return stringBuffer.toString();
}
This post is a little bit old, but here is another easy solution for getting data related to Call logs content provider in Android:
Use this lib: https://github.com/EverythingMe/easy-content-providers
Get all calls:
CallsProvider callsProvider = new CallsProvider(context);
List<Call> calls = callsProvider.getCalls().getList();
Each Call has all fields, so you can get any info you need:
callDate, duration, number, type(INCOMING, OUTGOING, MISSED), isRead, ...
It works with List or Cursor and there is a sample app to see how it looks and works.
In fact, there is a support for all Android content providers like: Contacts, SMS, Calendar, ...
Full doc with all options: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers
Hope it also helped :)
in My project i am getting error int htc device.now this code is universal.
I think this is help for you.
public class CustomContentObserver extends ContentObserver {
public CustomContentObserver(Handler handler) {
super(handler);
System.out.println("Content obser");
}
public void onChange(boolean selfChange) {
super.onChange(selfChange);
String lastCallnumber;
currentDate = sdfcur.format(calender.getTime());
System.out.println("Content obser onChange()");
Log.d("PhoneService", "custom StringsContentObserver.onChange( " + selfChange + ")");
//if(!callFlag){
String[] projection = new String[]{CallLog.Calls.NUMBER,
CallLog.Calls.TYPE,
CallLog.Calls.DURATION,
CallLog.Calls.CACHED_NAME,
CallLog.Calls._ID};
Cursor c;
c=mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, CallLog.Calls._ID + " DESC");
if(c.getCount()!=0){
c.moveToFirst();
lastCallnumber = c.getString(0);
String type=c.getString(1);
String duration=c.getString(2);
String name=c.getString(3);
String id=c.getString(4);
System.out.println("CALLLLing:"+lastCallnumber+"Type:"+type);
Database db=new Database(mContext);
Cursor cur =db.getFirstRecord(lastCallnumber);
final String endCall=lastCallnumber;
//checking incoming/outgoing call
if(type.equals("3")){
//missed call
}else if(type.equals("1")){
//incoming call
}else if(type.equals("2")){
//outgoing call
}
}
c.close();
}
}
To get Incoming,Outgoing and Missed Call history , hope this code will help u:)
Call this code on your background thread.
StringBuffer sb = new StringBuffer();
String[] projection = new String[] {
CallLog.Calls.CACHED_NAME,
CallLog.Calls.NUMBER,
CallLog.Calls.TYPE,
CallLog.Calls.DATE,
CallLog.Calls.DURATION
};
sb.append("Call Details :");
// String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Cursor managedCursor = getApplicationContext().getContentResolver().query(CallLog.Calls.CONTENT_URI, projection, null, null, null);
while (managedCursor.moveToNext()) {
String name = managedCursor.getString(0); //name
String number = managedCursor.getString(1); // number
String type = managedCursor.getString(2); // type
String date = managedCursor.getString(3); // time
#SuppressLint("SimpleDateFormat")
SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm");
String dateString = formatter.format(new Date(Long.parseLong(date)));
String duration = managedCursor.getString(4); // duration
String dir = null;
int dircode = Integer.parseInt(type);
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 Name :-- "+name+" Number:--- " + number + " \nCall Type:--- " + dir + " \nCall Date:--- " + dateString + " \nCall duration in sec :--- " + duration);
sb.append("\n----------------------------------");
Before considering making Read Call Log or Read SMS permissions a part of your application I strongly advise you to have a look at this policy of Google Play Market: https://support.google.com/googleplay/android-developer/answer/9047303?hl=en
Those permissions are very sensitive and you will have to prove that your application needs them. But even if it really needs them Google Play Support team may easily reject your request without proper explanations.
This is what happened to me. After providing all the needed information along with the Demonstration video of my application it was rejected with the explanation that my "account is not authorized to provide a certain use case solution in my application" (the list of use cases they may consider as an exception is listed on that Policy page). No link to any policy statement was provided to explain what it all means. Basically they just judged my app as not to go without proper explanation.
I wish you good luck of cause with your applications guys but be careful.
To get Only Incoming Call history , the beneath code will help u:)
private void getCallDetailsAgil() {
StringBuffer sb = new StringBuffer();
Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
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";
sb.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " + callDayTime + " \nCall duration in sec :--- " + callDuration);
sb.append("\n----------------------------------");
miss_cal.setText(sb);
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED";
break;
}
}
managedCursor.close();
}
Use Below code:
private void getCallDeatils() {
StringBuffer stringBuffer = new StringBuffer();
Cursor managedCursor = getActivity().managedQuery(CallLog.Calls.CONTENT_URI, null, null, null, null);
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);
stringBuffer.append("Call Deatils");
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));
DateFormat df = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
String reportDate = df.format(callDayTime);
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;
}
stringBuffer.append("\nPhone Number:--- " + phNumber + " \nCall Type:--- " + dir + " \nCall Date:--- " +callDate + " \nCall duration in sec :--- " + callDuration);
stringBuffer.append("\n----------------------------------");
logs.add(new LogClass(phNumber,dir,reportDate,callDuration));
}
If we use Kotlin it is shorter. Example of class which responds for provide call logs:
import android.content.Context
import android.database.Cursor
import android.provider.CallLog.Calls.*
class CallsLoader {
fun getCallLogs(context: Context): List<List<String?>> {
val c = context.applicationContext
val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)
val cursor = c.contentResolver.query(
CONTENT_URI,
projection,
null,
null,
null,
null
)
return cursorToMatrix(cursor)
}
private fun cursorToMatrix(cursor: Cursor?): List<List<String?>> {
val matrix = mutableListOf<List<String?>>()
cursor?.use {
while (it.moveToNext()) {
val list = listOf(
it.getStringFromColumn(CACHED_NAME),
it.getStringFromColumn(NUMBER),
it.getStringFromColumn(TYPE),
it.getStringFromColumn(DATE),
it.getStringFromColumn(DURATION)
)
matrix.add(list.toList())
}
}
return matrix
}
private fun Cursor.getStringFromColumn(columnName: String) =
getString(getColumnIndex(columnName))
}
We can also convert cursor to map:
fun getCallLogs(context: Context): Map<String, Array<String?>> {
val c = context.applicationContext
val projection = arrayOf(CACHED_NAME, NUMBER, TYPE, DATE, DURATION)
val cursor = c.contentResolver.query(
CONTENT_URI,
projection,
null,
null,
null,
null
)
return cursorToMap(cursor)
}
private fun cursorToMap(cursor: Cursor?): Map<String, Array<String?>> {
val arraySize = cursor?.count ?: 0
val map = mapOf(
CACHED_NAME to Array<String?>(arraySize) { "" },
NUMBER to Array<String?>(arraySize) { "" },
TYPE to Array<String?>(arraySize) { "" },
DATE to Array<String?>(arraySize) { "" },
DURATION to Array<String?>(arraySize) { "" }
)
cursor?.use {
for (i in 0 until arraySize) {
it.moveToNext()
map[CACHED_NAME]?.set(i, it.getStringFromColumn(CACHED_NAME))
map[NUMBER]?.set(i, it.getStringFromColumn(NUMBER))
map[TYPE]?.set(i, it.getStringFromColumn(TYPE))
map[DATE]?.set(i, it.getStringFromColumn(DATE))
map[DURATION]?.set(i, it.getStringFromColumn(DURATION))
}
}
return map
}