Getting events from calendar - android

My issue is, I have to make one demo application in which I wants to read the events of the Google calendar, for that I have manually inserted the events like the title of event, the time of events and the details of the whole events. now I need to just read those events form that calendar.
For that I have tried to use the gcode(google code) API which provides the calendar API class. But still I cant read those events.

That code above is pretty awful (and it does not seem to work in ICS - definitely the column names are different)
The page here:
http://developer.android.com/guide/topics/providers/calendar-provider.html
provides a much better overview.
A (much) simpler code to retrieve calendars:
public class CalendarContentResolver {
public static final String[] FIELDS = {
CalendarContract.Calendars.NAME,
CalendarContract.Calendars.CALENDAR_DISPLAY_NAME,
CalendarContract.Calendars.CALENDAR_COLOR,
CalendarContract.Calendars.VISIBLE
};
public static final Uri CALENDAR_URI = Uri.parse("content://com.android.calendar/calendars");
ContentResolver contentResolver;
Set<String> calendars = new HashSet<String>();
public CalendarContentResolver(Context ctx) {
contentResolver = ctx.getContentResolver();
}
public Set<String> getCalendars() {
// Fetch a list of all calendars sync'd with the device and their display names
Cursor cursor = contentResolver.query(CALENDAR_URI, FIELDS, null, null, null);
try {
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
String name = cursor.getString(0);
String displayName = cursor.getString(1);
// This is actually a better pattern:
String color = cursor.getString(cursor.getColumnIndex(CalendarContract.Calendars.CALENDAR_COLOR));
Boolean selected = !cursor.getString(3).equals("0");
calendars.add(displayName);
}
}
} catch (AssertionError ex) { /*TODO: log exception and bail*/ }
return calendars;
}
}
Hope this helps!

