Android how to Get the Calls counts for specific date - android

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

Related

How to get dual sim number call logs?

How to get dual sim number call logs in android. I followed below link to get the dual sim call logs but this method returns -1 always.
I tried other stackoverflow not much answers for dual sim call logs which is available from api 21.
https://stackoverflow.com/a/23907166/6891712
I have tried using the below method which give only the call details but not able to find that from which sim the call is dialed or received
private void getCalldetailsNow() {
#SuppressLint("MissingPermission") Cursor managedCursor=c.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DATE + " DESC");
int number = 0;
if (managedCursor != null) {
number = managedCursor.getColumnIndex( CallLog.Calls.NUMBER );
}
int duration1 = managedCursor.getColumnIndex( CallLog.Calls.DURATION);
int type1=managedCursor.getColumnIndex(CallLog.Calls.TYPE);
int date1=managedCursor.getColumnIndex(CallLog.Calls.DATE);
int idSimId = getSimIdColumn(managedCursor);
if( managedCursor.moveToFirst() == true ) {
String phNumber = managedCursor.getString(number);
String callDuration = managedCursor.getString(duration1);
String type=managedCursor.getString(type1);
String date=managedCursor.getString(date1);
String gettSimNumber=managedCursor.getString(idSimId);
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;
default:
dir = "MISSED";
break;
}
}
managedCursor.close();
}
public static int getSimIdColumn(final Cursor c) {
for (String s : new String[] { "sim_id", "simid", "sub_id" }) {
int id = c.getColumnIndex(s);
if (id >= 0) {
Log.d(" Simmmm", "sim_id column found: " + s);
return id;
}
}
Log.d(" Simmmm", "no sim_id column found");
return -1;
}
Try this method to read sim card contact ..
if you want to read first device store contact then implement to implements LoaderManager.LoaderCallbacks into class..
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new CursorLoader(getActivity(),
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, ProfileQuery.PROJECTION,
// Select only email addresses
null, null, null);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
List<String> numbers = new ArrayList<>();
cursor.moveToFirst();
while (!cursor.isAfterLast()) {
String phoneNumber = cursor.getString(ProfileQuery.NUMBER).replaceAll("\\D", "");
CustomLogHandler.printDebuglog(TAG, "onLoadFinished: " + phoneNumber);
if (!TextUtils.isEmpty(phoneNumber) && !phoneNumber.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).append(phoneNumber).toString());
} else {
mCountryCodeList.add(new StringBuilder().append(Constants.SP_COUNTRY_CODE).toString());
alPhoneNumbers.add(phoneNumber);
}
names.add(cursor.getString(ProfileQuery.NAME));
cursor.moveToNext();
}
allPhoneNumberName.addAll(names);
}
this below class read sim card data..
private class ReadContactFromSIMCard extends AsyncTask<Object, Object, Object> {
#Override
protected void onPostExecute(Object o) {
super.onPostExecute(o);
requestForContact();
}
#Override
protected Object doInBackground(Object[] params) {
Cursor cursorSim = null;
try {
String phoneNo;
String name;
Uri simUri = Uri.parse("content://icc/adn");
cursorSim = getActivity().getContentResolver().query(simUri, null, null, null, null);
if (cursorSim != null) {
while (cursorSim.moveToNext()) {
name = cursorSim.getString(cursorSim.getColumnIndex("name"));
phoneNo = cursorSim.getString(cursorSim.getColumnIndex("number"));
if (!TextUtils.isEmpty(name)) {
allPhoneNumberName.add(name);
}
if (!TextUtils.isEmpty(phoneNo)) {
phoneNo.replaceAll("\\D", "");
phoneNo.replaceAll("&", "");
if (!TextUtils.isEmpty(phoneNo) && !phoneNo.startsWith(Constants.SP_COUNTRY_CODE)) {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(Constants.SP_COUNTRY_CODE + phoneNo);
} else {
mCountryCodeList.add(Constants.SP_COUNTRY_CODE);
alPhoneNumbers.add(phoneNo);
}
}
}
}
} catch (Throwable e) {
CustomLogHandler.printErrorlog(e);
} finally {
if (cursorSim != null) {
cursorSim.close();
}
}
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
getLoaderManager().initLoader(0, null, FindFriendsFragment.this);
}
}
get call log details...
private void getCallDetails() {
StringBuffer sb = new StringBuffer();
Uri contacts = CallLog.Calls.CONTENT_URI;
Cursor managedCursor = this.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----------------------------------");
Uri allCalls = Uri.parse("content://call_log/calls");
Cursor c = managedQuery(allCalls, null, null, null, null);
String id = c.getString(c.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID));
Log.d("sim",id);
}
managedCursor.close();
System.out.println(sb);
}
and i hope you add below permission into android manifest file ..
<uses-permission android:name="android.permission.READ_CALL_LOG" />
Maybe you can get subscription_id by get "Calls.PHONE_ACCOUNT_ID" item, which called "The identifier for the account used to place or receive the call."
And after you get the subscription_id, which is match slot id, for example, slot 0 is subscription_id 0, and slot id 1 is subscription_id 1, then you can getSlotIndex using giveb subid, then you can using this slotid to query calls from this slot or to this slot.

