private void queryBdayToUpdate(JSONObject bd) throws JSONException {
   uChecksCounter++;
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String[] projection = {EventTable.COLUMN_OID, EventTable.COLUMN_ID, EventTable.COLUMN_PIC_URL};
   Long begin = bdayToMillis(bd.getString("anon"), true);
   String selection =
       EventTable.COLUMN_CALENDAR_ID
           + " = \""
           + EventTable.CALENDAR_ID_FB_BIRTHDAYS
           + "\" AND "
           + EventTable.COLUMN_BEGIN
           + " >= "
           + Calendar.getInstance().getTimeInMillis()
           + " AND "
           + EventTable.COLUMN_OID
           + " = "
           + bd.getString("uid")
           + " AND "
           + EventTable.COLUMN_BEGIN_DAY
           + " != "
           + Time.getJulianDay(
               begin, TimeUnit.MILLISECONDS.toSeconds(TimeZone.getDefault().getOffset(begin)));
   // IDEA: setting the event JSONObject as cookie
   handler.startQuery(
       QUERY_BD_TO_UPDATE,
       bd,
       AgendaNowProvider.CONTENT_URI_EV,
       projection,
       selection,
       null,
       null);
 }
 public void queryFutureStoredBDays() {
   resetCounters();
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String[] projection = {
     EventTable.COLUMN_OID, EventTable.COLUMN_UPDATED_TIME, EventTable.COLUMN_ID
   };
   String selection =
       EventTable.COLUMN_CALENDAR_ID
           + " = "
           + EventTable.CALENDAR_ID_FB_BIRTHDAYS
           + " AND "
           + EventTable.COLUMN_BEGIN
           + " >= "
           + today_begin.getTimeInMillis();
   if (isAppLaunchStage) {
     selection += " AND " + EventTable.COLUMN_BEGIN + " <= " + today_end.getTimeInMillis();
   }
   String orderBy = "date(" + EventTable.COLUMN_UPDATED_TIME + ") ASC";
   handler.startQuery(
       QUERY_FUTURE_STORED_BDS,
       null,
       AgendaNowProvider.CONTENT_URI_EV,
       projection,
       selection,
       null,
       orderBy);
 }
 private void queryBdayToInsert(JSONObject bd) throws JSONException {
   iChecksCounter++;
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String[] projection = {EventTable.COLUMN_OID, EventTable.COLUMN_ID};
   String selection =
       EventTable.COLUMN_CALENDAR_ID
           + " = \""
           + EventTable.CALENDAR_ID_FB_BIRTHDAYS
           + "\" AND "
           + EventTable.COLUMN_OID
           + " = "
           + bd.getString("uid");
   // IDEA: setting the event JSONObject as cookie
   handler.startQuery(
       101, bd, AgendaNowProvider.CONTENT_URI_EV, projection, selection, null, null);
 }
 private void deleteCanceledBdays(Cursor futureStored) {
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String selection =
       EventTable.COLUMN_OID + " = ? AND " + EventTable.COLUMN_CALENDAR_ID + " = ? ";
   if (futureStored.getCount() > 0) {
     futureStored.moveToFirst();
     do {
       String userId = futureStored.getString(futureStored.getColumnIndex(EventTable.COLUMN_OID));
       if (!(rs3.toString().contains(userId))) {
         deletionCounter++;
         String[] selArgs = {userId, Integer.toString(EventTable.CALENDAR_ID_FB_BIRTHDAYS)};
         handler.startDelete(
             DELETE_CANCELED_EV, null, AgendaNowProvider.CONTENT_URI_EV, selection, selArgs);
       }
       futureStored.moveToNext();
     } while (!(futureStored.isAfterLast()));
     futureStored.close();
   }
 }
 /*
  * Taking an event coming from FB JSON response as input parameter, this method is looking
  * for that event in the ContentProvider, selecting it only if its latest update time
  * is different by the one present in the JSON. If so, the event row is updated.
  */
 public void queryEventToUpdate(JSONObject ev) throws JSONException {
   uChecksCounter++;
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String[] projection = {
     EventTable.COLUMN_OID,
     EventTable.COLUMN_UPDATED_TIME,
     EventTable.COLUMN_ID,
     EventTable.COLUMN_PIC_URL
   };
   String selection =
       EventTable.COLUMN_PLATFORM
           + " = \""
           + EventTable.PLATFORM_FACEBOOK
           + "\" AND "
           + EventTable.COLUMN_BEGIN
           + " >= "
           + today_begin.getTimeInMillis()
           + " AND "
           + EventTable.COLUMN_OID
           + " = "
           + ev.getString("eid")
           + " AND "
           + EventTable.COLUMN_UPDATED_TIME
           + " <> "
           + ev.getString("update_time");
   if (isAppLaunchStage) {
     selection += " AND " + EventTable.COLUMN_BEGIN + "<=" + today_end.getTimeInMillis();
   }
   // IDEA: setting the event JSONObject as cookie
   handler.startQuery(
       QUERY_EV_TO_UPDATE,
       ev,
       AgendaNowProvider.CONTENT_URI_EV,
       projection,
       selection,
       null,
       null);
 }
 /*
  * Taking an event coming from FB JSON response as input parameter, this method is looking
  * for that event in the ContentProvider. If not found, a new row is created, to insert the new event.
  */
 public void queryEventToInsert(JSONObject ev) throws JSONException {
   iChecksCounter++;
   CustomAsyncHandler handler = new CustomAsyncHandler(getContentResolver(), this);
   String[] projection = {
     EventTable.COLUMN_OID, EventTable.COLUMN_UPDATED_TIME, EventTable.COLUMN_ID
   };
   String selection =
       EventTable.COLUMN_PLATFORM
           + " = \""
           + EventTable.PLATFORM_FACEBOOK
           + "\" AND "
           + EventTable.COLUMN_OID
           + " = "
           + ev.getString("eid");
   // IDEA: setting the event JSONObject as cookie
   handler.startQuery(
       QUERY_EV_TO_INSERT,
       ev,
       AgendaNowProvider.CONTENT_URI_EV,
       projection,
       selection,
       null,
       null);
 }
 /*
  * Handling actions to execute on the completion of queries, updates, deletions, insertions.
  * Order of the operations:
  * 1) Querying for future FB events stored;
  * 2) Deletion of canceled FB events;
  * 3) For each event got from the JSON, check if there is a row to update
  *    or if there is no row: in the latter case, create it.
  *
  * NB: on completion of queries, updates, deletes, insertions the operation counters
  * are checked; if they are all set to 0, then sync process has been completed.
  * In this case, if there is a PTR layout active, then its animation is stopped.
  */
 @Override
 public void onQueryComplete(int token, Object cookie, Cursor cursor) {
   switch (token) {
     case QUERY_FUTURE_STORED_EVS:
       deleteCanceledEvents(cursor);
       for (int i = 0; i < rs1.length(); i++) {
         try {
           JSONObject ev = rs1.getJSONObject(i);
           queryEventToUpdate(ev);
           queryEventToInsert(ev);
         } catch (JSONException e1) {
           e1.printStackTrace();
         }
       }
       checkIfUptodate();
       break;
     case QUERY_FUTURE_STORED_BDS:
       deleteCanceledBdays(cursor);
       for (int i = 0; i < rs3.length(); i++) {
         try {
           JSONObject bd = rs3.getJSONObject(i);
           queryBdayToUpdate(bd);
           queryBdayToInsert(bd);
         } catch (JSONException e1) {
           e1.printStackTrace();
         }
       }
       checkIfUptodate();
       break;
     case QUERY_EV_TO_UPDATE:
       CustomAsyncHandler updateHandler = new CustomAsyncHandler(getContentResolver(), this);
       if (cursor.getCount() > 0) {
         cursor.moveToFirst();
         if (ptrl != null) {
           if (!ptrl.isRefreshing()) ptrl.setRefreshing(true);
         }
         updateCounter++;
         JSONObject ev = (JSONObject) cookie;
         String selection = null;
         try {
           selection =
               EventTable.COLUMN_PLATFORM
                   + " = \""
                   + EventTable.PLATFORM_FACEBOOK
                   + "\" AND "
                   + EventTable.COLUMN_BEGIN
                   + " >= "
                   + today_begin.getTimeInMillis()
                   + " AND "
                   + EventTable.COLUMN_OID
                   + " = "
                   + ev.getString("eid")
                   + " AND "
                   + EventTable.COLUMN_UPDATED_TIME
                   + " <> "
                   + ev.getString("update_time");
           if (isAppLaunchStage) {
             selection += " AND " + EventTable.COLUMN_BEGIN + "<=" + today_end.getTimeInMillis();
           }
           updateHandler.startUpdate(
               UPDATE_STORED_EV,
               null,
               AgendaNowProvider.CONTENT_URI_EV,
               setContentValues(
                   ev,
                   UPDATE_STORED_EV,
                   cursor.getString(cursor.getColumnIndex(EventTable.COLUMN_PIC_URL))),
               selection,
               null);
         } catch (JSONException e) {
           e.printStackTrace();
         }
       }
       cursor.close();
       uChecksCounter--;
       checkIfFinished();
       break;
     case QUERY_BD_TO_UPDATE:
       CustomAsyncHandler updateHandler2 = new CustomAsyncHandler(getContentResolver(), this);
       if (cursor.getCount() > 0) {
         cursor.moveToFirst();
         if (ptrl != null) {
           if (!ptrl.isRefreshing()) ptrl.setRefreshing(true);
         }
         updateCounter++;
         JSONObject bd = (JSONObject) cookie;
         String selection = null;
         try {
           selection =
               EventTable.COLUMN_CALENDAR_ID
                   + " = \""
                   + EventTable.CALENDAR_ID_FB_BIRTHDAYS
                   + "\" AND "
                   + EventTable.COLUMN_OID
                   + " = "
                   + bd.getString("uid");
           updateHandler2.startUpdate(
               UPDATE_STORED_BD,
               null,
               AgendaNowProvider.CONTENT_URI_EV,
               setContentValues(
                   bd,
                   UPDATE_STORED_BD,
                   cursor.getString(cursor.getColumnIndex(EventTable.COLUMN_PIC_URL))),
               selection,
               null);
         } catch (JSONException e) {
           e.printStackTrace();
         }
       }
       cursor.close();
       uChecksCounter--;
       checkIfFinished();
       break;
     case QUERY_EV_TO_INSERT:
       CustomAsyncHandler insertHandler = new CustomAsyncHandler(getContentResolver(), this);
       if (cursor.getCount() < 1) {
         if (ptrl != null) {
           if (!ptrl.isRefreshing()) ptrl.setRefreshing(true);
         }
         insertionCounter++;
         JSONObject ev = (JSONObject) cookie;
         try {
           insertHandler.startInsert(
               INSERT_NEW_EV,
               null,
               AgendaNowProvider.CONTENT_URI_EV,
               setContentValues(ev, INSERT_NEW_EV, null));
         } catch (JSONException e) {
           e.printStackTrace();
         }
       }
       cursor.close();
       iChecksCounter--;
       checkIfFinished();
       break;
     case 101:
       CustomAsyncHandler insertHandler2 = new CustomAsyncHandler(getContentResolver(), this);
       if (cursor.getCount() < 1) {
         if (ptrl != null) {
           if (!ptrl.isRefreshing()) ptrl.setRefreshing(true);
         }
         insertionCounter++;
         JSONObject bd = (JSONObject) cookie;
         try {
           insertHandler2.startInsert(
               INSERT_NEW_BD,
               null,
               AgendaNowProvider.CONTENT_URI_EV,
               setContentValues(bd, INSERT_NEW_BD, null));
         } catch (JSONException e) {
           e.printStackTrace();
         }
       }
       cursor.close();
       iChecksCounter--;
       checkIfFinished();
       break;
   }
 }