Ok i found the answer of this whole of the concept that how to use the google calendar application integration with the android phone.
code:--
first you set this line which will goes to read the calendar events form the other class form your class which is current is the ApplicationSettings.java .
ReadCalendar.readCalendar(ApplicationSettings.this);
package com.mycalendarevents.android;
import java.util.Date;
import java.util.HashSet;
import java.util.regex.Pattern;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.text.format.DateUtils;
public class ReadCalendar
{
static Cursor cursor;
public static void readCalendar(Context context) {
ContentResolver contentResolver = context.getContentResolver();
// Fetch a list of all calendars synced with the device, their display names and whether the
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/calendars"),
(new String[] { "_id", "displayName", "selected"}), null, null, null);
HashSet<String> calendarIds = new HashSet<String>();
try
{
System.out.println("Count="+cursor.getCount());
if(cursor.getCount() > 0)
{
System.out.println("the control is just inside of the cursor.count loop");
while (cursor.moveToNext()) {
String _id = cursor.getString(0);
String displayName = cursor.getString(1);
Boolean selected = !cursor.getString(2).equals("0");
System.out.println("Id: " + _id + " Display Name: " + displayName + " Selected: " + selected);
calendarIds.add(_id);
}
}
}
catch(AssertionError ex)
{
ex.printStackTrace();
}
catch(Exception e)
{
e.printStackTrace();
}
// For each calendar, display all the events from the previous week to the end of next week.
for (String id : calendarIds) {
Uri.Builder builder = Uri.parse("content://com.android.calendar/instances/when").buildUpon();
//Uri.Builder builder = Uri.parse("content://com.android.calendar/calendars").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=" + 1,
null, "startDay ASC, startMinute ASC");
System.out.println("eventCursor count="+eventCursor.getCount());
if(eventCursor.getCount()>0)
{
if(eventCursor.moveToFirst())
{
do
{
Object mbeg_date,beg_date,beg_time,end_date,end_time;
final String title = eventCursor.getString(0);
final Date begin = new Date(eventCursor.getLong(1));
final Date end = new Date(eventCursor.getLong(2));
final Boolean allDay = !eventCursor.getString(3).equals("0");
/* System.out.println("Title: " + title + " Begin: " + begin + " End: " + end +
" All Day: " + allDay);
*/
System.out.println("Title:"+title);
System.out.println("Begin:"+begin);
System.out.println("End:"+end);
System.out.println("All Day:"+allDay);
/* the calendar control metting-begin events Respose sub-string (starts....hare) */
Pattern p = Pattern.compile(" ");
String[] items = p.split(begin.toString());
String scalendar_metting_beginday,scalendar_metting_beginmonth,scalendar_metting_beginyear,scalendar_metting_begindate,scalendar_metting_begintime,scalendar_metting_begingmt;
scalendar_metting_beginday = items[0];
scalendar_metting_beginmonth = items[1];
scalendar_metting_begindate = items[2];
scalendar_metting_begintime = items[3];
scalendar_metting_begingmt = items[4];
scalendar_metting_beginyear = items[5];
String calendar_metting_beginday = scalendar_metting_beginday;
String calendar_metting_beginmonth = scalendar_metting_beginmonth.toString().trim();
int calendar_metting_begindate = Integer.parseInt(scalendar_metting_begindate.trim());
String calendar_metting_begintime = scalendar_metting_begintime.toString().trim();
String calendar_metting_begingmt = scalendar_metting_begingmt;
int calendar_metting_beginyear = Integer.parseInt(scalendar_metting_beginyear.trim());
System.out.println("calendar_metting_beginday="+calendar_metting_beginday);
System.out.println("calendar_metting_beginmonth ="+calendar_metting_beginmonth);
System.out.println("calendar_metting_begindate ="+calendar_metting_begindate);
System.out.println("calendar_metting_begintime="+calendar_metting_begintime);
System.out.println("calendar_metting_begingmt ="+calendar_metting_begingmt);
System.out.println("calendar_metting_beginyear ="+calendar_metting_beginyear);
/* the calendar control metting-begin events Respose sub-string (starts....ends) */
/* the calendar control metting-end events Respose sub-string (starts....hare) */
Pattern p1 = Pattern.compile(" ");
String[] enditems = p.split(end.toString());
String scalendar_metting_endday,scalendar_metting_endmonth,scalendar_metting_endyear,scalendar_metting_enddate,scalendar_metting_endtime,scalendar_metting_endgmt;
scalendar_metting_endday = enditems[0];
scalendar_metting_endmonth = enditems[1];
scalendar_metting_enddate = enditems[2];
scalendar_metting_endtime = enditems[3];
scalendar_metting_endgmt = enditems[4];
scalendar_metting_endyear = enditems[5];
String calendar_metting_endday = scalendar_metting_endday;
String calendar_metting_endmonth = scalendar_metting_endmonth.toString().trim();
int calendar_metting_enddate = Integer.parseInt(scalendar_metting_enddate.trim());
String calendar_metting_endtime = scalendar_metting_endtime.toString().trim();
String calendar_metting_endgmt = scalendar_metting_endgmt;
int calendar_metting_endyear = Integer.parseInt(scalendar_metting_endyear.trim());
System.out.println("calendar_metting_beginday="+calendar_metting_endday);
System.out.println("calendar_metting_beginmonth ="+calendar_metting_endmonth);
System.out.println("calendar_metting_begindate ="+calendar_metting_enddate);
System.out.println("calendar_metting_begintime="+calendar_metting_endtime);
System.out.println("calendar_metting_begingmt ="+calendar_metting_endgmt);
System.out.println("calendar_metting_beginyear ="+calendar_metting_endyear);
/* the calendar control metting-end events Respose sub-string (starts....ends) */
System.out.println("only date begin of events="+begin.getDate());
System.out.println("only begin time of events="+begin.getHours() + ":" +begin.getMinutes() + ":" +begin.getSeconds());
System.out.println("only date begin of events="+end.getDate());
System.out.println("only begin time of events="+end.getHours() + ":" +end.getMinutes() + ":" +end.getSeconds());
beg_date = begin.getDate();
mbeg_date = begin.getDate()+"/"+calendar_metting_beginmonth+"/"+calendar_metting_beginyear;
beg_time = begin.getHours();
System.out.println("the vaule of mbeg_date="+mbeg_date.toString().trim());
end_date = end.getDate();
end_time = end.getHours();
CallHandlerUI.metting_begin_date.add(beg_date.toString());
CallHandlerUI.metting_begin_mdate.add(mbeg_date.toString());
CallHandlerUI.metting_begin_mtime.add(calendar_metting_begintime.toString());
CallHandlerUI.metting_end_date.add(end_date.toString());
CallHandlerUI.metting_end_time.add(end_time.toString());
CallHandlerUI.metting_end_mtime.add(calendar_metting_endtime.toString());
}
while(eventCursor.moveToNext());
}
}
break;
}
}
}
here is the whole of the code is to be posted which will simply reads each and every events form your calendar with the help of that postback url which is for 2.2 and above version:
Uri.parse("content://com.android.calendar/instances/when").buildUpon();
pl find the under those version lower then 2.2 in android and use those events as you required place...

