understanding the use of ContentUris.appendId to query the calendar provider - android

The code i'm working on lists the events from the calendar, i need to limit the range of dates, and in the examples i see this code:
// Construct the query with the desired date range.
Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(builder, startMillis);
ContentUris.appendId(builder, endMillis);
I don't understand why appendId is used in this way. startMillis and endMillis are not ids, i would expect that the parameter name had to be provided eg "startdate" , It's not clear to me why this works, and what other parameters could be specified this way. Are there more parameters supported by appenedId? How can i know?

What appendId actually does is add a /# to your uri where # is a number. In your example (assuming startMillis = 1000 and endMillis = 3000 and the uri content://com.google.calendar/) this would mean your uri could end up like this:
content://com.google.calendar/1000/3000
This is something that a uri parser can pickup:
URIMatcher.addURI(AUTHORITY, calendar + "/#/#", DATE_RANGE);
Long story short: appendId is just a convenient and type-safe way to add an integer to your uri path.

I too have been trying to understand more about ContentUris as I had a section of code that wasn't working within the CalendarContract Instances table. This is strange because I didn't need to pass these in for the Calendars or Events table queries that I have developed.
So I added the appendId statements and passed in the current time in UTC for both values and the code now works. The actual query in my code is using the current time to looking for current events - please see the code below. If I take the appendID statements out an exception is raised - I think it was something like Content Provider URL not found.
String instanceQuery = "EVENT_ID = " + event_id +
" AND begin <= " + now +
" AND end >= " + now;
Uri.Builder eventsUriBuilder = CalendarContract.Instances.CONTENT_URI.buildUpon();
ContentUris.appendId(eventsUriBuilder, now);
ContentUris.appendId(eventsUriBuilder, now);
Uri eventsUri = eventsUriBuilder.build();
Cursor instanceCursor = null;
instanceCursor = ctx.getContentResolver().query(eventsUri,
new String[] { CalendarContract.Instances.EVENT_ID,
CalendarContract.Instances.BEGIN,
CalendarContract.Instances.END},
instanceQuery,
null,
null);
My code is working but I would like to know what impact the appendID statements actually have, e.g. do the values add any constraints. It looks like my actual query is overriding any implied range that is passed in and I really don't understand why they are required.
Hopefully a brief explanation from someone who understands this more would benefit the developer community....

Related

Search in Android calendar Instances

I want to search events in Android Calendar API Instances table by title or description. But I can't fetch all instances from the table because of API. CalendarContract.Instances has CONTENT_SEARCH_URI. Does anybody know how to use it?
Here is what is CONTENT_SEARCH_URI and how to use it.
CONTENT_SEARCH_URI = content://com.android.calendar/instances/search
If you want to use it, add 3 arguments: begin in millis, end in millis and search as String.
Uri.Builder builder = CalendarContract.Instances.CONTENT_SEARCH_URI.buildUpon();
builder.appendPath(Long.toString(startDate));
builder.appendPath(Long.toString(endDate));
builder.appendPath(searchString);
Uri uri = builder.build();
The path will be content://com.android.calendar/instances/search/[your begin]/[your end]/[your search]
If you make query with this Uri, Android makes this SQL:
SELECT Instances._id AS _id, Instances.event_id AS event_id,
title, description, eventLocation
FROM (Instances INNER JOIN view_events AS Events ON
(Instances.event_id=Events._id))
LEFT OUTER JOIN Attendees ON (Attendees.event_id=Events._id)
WHERE (begin<=? AND end>=?)
GROUP BY Instances._id
HAVING (title LIKE ? ESCAPE "#"
OR description LIKE ? ESCAPE "#"
OR eventLocation LIKE ? ESCAPE "#"
OR group_concat(attendeeEmail) LIKE ? ESCAPE "#"
OR group_concat(attendeeName) LIKE ? ESCAPE "#" )

Android calendar event duration (API)