Android Call Log data between two dates and Total duration of calls from same number.

want to get the call log history by today, yesterday, last seven days and last 30days along with that i want to show the total duration of incoming and outgoing calls of that particular number.
suppose abc has 3 outgoing and 1 incoming calls. i should get the total duration of those calls.
just let me know if we can get duration and calls log by cursor GroupBy or ORDER BY clause rather than looping and adding duration. Just give me rough structure for better solution and can work effectively .
String[] whereValue=null;
Calendar calendar = Calendar.getInstance();
String currentDate = String.valueOf(calendar.getTimeInMillis());
switch (period) {
case DAY:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case YESTERDAY:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case WEEK:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
case MONTH:
whereValue = new String[]{getTimeFrom(period),currentDate};
break;
default:
Log.d(Utils.LOG_TAG, "Error:");
}
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Uri callUri = Uri.parse("content://call_log/calls");
Cursor cur = context.getContentResolver().query(callUri, null, android.provider.CallLog.Calls.DATE+" BETWEEN ? AND ?", whereValue, strOrder);
String callNumber = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
String callName = cur
.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.CACHED_NAME));
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:
case CallLog.Calls.INCOMING_TYPE:
break;
}
String duration = cur.getString(cur
.getColumnIndex(android.provider.CallLog.Calls.DURATION));
the above code is even not working for getting call log between fromdate to till date. any help?
I have managed to get the call log between two dates. You can get call log of today, yesterday, last seven days, last 30days. as well duration of calls (calls from same number multiple times also)
you should pass selection as
android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?"
and
selectionArgs
whereValue = new String[]{String.valueOf(calendar1.getTimeInMillis()),String.valueOf(calendar.getTimeInMillis());};
Map<String, StatEntry> callLogMap1 = new HashMap<>();
callLogMap1.clear();
String strOrder1 = android.provider.CallLog.Calls.DATE + " DESC limit 500";
Uri callUri = Uri.parse("content://call_log/calls");
Cursor cur = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?", whereValue,
strOrder1);
if (cur != null) {
try {
while (cur.moveToNext()) {
String callNumber = cur.getString(cur.getColumnIndex(android.provider.CallLog.Calls.NUMBER));
// String callDate = cur.getString(cur.getColumnIndex(android.provider.CallLog.Calls.DATE));
int duration = cur.getInt(cur.getColumnIndex(android.provider.CallLog.Calls.DURATION));
String name = cur.getString(cur.getColumnIndex(CallLog.Calls.CACHED_NAME));
StatEntry StatEntry1 = null;
int id = cur.getInt(cur.getColumnIndex(CallLog.Calls._ID));
int type = cur.getInt(cur.getColumnIndex(CallLog.Calls.TYPE));
if (callNumber != null & duration > 0 && (type == 1 || type == 2)) {
int n = callNumber.length();
String lastDigits;
String number = callNumber.replaceAll(Pattern.quote("+"), ""); //replacing the plus
//am just checking last 5digitis and saving to map so that we can get same //number duration
if (n >= 5) {
try {
lastDigits = String.valueOf(Long.parseLong(number) % 100000);
} catch (NumberFormatException e) {
e.printStackTrace();
lastDigits = callNumber;
}
} else {
lastDigits = callNumber;
}
if (callLogMap1.containsKey(lastDigits)) {
StatEntry1 = callLogMap1.get(callNumber);
StatEntry1.setTitle(callNumber);
StatEntry1.Duration += duration;
} else {
StatEntry1 = new StatEntry();
StatEntry1.setTitle(callNumber);
StatEntry1.Duration += duration;
}
StatEntry1.setTime((StatEntry1.Duration) / 60);
callLogMap1.put(callNumber, StatEntry1);
}
}
} catch (Exception e) {
e.printStackTrace(
);
} finally {
cur.close();
}
}
atlast passing hashmap data to arraylist.
ArrayList<StatEntry> callLogList1 = new ArrayList<>(callLogMap1.size());
if (callLogMap1.size() > 0) {
for (Map.Entry<String, StatEntry> entry : callLogMap1.entrySet()) {
callLogList1.add(entry.getValue());
}
}
hope this will be helpful for viewers.
I managed to get the call log between two dates and also you can get the duration of the calls.Try this method..
public class CallLogActivity extends Activity {
TextView textView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_call_log);
textView = (TextView) findViewById(R.id.textCallBetween);
textView.setVisibility(View.GONE);
// listcallLog = (ListView) findViewById(R.id.calllogItems);
getCalldetails();
}
public void getCalldetails() {
StringBuffer stringBuffer = new StringBuffer();
String strOrder = android.provider.CallLog.Calls.DATE + " DESC";
Calendar calender = Calendar.getInstance();
calender.set(2016, calender.NOVEMBER, 18);
String fromDate = String.valueOf(calender.getTimeInMillis());
calender.set(2016, calender.NOVEMBER, 20);
String toDate = String.valueOf(calender.getTimeInMillis());
String[] whereValue = {fromDate,toDate};
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_CALL_LOG) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Cursor managedCursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE + " BETWEEN ? AND ?", whereValue, strOrder);
// Cursor managedCursor = managedQuery(CallLog.Calls.CONTENT_URI, null, android.provider.CallLog.Calls.DATE, new String[]{" BETWEEN ? AND ?"}, strOrder);
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 Log :");
while (managedCursor.moveToNext())
{
String phoneNumber = managedCursor.getString(number);
String callType = managedCursor.getString(type);
String callDate = managedCursor.getString(date);
SimpleDateFormat formatter = new SimpleDateFormat(
"dd-MMM-yyyy HH:mm");
String dateString = formatter.format(new Date(Long
.parseLong(callDate)));
// 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 = "INCOMMING";
break;
case CallLog.Calls.MISSED_TYPE:
dir = "MISSED CALL";
break;
}
stringBuffer.append("\nPhone Number:--- " + phoneNumber + "\nCall Type:--- "
+ dir + "\nCall Date:---"
+ dateString + "\nCall Duration:---" + callDuration);
stringBuffer.append("\n--------------------------");
}
textView.setText(stringBuffer);
textView.setVisibility(View.VISIBLE);
}
}