I am aware that this is an old post, but I found inspiration for optimizing the solution found in the answer given by Akash Takkar if anyone is in need of a solution in the near future.
The issues
Specically, I found a few issues in the original code:
The loop for retrieving calendar events broke immaturely
Hereby, only events from the first calendar was retrieved
The first event in each calendar was skipped by using eventCursor.moveToFirst(); which thereafter moves directly to the next event in the while loop
The id of the calendars were not set correctly in the eventCursor
"Calendars._id=" + 1, should be "Calendars._id=" + id,
It would be difficult for others to specify their own time range
The current solution is not object oriented which would hold many advantages
The readability and documentation is not the best
The solution
I have hereby created a Github Library which returns a list of event objects in a specified time range which can be found at:
https://github.com/david-laundav/CalendarService
The source files can be found under "CalendarService/src/dk/CalendarService".
Use cases
The solution itself contains two different methods for different purposes.
First use case:
CalendarService.readCalendar(class.this)
// where class.this is either your class or the context
This method will return a list of events for +/- 1 day
Second use case:
You can also specify your own time range:
CalendarService.readCalendar(class.this, int days, int hours)
An example might be:
CalendarService.readCalendar(class.this, 2, 5)
In doing so will return a list of events from +/-2 days and +/- 5 hours.
The service has been tested, but please tell me if you experience any issues.

This post is a little bit old, but here is another easy solution for getting data related to Calendar content provider in Android:
Use this lib: https://github.com/EverythingMe/easy-content-providers
And now, get all calendars:
CalendarProvider calendarProvider = new CalendarProvider(context);
List<Calendar> calendars = calendarProvider.getCalendars().getList();
Each Calendar has all fields, so you can get any info you need:
id, name, calendarColor, ownerAccount, accountName, calendarAccessLevel, ...
Or, get all Events of specific calendar:
List<Event> calendars = calendarProvider.getEvents(calendar.id).getList();
And there is also option to get Reminders, Attendees, Instances.
It works with lists or cursor and there a sample app to see how it looks and works.
In fact, there is support for all Android content providers like: Contacts, SMS, Calls, ...
Full doc with all options: https://github.com/EverythingMe/easy-content-providers/wiki/Android-providers
Hope it helped :)