why duration column in calendar Evens table does not get value set via provider?
ContentValues event = new ContentValues();
if(allDay==1) {
long days = (dtend - dtstart + DateUtils.DAY_IN_MILLIS - 1) / DateUtils.DAY_IN_MILLIS;
event.put("duration", "P" + days + "D");
} else {
event.put("duration", "P" + ((dtend-dtstart)/DateUtils.SECOND_IN_MILLIS) + "S");
}
Uri eventsUri =Uri.parse("content://com.android.calendar/events")
cr.insert(eventsUri, event);
Are you sure you are not dividing by zero?
The DateUtils.SECOND_IN_MILLIS might get zero as value and then it will not perform the calculation (it should crash I presume).
You might want to check it out. I'm no Android programmer, but that's the first thing I would check assuming the code has a valid syntax.

Adding Calendar and events in Android 2.2

What I want: I want to add calendar events in Android 2.2.
What I Have: I have added an event using the below code
Uri calendars = Uri.parse("content://com.android.calendar/events");
Cursor managedCursor = managedQuery(calendars, null, null, null, null);
startManagingCursor(managedCursor);
managedCursor.moveToFirst();
String ID = null;
do
{
ID = managedCursor.getString(managedCursor.getColumnIndexOrThrow("_id"));
}
while (managedCursor.moveToNext());
managedCursor.close();
int NewID = Integer.parseInt(ID) + 1;
ContentValues event = new ContentValues();
event.put("calendar_id", NewID); // --- Some confusion Here with the ID,
// --- not sure how to use it here
event.put("title", "New Event Title");
event.put("description", "Event Desc");
event.put("eventLocation", "Somewhere");
long startTime = System.currentTimeMillis() + 1000 * 60 * 60;
long endTime = System.currentTimeMillis() + 1000 * 60 * 60 * 2;
event.put("dtstart", startTime);
event.put("dtend", endTime);
event.put("allDay", 0); // 0 for false, 1 for true
event.put("eventStatus", 1);
event.put("visibility", 0);
event.put("transparency", 0);
event.put("hasAlarm", 0); // 0 for false, 1 for true
Uri eventsUri = Uri.parse("content://com.android.calendar/events");
Uri insertedUri = getContentResolver().insert(eventsUri, event);
What is the problem:
So far I have been successful in adding a single event on the specified date time, and apparently NewID's role is suspicious to me. When I try to add some other event, I get the returned Uri insertedUri and it shows me the newly added ID at the end of the URI. But I cant see any such event on the device. May be there is some problem in my understanding of the Calendar and events, or differences in both and their ID's. Kindly guide me what I am missing or doing wrong.
Regards,
Khawar
Most of the code is fine, you just need to know a little bit of concepts regarding calendar. Actually there is more than one calendar types in Android.
To Traverse all the calendars, Use following Uri for 2.2:
Uri calendars = Uri.parse("content://com.android.calendar"+ "/calendars");
And get the values of 'id' and 'name', you will get the idea.
NewID's role is suspicious to me
Your insertion code is fine, you just need to give the id of that calendar in which you want to insert any event.
I still believe that even myself needs to learn alot so if you have anything to tell or correct, you are most welcome. Following links helped me:
Working with Android Calendars
Accessing Calendars events without using gdata api

calendar , triggering , web service access in android