how to convert android contacts date-of birth-string to date format?

In my Android project i want to convert contacts date-of-birth as string to date from user locale.
String whereBday = ContactsContract.Data.MIMETYPE + "= ? AND " +
ContactsContract.CommonDataKinds.Event.TYPE + "=" +
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] paramsBday = new String[]{
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE };
Cursor bDayCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI,
null, whereBday, paramsBday, null);
while (bDayCursor.moveToNext()) {
//date of birth as String format
String bDay = bDayCursor.getString(bDayCursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE));
//converting string to date format
SimpleDateFormat formatter = new SimpleDateFormat(bDay);
Date myDate= formatter.parse(mytime);
DateFormat f = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
String formattedDate = f.format(new Date());
System.out.println("Date: " + formattedDate);
}
bDayCursor.close();
Unfortunately it seems that there is no fixed standard as to what the date format is stored in. The best solution is to loop through a list of date formats, and see if it matches any of the following. And once you get the date object you can modify it to be printed in any format using your own formatter. Also if its not found, then you can check the format which is not supported, and add it in your array.
You can use the following code:
public static final SimpleDateFormat[] birthdayFormats = {
new SimpleDateFormat("yyyy-MM-dd"),
new SimpleDateFormat("yyyy.MM.dd"),
new SimpleDateFormat("yy-MM-dd"),
new SimpleDateFormat("yy.MM.dd"),
new SimpleDateFormat("yy/MM/dd"),
new SimpleDateFormat("MMM dd, yyyy")
};
private void printBirthdays() {
Cursor cursor = getContactsBirthdays();
int bDayColumn = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE);
while (cursor.moveToNext()) {
String bDay = cursor.getString(bDayColumn);
Date birthday = null;
boolean found = false;
for (SimpleDateFormat f : birthdayFormats) {
try {
birthday = f.parse(bDay);
Log.e(TAG, bDay + " = " + birthday.toString());
found = true;
break;
} catch (ParseException e) {
}
}
if (!found) {
Log.e(TAG, bDay);
}
}
}
private Cursor getContactsBirthdays() {
Uri uri = ContactsContract.Data.CONTENT_URI;
String[] projection = new String[]{
ContactsContract.Contacts.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Event.CONTACT_ID,
ContactsContract.CommonDataKinds.Event.START_DATE
};
String where =
ContactsContract.Data.MIMETYPE + "= ? AND " +
ContactsContract.CommonDataKinds.Event.TYPE + "=" +
ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY;
String[] selectionArgs = new String[]{
ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE
};
String sortOrder = null;
return managedQuery(uri, projection, where, selectionArgs, sortOrder);
}

How to get the call log from specific date in android

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

How do I access call log for android?

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
}

Categories

Resources