Use this code get the calendar events for one day.
public static void readCalendarEvent(Context context) throws ParseException {
ContentResolver contentResolver = context.getContentResolver();
Calendar calendar = Calendar.getInstance();
String dtstart = "dtstart";
String dtend = "dtend";
SimpleDateFormat displayFormatter = new SimpleDateFormat("MMMM dd, yyyy (EEEE)");
stime=displayFormatter.format(calendar.getTime());
SimpleDateFormat startFormatter = new SimpleDateFormat("MM/dd/yy");
String dateString = startFormatter.format(calendar.getTime());
long after = calendar.getTimeInMillis();
SimpleDateFormat formatterr = new SimpleDateFormat("hh:mm:ss MM/dd/yy");
Calendar endOfDay = Calendar.getInstance();
Date dateCCC = formatterr.parse("23:59:59 " + dateString);
endOfDay.setTime(dateCCC);
cursor = contentResolver.query(Uri.parse("content://com.android.calendar/events"), (new String[] { "calendar_id", "title", "description", "dtstart", "dtend","eventTimezone", "eventLocation" }), "(" + dtstart + ">" + after + " and " + dtend + "<" + endOfDay.getTimeInMillis() + ")", null, "dtstart ASC");
/*String[] COLS={"calendar_id", "title", "description", "dtstart", "dtend","eventTimezone", "eventLocation"};
cursor = contentResolver.query(
CalendarContract.Events.CONTENT_URI, COLS,null, null, null);*/
gCalendar = new ArrayList<GoogleCalendar>();
try {
if (cursor.getCount() > 0) {
while (cursor.moveToNext()) {
GoogleCalendar googleCalendar = new GoogleCalendar();
gCalendar.add(googleCalendar);
int calendar_id = cursor.getInt(0);
googleCalendar.setCalendar_id(calendar_id);
String title = cursor.getString(1);
googleCalendar.setTitle(title);
String description = cursor.getString(2);
googleCalendar.setDescription(description);
String dtstart1 = cursor.getString(3);
dt=convertDate(dtstart1,"hh:mm:ss");
googleCalendar.setDtstart(dt);
String dtend1 = cursor.getString(4);
googleCalendar.setDtend(dtend1);
String eventTimeZone=cursor.getString(5);
googleCalendar.setEventTimeZone(eventTimeZone);
String eventlocation = cursor.getString(6);
googleCalendar.setEventlocation(eventlocation);
}
}
} catch (AssertionError ex) {
ex.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}

Related

Smart searching contacts in android

Following This Retrieving a List of Contacts Tutorial in the android developers site, I managed to implement contacts search functionality. Here is my code so far
private void retrieveContactRecord(String phoneNo) {
try {
Log.e("Info", "Input: " + phoneNo);
Uri uri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI,
Uri.encode(phoneNo));
String[] projection = new String[]{ContactsContract.PhoneLookup._ID, ContactsContract.PhoneLookup.DISPLAY_NAME};
String sortOrder = ContactsContract.PhoneLookup.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
ContentResolver cr = getContentResolver();
if (cr != null) {
Cursor resultCur = cr.query(uri, projection, null, null, sortOrder);
if (resultCur != null) {
while (resultCur.moveToNext()) {
String contactId = resultCur.getString(resultCur.getColumnIndex(ContactsContract.PhoneLookup._ID));
String contactName = resultCur.getString(resultCur.getColumnIndexOrThrow(ContactsContract.PhoneLookup.DISPLAY_NAME));
Log.e("Info", "Contact Id : " + contactId);
Log.e("Info", "Contact Display Name : " + contactName);
break;
}
resultCur.close();
}
}
} catch (Exception sfg) {
Log.e("Error", "Error in loadContactRecord : " + sfg.toString());
}
}
Here is the catch, this code works pretty great, but I need to implement a smart search here. I want 26268 to match Amanu as well as 094 526 2684. I believe it is called T9 dictionary.
I tried looking at other projects for clue, but I couldn't find anything. Any pointers would be appreciated!
T9 search can be implemented using trie data structure. You can see an example here - Trie dict.
After implementing something similar you will be able to convert your search input into its possible T9 decoded variant and compare if it matches with name.
Dump all contacts to a HashSet
Set<String> contacts = new HashSet<String>();
Then search:
List<List<String>> results = new ArrayList<List<String>>();
// start the search, pass empty stack to represent words found so far
search(input, dictionary, new Stack<String>(), results);
Search method (from #WhiteFang34)
public static void search(String input, Set<String> contacts,
Stack<String> words, List<List<String>> results) {
for (int i = 0; i < input.length(); i++) {
// take the first i characters of the input and see if it is a word
String substring = input.substring(0, i + 1);
if (contacts.contains(substring)) {
// the beginning of the input matches a word, store on stack
words.push(substring);
if (i == input.length() - 1) {
// there's no input left, copy the words stack to results
results.add(new ArrayList<String>(words));
} else {
// there's more input left, search the remaining part
search(input.substring(i + 1), contacts, words, results);
}
// pop the matched word back off so we can move onto the next i
words.pop();
}
}
}
The ContentProvider for contacts doesn't support it. So what I did was to dump all of the contacts in a List then use a RegEx to match for the name.
public static String[] values = new String[]{" 0", "1", "ABC2", "DEF3", "GHI4", "JKL5", "MNO6", "PQRS7", "TUV8", "WXYZ9"};
/**
* Get the possible pattern
* You'll get something like ["2ABC","4GHI"] for input "14"
*/
public static List<String> possibleValues(String in) {
if (in.length() >= 1) {
List<String> p = possibleValues(in.substring(1));
String s = "" + in.charAt(0);
if (s.matches("[0-9]")) {
int n = Integer.parseInt(s);
p.add(0, values[n]);
} else {
// It is a character, use it as it is
p.add(s);
}
return p;
}
return new ArrayList<>();
}
.... Then compile the pattern. I used (?i) to make it case insensitive
List<String> values = Utils.possibleValues(query);
StringBuilder sb = new StringBuilder();
for (String value : values) {
sb.append("[");
sb.append(value);
sb.append("]");
if (values.get(values.size() - 1) != value) {
sb.append("\\s*");
}
}
Log.e("Utils", "Pattern = " + sb.toString());
Pattern queryPattern = Pattern.compile("(?i)(" + sb.toString() + ")");
You'll know what to do after this.

Difference between LG default calendar and Google calendars

On my LG-G3 there is a default calendar named "Phone". It's not Google's.
I build an application which syncs events with the user's Google Calendars, but when I select all the calendars with a query - I get the "Phone" calendar too. Since it's not a Google calendar, I can't use it with the Google Calendar functions (insert, delete, etc.).
I can't see any different between "Phone" calendar and Google canledars except of its name. Is there any way to know if a calendar is Google's or not?
This is my query:
String[] l_projection = new String[] { Calendars._ID, Calendars.CALENDAR_DISPLAY_NAME, Calendars.CALENDAR_ACCESS_LEVEL, Calendars.ALLOWED_REMINDERS, Calendars.SYNC_EVENTS };
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");
}
try {
Cursor l_managedCursor = activity.getContentResolver().query(l_calendars, l_projection, null, null, null);
if (l_managedCursor.moveToFirst()) {
String l_methodAllow;
String l_accessPermission;
String l_calName;
String l_calId;
String l_syncEvents;
int l_cnt = 0;
int l_syncEventsCol = l_managedCursor.getColumnIndex(l_projection[4]);
int l_methodAllowCol = l_managedCursor.getColumnIndex(l_projection[3]);
int l_accessPermissionCol = l_managedCursor.getColumnIndex(l_projection[2]);
int l_nameCol = l_managedCursor.getColumnIndex(l_projection[1]);
int l_idCol = l_managedCursor.getColumnIndex(l_projection[0]);
do {
String access = l_managedCursor.getString(l_accessPermissionCol);
if (access.equals("500") || access.equals("600") || access.equals("700") || access.equals("800")) {
l_syncEvents = l_managedCursor.getString(l_syncEventsCol);
l_methodAllow = l_managedCursor.getString(l_methodAllowCol);
l_accessPermission = l_managedCursor.getString(l_accessPermissionCol);
l_calName = l_managedCursor.getString(l_nameCol);
l_calId = l_managedCursor.getString(l_idCol);
calNames.add(l_calName);
// ....
++l_cnt;
}
} while (l_managedCursor.moveToNext());
}
} catch (Exception e) {
// ...
}
Google calendar can be identified by looking at the domain name of the Calendar ID. For primary calendar, calendar ID domain name is #gmail.com. If its secondary calendar, calendar ID domain name is group.calendar.google.com

