I have created a service that reads user messages after every 15 minutes , code is working fine for all messages but the problem is that i want to read messages sent for last 15 minutes not all messages , here is my code for service
public class MessageReadingService extends Service {
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
int happy,sad,lonely,joyful=0;
Cursor cur;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
scheduler.scheduleWithFixedDelay(new Runnable() {
#Override
public void run() {
Uri uriSMSURI = Uri.parse("content://sms/sent");
cur = getContentResolver().query(uriSMSURI, new String[]{"_id", "thread_id", "address", "person", "date", "body"}, null, null, "DATE desc");
if (cur.getCount() > 0) {
while (cur.moveToNext()) {
String smsBody = cur.getString(5);
String body=smsBody.toString().toLowerCase();
if (body.contains("happy") || body.contains("yay") || body.contains("I am well") || body.contains("excited")) {
happy++;
//Toast.makeText(getApplicationContext(), "found"+s, Toast.LENGTH_SHORT).show();
}
if (body.contains("sad") || body.contains("not well") || body.contains("crying")|| body.contains("ill") || body.contains("leave me alone") || body.contains("i hate people")){
sad++;
}
if (body.contains("alone") ||body.contains("lonely") || body.contains("heart broken") || body.contains("Extremely sad")){
lonely++;
}
if (body.contains("joyful") || body.contains("exited") || body.contains("")){
joyful++;
}
}
}
}
}, 60*15, 60*15, SECONDS);
return super.onStartCommand(intent, flags, startId);
}
Create a calendar object and set the condition for where clause
private static final int FIFTEEN_MINUTES= 15 * 60 * 1000;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + FIFTEEN_MINUTES);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
and then use the query like this
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC");
This gets the latest messages of the last 15 minutes.
mCursor = getContentResolver().query(
UserDictionary.Words.CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder);
You set select criteria to NULL;
Replace mSelectionClause with a WHERE clause: WHERE col = value
"date>=" + dateStart.getTime();
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 am wondering how to read last five SMS received from a particular mobile number on a particular date.
I know how to read all SMS from a particular sender, and how to read the last SMS, but I am unable to fetch and read the last few SMS. I tried to read them by using
"date DESC LIMIT 5"
My code is like below
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
String[] projection = {"address", "body"};
Cursor cursor1 = MainActivity.this.getContentResolver().query(mSmsinboxQueryUri,
null,
"address = ?",
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor1 != null && cursor1.moveToFirst()) {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
}
But every time it's showing only the last message.
You're only seeing one message because your code is only handling the first record in the returned Cursor. You need to loop over the Cursor to handle the rest. For example:
if (cursor != null && cursor.moveToFirst()) {
do {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
} while (cursor.moveToNext());
}
Also, if you want to restrict the query to one day, you can use a Calendar to figure the starting and ending times for that day in milliseconds - as that is how dates are stored in the SMS table - and add the appropriate comparison to the where clause. For example:
private static final int DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
private static final Uri inboxUri = Uri.parse("content://sms/inbox");
// Months are zero-based; i.e., JANUARY == 0
// Phone number must be exact in this example
private void listMessages(String phoneNumber, int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + DAY_MILLISECONDS);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
Cursor cursor = null;
try {
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor != null && cursor.moveToFirst()) {
do {
Log.d("Message", cursor.getString(cursor.getColumnIndex("body")));
} while (cursor.moveToNext());
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
I am wondering how to read last five SMS received from a particular mobile number on a particular date.
I know how to read all SMS from a particular sender, and how to read the last SMS, but I am unable to fetch and read the last few SMS. I tried to read them by using
"date DESC LIMIT 5"
My code is like below
Uri mSmsinboxQueryUri = Uri.parse("content://sms/inbox");
String[] projection = {"address", "body"};
Cursor cursor1 = MainActivity.this.getContentResolver().query(mSmsinboxQueryUri,
null,
"address = ?",
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor1 != null && cursor1.moveToFirst()) {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
}
But every time it's showing only the last message.
You're only seeing one message because your code is only handling the first record in the returned Cursor. You need to loop over the Cursor to handle the rest. For example:
if (cursor != null && cursor.moveToFirst()) {
do {
body = cursor1.getString(cursor1.getColumnIndex("body"));
totalBody = totalBody + body;
Log.d("Registration", totalBody);
} while (cursor.moveToNext());
}
Also, if you want to restrict the query to one day, you can use a Calendar to figure the starting and ending times for that day in milliseconds - as that is how dates are stored in the SMS table - and add the appropriate comparison to the where clause. For example:
private static final int DAY_MILLISECONDS = 24 * 60 * 60 * 1000;
private static final Uri inboxUri = Uri.parse("content://sms/inbox");
// Months are zero-based; i.e., JANUARY == 0
// Phone number must be exact in this example
private void listMessages(String phoneNumber, int year, int month, int day) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.YEAR, year);
cal.set(Calendar.MONTH, month);
cal.set(Calendar.DATE, day);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
String[] projection = {"address", "body"};
String whereAddress = "address = ?";
String whereDate = "date BETWEEN " + cal.getTimeInMillis() +
" AND " + (cal.getTimeInMillis() + DAY_MILLISECONDS);
String where = DatabaseUtils.concatenateWhere(whereAddress, whereDate);
Cursor cursor = null;
try {
cursor = getContentResolver().query(inboxUri,
projection,
where,
new String[]{phoneNumber},
"date DESC LIMIT 5");
if (cursor != null && cursor.moveToFirst()) {
do {
Log.d("Message", cursor.getString(cursor.getColumnIndex("body")));
} while (cursor.moveToNext());
}
}
catch (Exception e) {
e.printStackTrace();
}
finally {
if (cursor != null) {
cursor.close();
}
}
}
Hi i need to implement a code for insert, update events on android calendar, When i was trying add Events on Android Calendar it throws exception - invalid column displayname.
i try to replace deprecated , because apps crash:
Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
with this , but i received error by logcat "invalid column displayname"
Cursor l_managedCursor = getContentResolver().query (l_calendars, l_projection,null,null,null);
this is code
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/*get calendar list and populate the view*/
getCalendars();
populateCalendarSpinner();
populateAddBtn();
populateAddBtn2();
populateTextEvent();
populateGetEventsBtn();
}
private void populateCalendarSpinner() {
m_spinner_calender = (Spinner)this.findViewById(R.id.spinner_calendar);
ArrayAdapter l_arrayAdapter = new ArrayAdapter(this.getApplicationContext(), android.R.layout.simple_spinner_item, m_calendars);
l_arrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
m_spinner_calender.setAdapter(l_arrayAdapter);
m_spinner_calender.setSelection(0);
m_spinner_calender.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> p_parent, View p_view,
int p_pos, long p_id) {
m_selectedCalendarId = m_calendars[(int)p_id].id;
}
#Override
public void onNothingSelected(AdapterView<?> arg0) {}
});
}
private void populateAddBtn() {
m_button_add = (Button) this.findViewById(R.id.button_add);
m_button_add.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addEvent();
}
});
}
private void populateAddBtn2() {
m_button_add2 = (Button) this.findViewById(R.id.button_add2);
m_button_add2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addEvent2();
}
});
}
private void populateGetEventsBtn() {
m_button_getEvents = (Button) findViewById(R.id.button_get_events);
m_button_getEvents.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getLastThreeEvents();
}
});
}
private void populateTextEvent() {
m_text_event = (TextView) findViewById(R.id.text_event);
String l_str = "title: roman10 calendar tutorial test\n" +
"description: This is a simple test for calendar api\n" +
"eventLocation: #home\n" +
"start time:" + getDateTimeStr(0) + "\n" +
"end time: " + getDateTimeStr(30) + "\n" +
"event status: confirmed\n" +
"all day: no\n" +
"has alarm: yes\n";
m_text_event.setText(l_str);
}
/****************************************************************
* Data part
*/
/*retrieve a list of available calendars*/
private MyCalendar m_calendars[];
private String m_selectedCalendarId = "0";
private void getCalendars() {
String[] l_projection = new String[]{"_id", "displayName"};
Uri l_calendars;
if (Build.VERSION.SDK_INT >= 8) {
l_calendars = Uri.parse("content://com.android.calendar/calendars");
} else {
l_calendars = Uri.parse("content://calendar/calendars");
}
// Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, null, null, null); //all calendars
//Cursor l_managedCursor = this.managedQuery(l_calendars, l_projection, "selected=1", null, null); //active calendars
Cursor l_managedCursor = getContentResolver().query (l_calendars, l_projection, "selected=1", null, null); //all calendars
if (l_managedCursor.moveToFirst()) {
m_calendars = new MyCalendar[l_managedCursor.getCount()];
String l_calName;
String l_calId;
int l_cnt = 0;
int l_nameCol = l_managedCursor.getColumnIndex(l_projection[1]);
int l_idCol = l_managedCursor.getColumnIndex(l_projection[0]);
do {
l_calName = l_managedCursor.getString(l_nameCol);
l_calId = l_managedCursor.getString(l_idCol);
m_calendars[l_cnt] = new MyCalendar(l_calName, l_calId);
++l_cnt;
} while (l_managedCursor.moveToNext());
}
}
/*add an event to calendar*/
private void addEvent() {
ContentValues l_event = new ContentValues();
l_event.put("calendar_id", m_selectedCalendarId);
l_event.put("title", "roman10 calendar tutorial test");
l_event.put("description", "This is a simple test for calendar api");
l_event.put("eventLocation", "#home");
l_event.put("dtstart", System.currentTimeMillis());
l_event.put("dtend", System.currentTimeMillis() + 1800*1000);
l_event.put("allDay", 0);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
l_event.put("eventStatus", 1);
//0~ default; 1~ confidential; 2~ private; 3~ public
l_event.put("visibility", 0);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
l_event.put("transparency", 0);
//0~ false; 1~ true
l_event.put("hasAlarm", 1);
Uri l_eventUri;
if (Build.VERSION.SDK_INT >= 8) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
Uri l_uri = this.getContentResolver().insert(l_eventUri, l_event);
Log.v("++++++test", l_uri.toString());
}
private void addEvent2() {
Intent l_intent = new Intent(Intent.ACTION_EDIT);
l_intent.setType("vnd.android.cursor.item/event");
//l_intent.putExtra("calendar_id", m_selectedCalendarId); //this doesn't work
l_intent.putExtra("title", "roman10 calendar tutorial test");
l_intent.putExtra("description", "This is a simple test for calendar api");
l_intent.putExtra("eventLocation", "#home");
l_intent.putExtra("beginTime", System.currentTimeMillis());
l_intent.putExtra("endTime", System.currentTimeMillis() + 1800*1000);
l_intent.putExtra("allDay", 0);
//status: 0~ tentative; 1~ confirmed; 2~ canceled
l_intent.putExtra("eventStatus", 1);
//0~ default; 1~ confidential; 2~ private; 3~ public
l_intent.putExtra("visibility", 0);
//0~ opaque, no timing conflict is allowed; 1~ transparency, allow overlap of scheduling
l_intent.putExtra("transparency", 0);
//0~ false; 1~ true
l_intent.putExtra("hasAlarm", 1);
try {
startActivity(l_intent);
} catch (Exception e) {
Toast.makeText(this.getApplicationContext(), "Sorry, no compatible calendar is found!", Toast.LENGTH_LONG).show();
}
}
private void getLastThreeEvents() {
Uri l_eventUri;
if (Build.VERSION.SDK_INT >= 8) {
l_eventUri = Uri.parse("content://com.android.calendar/events");
} else {
l_eventUri = Uri.parse("content://calendar/events");
}
String[] l_projection = new String[]{"title", "dtstart", "dtend"};
//Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
//Cursor l_managedCursor = this.managedQuery(l_eventUri, l_projection, null, null, null);
Cursor l_managedCursor = this.getContentResolver().query(l_eventUri, l_projection, "calendar_id=" + m_selectedCalendarId, null, "dtstart DESC, dtend DESC");
if (l_managedCursor.moveToFirst()) {
int l_cnt = 0;
String l_title;
String l_begin;
String l_end;
StringBuilder l_displayText = new StringBuilder();
int l_colTitle = l_managedCursor.getColumnIndex(l_projection[0]);
int l_colBegin = l_managedCursor.getColumnIndex(l_projection[1]);
int l_colEnd = l_managedCursor.getColumnIndex(l_projection[1]);
do {
l_title = l_managedCursor.getString(l_colTitle);
l_begin = getDateTimeStr(l_managedCursor.getString(l_colBegin));
l_end = getDateTimeStr(l_managedCursor.getString(l_colEnd));
l_displayText.append(l_title + "\n" + l_begin + "\n" + l_end + "\n----------------\n");
++l_cnt;
} while (l_managedCursor.moveToNext() && l_cnt < 3);
m_text_event.setText(l_displayText.toString());
}
}
/************************************************
* utility part
*/
private static final String DATE_TIME_FORMAT = "yyyy MMM dd, HH:mm:ss";
public static String getDateTimeStr(int p_delay_min) {
Calendar cal = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
if (p_delay_min == 0) {
return sdf.format(cal.getTime());
} else {
Date l_time = cal.getTime();
//l_time.getMinutes (l_time.getMinutes() + p_delay_min);
return sdf.format(l_time);
}
}
public static String getDateTimeStr(String p_time_in_millis) {
SimpleDateFormat sdf = new SimpleDateFormat(DATE_TIME_FORMAT);
Date l_time = new Date(Long.parseLong(p_time_in_millis));
return sdf.format(l_time);
}
}
LOGCAT
01-05 17:09:26.690 2354-2354/app.android.ny E/AndroidRuntime﹕ FATAL EXCEPTION: main
Process: app.android.ny, PID: 2354
java.lang.RuntimeException: Unable to start activity ComponentInfo{app.android.ny/app.android.ny.Main}: java.lang.IllegalArgumentException: Invalid column displayName
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2298)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2360)
at android.app.ActivityThread.access$800(ActivityThread.java:144)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1278)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.IllegalArgumentException: Invalid column displayName
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:167)
at android.database.DatabaseUtils.readExceptionFromParcel(DatabaseUtils.java:137)
at android.content.ContentProviderProxy.query(ContentProviderNative.java:420)
at android.content.ContentResolver.query(ContentResolver.java:478)
at android.content.ContentResolver.query(ContentResolver.java:422)
at app.android.ny.Main.getCalendars(Main.java:136)
at app.android.ny.Main.onCreate(Main.java:58)
at android.app.Activity.performCreate(Activity.java:5933)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1105)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2251)
I Think there is a change in the way you query the calendars for newer API. They didn't seem to inform about it.
For API 10 I know displayName works.
For API >= 14 this code will work:
https://developer.android.com/guide/topics/providers/calendar-provider.html
// Projection array. Creating indices for this array instead of doing
// dynamic lookups improves performance.
public static final String[] EVENT_PROJECTION = new String[] {
Calendars._ID, // 0
Calendars.ACCOUNT_NAME, // 1
Calendars.CALENDAR_DISPLAY_NAME, // 2
Calendars.OWNER_ACCOUNT // 3
};
// Run query
Cursor cur = null;
ContentResolver cr = getContentResolver();
Uri uri = Calendars.CONTENT_URI;
String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
+ Calendars.ACCOUNT_TYPE + " = ?) AND ("
+ Calendars.OWNER_ACCOUNT + " = ?))";
String[] selectionArgs = new String[] {"sampleuser#gmail.com", "com.google",
"sampleuser#gmail.com"};
// Submit the query and get a Cursor object back.
cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);
Your app is crashing because the column name you are passing to get calender info is wrong. Change this line
String[] l_projection = new String[]{"_id", "displayName"};
in method getCalendars() to
String[] l_projection = new String[]{"_id", "calendar_displayName"};
You must have entered a different Column name. Kindly check the Upper case and lower case !!
Even I was facing this error, finaly got it done by this piece of code, hope this will help many
new String[] { "_id", Calendars.CALENDAR_DISPLAY_NAME }
I want to list of events from my calendar based on specific date. I am using following
Cursor cursor = getContentResolver().query(Uri.parse("content://com.android.calendar/events"), new String[]{ "_id", "title", "description", "dtstart", "dtend", "eventLocation" }, null, null, null);
This code works fine but it brings the total events from the calendar. But i need a events on specfic date like 2011-08-15. I tried following code
Cursor cursor = getContentResolver().query(Uri.parse("content://com.android.calendar/events"), new String[]{ "_id", "title", "description", "dtstart", "dtend", "eventLocation" }, "dtstart", new String[]{sdf.format(calender.getTime())}, null);
cursor.moveToFirst();
But I am getting exception
Caused by: android.database.sqlite.SQLiteException: no such column:
Calendars.dtstart: , while compiling: SELECT _id, title, description,
dtstart, dtend, eventLocation FROM view_events WHERE (1) AND
(Calendars.dtstart)
Please give some advise to solve my problem
I have done this way:
String[] projection = new String[] { CalendarContract.Events.CALENDAR_ID, CalendarContract.Events.TITLE, CalendarContract.Events.DESCRIPTION, CalendarContract.Events.DTSTART, CalendarContract.Events.DTEND, CalendarContract.Events.ALL_DAY, CalendarContract.Events.EVENT_LOCATION };
Calendar startTime = Calendar.getInstance();
startTime.set(Calendar.HOUR_OF_DAY,0);
startTime.set(Calendar.MINUTE,0);
startTime.set(Calendar.SECOND, 0);
Calendar endTime= Calendar.getInstance();
endTime.add(Calendar.DATE, 1);
String selection = "(( " + CalendarContract.Events.DTSTART + " >= " + startTime.getTimeInMillis() + " ) AND ( " + CalendarContract.Events.DTSTART + " <= " + endTime.getTimeInMillis() + " ) AND ( deleted != 1 ))";
Cursor cursor = context.getContentResolver().query(CalendarContract.Events.CONTENT_URI, projection, selection, null, null);
List<String> events = new ArrayList<>();
if (cursor!=null&&cursor.getCount()>0&&cursor.moveToFirst()) {
do {
events.add(cursor.getString(1));
} while ( cursor.moveToNext());
}
It will give today's event from Calendar content provider.
Note: Managed the deleted events from content provider.
Done
Refer to Calendar Provider Documentation this link
I am using this code and it is working..
ContentResolver contentResolver = context.getContentResolver();
Cursor cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"), (new String[] { Calendars._ID, Calendars.ACCOUNT_NAME, Calendars.CALENDAR_DISPLAY_NAME, }), null, null, null);
This methods is 100% worked for me however i tried several method . It will get all the event and store in a set . Then you can check the set whether a event is in the set or not . In this way you can check duplicate event
public Set<String> readCalendarEvent(Context context) {
Cursor cursor = context.getContentResolver()
.query(
Uri.parse("content://com.android.calendar/events"),
new String[] { "calendar_id", "title", "description",
"dtstart", "dtend", "eventLocation" }, null,
null, null);
cursor.moveToFirst();
// fetching calendars name
String CNames[] = new String[cursor.getCount()];
// fetching calendars id
calendars.clear();
Log.d("cnameslength",""+CNames.length);
if (CNames.length==0)
{
Toast.makeText(context,"No event exists in calendar",Toast.LENGTH_LONG).show();
}
for (int i = 0; i < CNames.length; i++) {
calendars.add(cursor.getString(1));
CNames[i] = cursor.getString(1);
cursor.moveToNext();
}
return calendars;
}
try this code i am in my application i am used this event for display event date wise;
ContentResolver contentResolver = mContext.getContentResolver();
final Cursor cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
(new String[] { "_id", "displayName", "selected" }), null, null, null);
HashSet<String> calendarIds = new HashSet<String>();
while (cursor.moveToNext()) {
final String _id = cursor.getString(0);
final String displayName = cursor.getString(1);
final Boolean selected = !cursor.getString(2).equals("0");
//System.out.println("Id: " + _id + " Display Name: " + displayName + " Selected: " + selected);
calendarIds.add(_id);
}
in this snipped you should get all calendar event in calendarIds...now check
for (String id : calendarIds) {
Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon();
long now = new Date().getTime();
ContentUris.appendId(builder, now - DateUtils.DAY_IN_MILLIS * 10000);
ContentUris.appendId(builder, now + DateUtils.DAY_IN_MILLIS * 10000);
Cursor eventCursor = contentResolver.query(builder.build(),
new String[] { "title", "begin", "end", "allDay"}, "Calendars._id=" + id,
null, "startDay ASC, startMinute ASC");
// For a full list of available columns see http://tinyurl.com/yfbg76w
while (eventCursor.moveToNext()) {
eventTitle = eventCursor.getString(0);
begin = new Date(eventCursor.getLong(1));
end = new Date(eventCursor.getLong(2));
allDay = !eventCursor.getString(3).equals("0");
eventDate = begin.getDate();
eventTime = begin.getHours();
eventMonth = begin.getMonth();
eventYear = begin.getYear();
event.add(eventTitle);
SimpleDateFormat sdfcur = new SimpleDateFormat("yyyy-MM-dd");
String beginString = sdfcur.format(begin);
Date begindt = null;
try {
begindt = sdfcur.parse(beginString);
stringEventDate = begindt.getDate();
stringEventMonth = begindt.getMonth();
stringEventYear = begindt.getYear();
} catch (ParseException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
Date dt = null;
dt = sdfcur.parse(onClickDate);
int passedday=dt.getDate();
int passedmonth = dt.getMonth();
int passedyear = dt.getYear();