Hello m
I am new to android..
I have samsung galaxy 3 and android 2.1 installed in it..
I want to build an widget as follows..
1.I want to access calendar of phone.. (googled a lot found diffrent answers but none wokrin..) (jimblackler.net/blog/?p=151 not working)..
since no public api is available it will be ok even if am able to use google calendar(the one from web).. letme know whichever is easier to implement. I just want to read events..
2.How do I trigger events on a specific time.. say when it is 3:00hrs it should call a function..
Is it possible ? if so how
3.I want to send two strings to a server and recieve andother text back as result. which would be the easiest way to code ?? have an c# web service..? or just use a php script on server accepting few parameters?
thanks a lot. :)
First Question: Calendar access: This is based on the content://calendar/calendars URI.
First, make sure your application defines the permission android.permission.READ_CALENDAR.
Get the calendars IDs and display names:
ContentResolver myContentResolver = getContentResolver();
final Cursor cursor = myContentResolver.query(Uri.parse("content://calendar/calendars"),
(new String[] { "_id", "displayName", "selected" }), null, null, null);
while (cursor.moveToNext()) {
final String _id = cursor.getString(0);
final String displayName = cursor.getString(1);
final Boolean selected = !cursor.getString(2).equals("0");
}
Work on a specific calendar:
Uri.Builder myUriBuilder = Uri.parse("content://calendar/instances/when").buildUpon();
long currentTime = new Date().getTime();
ContentUris.appendId(myUriBuilder , currentTime - DateUtils.WEEK_IN_MILLIS);
ContentUris.appendId(myUriBuilder, currentTime + DateUtils.WEEK_IN_MILLIS);
Cursor eventCursor = myContentResolver.query(myUriBuilder.build(),
new String[] { "title", "begin", "end", "allDay"}, "Calendars._id=" + id,
null, "startDay ASC, startMinute ASC");
while (eventCursor.moveToNext()) {
// fields:
// Event title - String - 0
String eventTitle = eventCursor.getString(0);
// Event start time - long - 1
Date startTime = new Date(eventCursor.getLong(1));
// Event end time - login - 2
Date endTime = new Date(eventCursor.getLong(2));
// Is it an All Day Event - String - 3 (0 is false, 1 is true)
Boolean allDay = !eventCursor.getString(3).equals("0");
}
Second Question: Scheduling Events:
Basically, you should use the AlarmManager class, see the android SDK for details.
Example to set the event 3 hours from now:
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 3);
Intent intent = new Intent(this, MyAlarmHandler.class);
intent.putExtra("alarm_message", "Wake up!");
int requestCode = 3824723; // this is not currently used by Android.
PendingIntent pIntent = PendingIntent.getBroadcast(this, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), pIntent);
Third Question: Yes, I suggest the PHP approach

Cannot get Correct month for a call from call log history

I am trying to extract information from the call log of the
android. I am getting the call date that is one month back from the
actual time of call. I mean to say that the information extracted by
my code for the date of call is one mont back than the actual call
date.
I have the following in the Emulator:
I saved a contact. Then I made a call to the contact.
Code:
I have 3 ways of extracting call Date information but getting the same
wrong result. My code is as follows:
/* Make the query to call log content */
Cursor callLogResult = context.getContentResolver().query(
CallLog.Calls.CONTENT_URI, null, null, null, null);
int columnIndex = callLogResult.getColumnIndex(Calls.DATE);
Long timeInResult = callLogResult.getLong(columnIndex);
/* Method 1 to change the milliseconds obtained to the readable date formate */
Time time = new Time();
time.toMillis(true);
time.set(timeInResult);
String callDate= time.monthDay+"-"+time.month+"-"+time.year;
/* Method 2 for extracting the date from tha value read from the column */
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(time);
String Month = calendar.get(Calendar.MONTH) ;
/* Method 3 for extracting date from the result obtained */
Date date = new Date(timeInResult);
String mont = date.getMonth()
While using the Calendar method , I also tried to set the DayLight
SAving Offset but it didnot worked,
calendar.setTimeZone(TimeZone.getTimeZone("Europe/Paris"));
int DST_OFFSET = calendar.get( Calendar.DST_OFFSET ); // DST_OFFSET
Boolean isSet = calendar.getTimeZone().useDaylightTime();
if(isSet)
calendar.set(Calendar.DST_OFFSET , 0);
int reCheck = calendar.get(Calendar.DST_OFFSET );
But the value is not set to 0 in recheck. I am getting the wrong
month value by using this also.
Please some one help me where I am wrong? or is this the error in
emulator ??
Thanks,
Nishant Kumar
Engineering Student
Calandar's months are from 0 to 11
You need to add 1 to the month Caladar is giving you.
I know, this is strange.
Try new Date(timeInResult);

Categories

Resources