Loading multiple contacts with Xamarin.Contacts.AddressBook

I want to load several contacts via Xamarin.Contacts.AddressBook, at the moment I have something like:
var loookupIDs = /* load 10 saved contact IDs */
var addressBook = new AddressBook(context) { PreferContactAggregation = true };
foreach(var id in loookupIDs)
{
var contact = addressBook.Load(id);
names.Add(contact.DisplayName);
}
However, this is really slow (tested on Android device) - even just loading 10 contacts. Is there a way to batch up the loading so it's faster? Or is the only option to use platform specific APIs instead of the Xamarin wrapper.
Yes, Xamarin.Mobile is kind of slow. It combines all possible contacts (phones, mails, etc) and all possible fields, which is not recommended by Android reference manual.
I recommend you to use native way to query your contacts with Cursor and filter it for your needs. Sadly, Xamarin dev mixed up all constants, so it is not trivial task.
Here is complete example
public class PhoneContactInfo
{
public string PhoneContactID { get; set; }
public string ContactName { get; set; }
public string ContactNumber { get; set; }
}
public IEnumerable<PhoneContactInfo> GetAllPhoneContacts(IEnumerable<int> filterIds = null)
{
Log.Debug("GetAllPhoneContacts", "Getting all Contacts");
var arrContacts = new System.Collections.Generic.List<PhoneContactInfo>();
PhoneContactInfo phoneContactInfo = null;
var uri = ContactsContract.CommonDataKinds.Phone.ContentUri;
string[] projection = { ContactsContract.Contacts.InterfaceConsts.Id,
ContactsContract.Contacts.InterfaceConsts.DisplayName,
ContactsContract.CommonDataKinds.Phone.Number
};
//String[] strings = filterIds.Select(k => Convert.ToString(k)).ToArray();
//string whereClause = ContactsContract.Contacts.InterfaceConsts.Id + " = ? ";
var cursor = MainActivity.ContextHolder.ContentResolver.Query(uri, projection,
null,
null,
null);
cursor.MoveToFirst();
while (cursor.IsAfterLast == false)
{
int phoneContactID = cursor.GetInt(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.Id));
if (filterIds.Contains(phoneContactID))
{
String contactNumber = cursor.GetString(cursor.GetColumnIndex(ContactsContract.CommonDataKinds.Phone.Number));
String contactName = cursor.GetString(cursor.GetColumnIndex(ContactsContract.Contacts.InterfaceConsts.DisplayName));
phoneContactInfo = new PhoneContactInfo()
{
PhoneContactID = Convert.ToString(phoneContactID),
ContactName = contactName,
ContactNumber = contactNumber
};
arrContacts.Add(phoneContactInfo);
}
cursor.MoveToNext();
}
cursor.Close();
cursor = null;
Log.Debug("GetAllPhoneContacts", "Got all Contacts");
return arrContacts;
}
If you wish to add some fancy async
public Task<IEnumerable<PhoneContactInfo>> GetAllPhoneContactsAsync(IEnumerable<int> filterIds)
{
return Task.FromResult(GetAllPhoneContacts(filterIds));
}
Also take a look at commented whereClause. You possibly can construct 'SQL like' where clause to make this query even more faster. Just build a string with several '=' and 'or'
P.S.
I didn't measure performance differences, if anyone has decent statistics i will be grateful
It looks like you access AdressBook for each loookupID, this might cause your speed issue.
Try:
1) Fetch all contacts, or only those you might be interested in. (Use Linq)
2) Do further work with found contacts
Example from Xamarin docs:
http://blog.xamarin.com/introducing-xamarin-contacts/
var book = new AddressBook (this) {
PreferContactAggregation = true
};
foreach (Contact c in book.Where (c => c.LastName == "Smith")) {
print (c.DisplayName);
foreach (Phone p in c.Phones)
print ("Phone: " + p.Number);
foreach (Email e in c.Emails)
print ("Email: " + e.Address);
}

I'm making a simple Dashclock Calendar extension, and it stopped updating

I'm making a basic Dashclock extension that polls CalendarContract.Events for a list of all calendar events synced to the user's device, retrieve the one that's scheduled to happen the soonest, and post the time, title, location, and desctiption. Here's my code:
public class FullCalService extends DashClockExtension {
public static final String[] FIELDS = { Events._ID, Events.TITLE,
Events.ALL_DAY, Events.EVENT_LOCATION, Events.DTSTART,
Events.EVENT_TIMEZONE, Events.DESCRIPTION };
public FullCalService() {
}
#Override
protected void onUpdateData(int arg0) {
TimeZone tz = TimeZone.getDefault();
long currentTimeMillis = Calendar.getInstance().getTimeInMillis() - tz.getRawOffset();
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this);
Cursor c;
if (prefs.getBoolean("allDayAllowed", false)) {
c = getContentResolver().query(
Events.CONTENT_URI,
FIELDS,
new StringBuilder().append("(").append(Events.DTSTART)
.append(" >= ?)").toString(),
new String[] { Long.toString(currentTimeMillis) },
Events.DTSTART, null);
} else {
c = getContentResolver().query(
Events.CONTENT_URI,
FIELDS,
new StringBuilder().append("((").append(Events.ALL_DAY)
.append("= ?) AND (").append(Events.DTSTART)
.append(" >= ?))").toString(),
new String[] { Integer.toString(0),
Long.toString(currentTimeMillis) }, Events.DTSTART,
null);
}
if (c.moveToFirst()) {
long eventTimeMillis = c.getLong(c.getColumnIndex(Events.DTSTART));
// if (tz.inDaylightTime(new Date(eventTimeMillis))) {
// eventTimeMillis += tz.getDSTSavings();
// }
//Log.d("DesCal service", "Value of hoursToReveal: "+prefs.getString("hoursToReveal", "1"));
if (eventTimeMillis < currentTimeMillis + 360000
* Integer.parseInt(prefs.getString("hoursToReveal", "1"))) {
String title = c.getString(c.getColumnIndex(Events.TITLE));
String loc = c.getString(c
.getColumnIndex(Events.EVENT_LOCATION));
String time = DateUtils.formatDateTime(this, eventTimeMillis,
DateUtils.FORMAT_SHOW_TIME);
String desc = c.getString(c.getColumnIndex(Events.DESCRIPTION));
StringBuilder expandedBody = new StringBuilder(time);
if (!loc.isEmpty()){
expandedBody.append(" - ").append(loc);
}
expandedBody.append("\n").append(desc);
String uri = new StringBuilder(
"content://com.android.calendar/events/").append(
c.getLong(c.getColumnIndex(Events._ID))).toString();
publishUpdate(new ExtensionData()
.visible(true)
.status(time)
.expandedTitle(title)
.expandedBody(expandedBody.toString())
.icon(R.drawable.ic_dash_cal)
.clickIntent(
new Intent(Intent.ACTION_VIEW, Uri.parse(uri))));
c.close();
} else {
publishUpdate(new ExtensionData().visible(false));
c.close();
}
} else {
publishUpdate(new ExtensionData().visible(false));
c.close();
}
}
}
Upon first install, it appeared to work just fine. However, after the event began, it would not grab any future events. Is there a reason why the extension will not refresh itself?
How are you triggering further updates? You need to manually specify when you'd like to have onUpdateData called, e.g. when there's a change to a content provider, or when the screen turns on, etc. Extensions by default refresh only every 30 minutes or so. See the source for the built in calendar extension for example code.

how to use SerialExecutor with AsyncTask (API < 11)

I've an app that is used by carers to sign in to the system using their android phones. They scan a QRcode or swipe an NFC tag to get the client's information, scan time and location. The latter info constitutes a transaction. The transaction is placed in the phone's DB as well as submitted to a server via HTTP.
All works well as all transactions are put in DB and posted to web service until i have to make two transactions at the same time. A transaction is made by calling AsyncTask as it's a network call and so not to block UI thread. Both transactions are made to the web service but not all the data is sent to DB. I've commented out some code and made one Async post at a time and the data is then sent fine.
The problem
When one AsyncTask is running the other starts. When this happens the first AsyncTask doesn't work correctly. I have found the following thread where there is a similar problem and using a SerialExecutor seems to be the answer.
serialexecutor
https://stackoverflow.com/questions/6645203/android-asynctask-avoid-multiple-instances-running
Could anyone help me implement the 2 following AsyncTasks in a SerialExecutor, I'm fairly new to Android and i'm struggling to start this off. I'd like apd to execute and finish then apd3 to execute after. All in a serial fashion.
Thanks in advance Matt
String temp_tagType = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TYPE));
String temp_tagCompId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_COMPANY_ID));
String temp_PersonId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_PERSON_ID));
String temp_tagName = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_NAME));
String temp_tagId = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TAG_ID));
String temp_tagScanTime = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TAG_SCAN_TIME));
String temp_tagLatitude = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TRANSACTIONS_LATITUDE));
String temp_tagLongitude = cursor.getString(cursor
.getColumnIndex(LoginValidate.C_TRANSACTIONS_LONGITUDE));
if(temp_tagId == null){
temp_tagId = "notag";
}
String manualM = "M";
Log.e(TAG, " temp name and status = " + temp_tagName + " " + manualM);
////////insert the temp variables with the status set to M
ContentValues values = new ContentValues();
values.putNull(LoginValidate.C_ID);
values.put(LoginValidate.C_TYPE, temp_tagType);
values.put(LoginValidate.C_COMPANY_ID, nfcscannerapplication.getCompId());
values.put(LoginValidate.C_PERSON_ID, temp_PersonId);
values.put(LoginValidate.C_NAME, temp_tagName);
values.put(LoginValidate.C_TAG_ID, temp_tagId);
values.put(LoginValidate.C_STATUS, manualM);
values.put(LoginValidate.C_TAG_SCAN_TIME, manualLogoutTime);
values.put(LoginValidate.C_TRANSACTIONS_LATITUDE, temp_tagLatitude);
values.put(LoginValidate.C_TRANSACTIONS_LONGITUDE, temp_tagLongitude);
DateTime now = new DateTime();
DateTimeFormatter df = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String formattedNowTime = df.print(now);
Log.e(TAG, "formattedNowTime = " + formattedNowTime);
DateTimeFormatter df2 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String manualTime = df2.print(timeSetOnSpinner);
Log.e(TAG, "about to put " + temp_tagName + " into DB");
nfcscannerapplication.loginValidate.insertIntoTransactions(values);
String[] params = new String[]{nfcscannerapplication.getCompId(), temp_tagId, temp_PersonId, nfcscannerapplication.getCarerID(),
manualTime, formattedNowTime, manualM, getDeviceName(), temp_tagLatitude, temp_tagLongitude};
AsyncPostData apd = new AsyncPostData();
apd.execute(params);
///////////////now carry on as usual with the last actual tag that has been scanned
Log.e(TAG, "about to insert the current record after inserting the manual logout");
if(tagId == null){
tagId = _tagId;
}
ContentValues values3 = new ContentValues();
values3.putNull(LoginValidate.C_ID);
values3.put(LoginValidate.C_TYPE, tagType);
values3.put(LoginValidate.C_COMPANY_ID, nfcscannerapplication.getCompId());
values3.put(LoginValidate.C_PERSON_ID, tagPerson);
values3.put(LoginValidate.C_NAME, tagUserName);
values3.put(LoginValidate.C_TAG_ID, tagId);
values3.put(LoginValidate.C_STATUS, IN);
values3.put(LoginValidate.C_TAG_SCAN_TIME, tagScanTime.getMillis());
values3.put(LoginValidate.C_TRANSACTIONS_LATITUDE, tagLatitude);
values3.put(LoginValidate.C_TRANSACTIONS_LONGITUDE, tagLongitude);
// make the current transaction out
DateTime now3 = new DateTime();
DateTimeFormatter df3 = DateTimeFormat.forPattern("yyyy-MM-dd H:mm:ss.SSS");
String formattedNowTime3 = df3.print(now3);
Log.e(TAG, "formattedNowTime = " + formattedNowTime3);
String formattedTagScanTime3 = df3.print(tagScanTime);
Log.e(TAG, "about to put " + tagUserName + " into DB");
nfcscannerapplication.loginValidate.insertIntoTransactions(values3);
String[] params3 = new String[]{nfcscannerapplication.getCompId(), tagId, tagPerson, nfcscannerapplication.getCarerID(),
formattedTagScanTime3, formattedNowTime, IN, getDeviceName(), tagLatitude, tagLongitude};
AsyncPostData apd3 = new AsyncPostData();
apd3.execute(params3);
.

Categories

Resources