Java tutorial
/* * Copyright (C) 2010 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. */ package pt.up.mobile.syncadapter; import java.io.File; import java.io.IOException; import java.lang.reflect.Type; import java.util.ArrayList; import java.util.List; import org.apache.http.auth.AuthenticationException; import org.json.JSONException; import pt.up.mobile.Constants; import pt.up.mobile.R; import pt.up.mobile.content.BaseColumns; import pt.up.mobile.content.SigarraContract; import pt.up.mobile.content.SigarraProvider; import pt.up.mobile.content.SubjectsTable; import pt.up.mobile.content.SyncStates; import pt.up.mobile.datatypes.Notification; import pt.up.mobile.datatypes.StudentCourse; import pt.up.mobile.datatypes.SubjectEntry; import pt.up.mobile.datatypes.TeachingService; import pt.up.mobile.datatypes.User; import pt.up.mobile.datatypes.TeachingService.Subject; import pt.up.mobile.sifeup.AccountUtils; import pt.up.mobile.sifeup.SifeupAPI; import pt.up.mobile.ui.notifications.NotificationsActivity; import pt.up.mobile.ui.notifications.NotificationsDescActivity; import pt.up.mobile.ui.notifications.NotificationsDescFragment; import pt.up.mobile.ui.notifications.NotificationsFragment; import pt.up.mobile.utils.DateUtils; import pt.up.mobile.utils.FileUtils; import pt.up.mobile.utils.GsonUtils; import pt.up.mobile.utils.LogUtils; import pt.up.mobile.utils.StringUtils; import android.accounts.Account; import android.accounts.AccountManager; import android.annotation.TargetApi; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.AbstractThreadedSyncAdapter; import android.content.ContentProviderClient; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.Intent; import android.content.SyncResult; import android.database.Cursor; import android.graphics.Bitmap; import android.media.RingtoneManager; import android.os.Build; import android.os.Bundle; import android.provider.ContactsContract; import android.support.v4.app.NotificationCompat; import android.support.v4.content.LocalBroadcastManager; import android.text.TextUtils; import android.text.format.Time; import android.util.Log; import com.google.analytics.tracking.android.EasyTracker; import com.google.gson.Gson; import com.google.gson.reflect.TypeToken; public class SigarraSyncAdapter extends AbstractThreadedSyncAdapter { final static String SINGLE_REQUEST = "single_request"; final static String REQUEST_TYPE = "request_type"; final static String PROFILE = "profile"; final static String PROFILE_CODE = "profile_code"; final static String PROFILE_TYPE = "profile_type"; final static String SUBJECT = "subject"; final static String EXAMS = "exams"; final static String CANTEENS = "canteens"; final static String TUITION = "tuition"; final static String TEACHING_SERVICE = "teaching_service"; final static String ACADEMIC_PATH = "academic_path"; final static String PRINTING_QUOTA = "printing_quota"; final static String NOTIFICATIONS = "notifications"; final static String PROFILE_PIC = "pic"; final static String CODE = "code"; final static String SCHEDULE = "schedule"; final static String SCHEDULE_CODE = "schedule_code"; final static String SCHEDULE_TYPE = "schedule_type"; final static String SCHEDULE_INITIAL = "initial"; final static String SCHEDULE_FINAL = "final"; public final static String NETWORK_ERROR = "pt.up.mobile.syncadapter.NETWORK_ERROR"; public final static String CANCELLED_ERROR = "pt.up.mobile.syncadapter.CANCELLED_ERROR"; public final static String GENERAL_ERROR = "pt.up.mobile.syncadapter.GENERAL_ERROR"; public final static String AUTHENTICATION_ERROR = "pt.up.mobile.syncadapter.AUTHENTICATION_ERROR"; public final static String SIGARRASYNCADAPTER_STATUS = "pt.up.mobile.syncadapter.SIGARRASYNCADAPTER_STATUS"; private final AccountManager mAccountManager; private LocalBroadcastManager broadcastManager; public SigarraSyncAdapter(Context context, boolean autoInitialize) { super(context, autoInitialize); mAccountManager = AccountManager.get(context.getApplicationContext()); broadcastManager = LocalBroadcastManager.getInstance(context.getApplicationContext()); EasyTracker.getInstance().setContext(context); } @TargetApi(8) @Override public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) { boolean listeningToProblems = false; try { if (extras.getBoolean(SINGLE_REQUEST)) { listeningToProblems = true; Log.d(getClass().getSimpleName(), "Fetching Sigarra"); if (SUBJECT.equals(extras.getString(REQUEST_TYPE))) { getSubject(account, extras.getString(CODE), syncResult); return; } if (PROFILE.equals(extras.getSerializable(REQUEST_TYPE))) { getProfile(account, extras.getString(PROFILE_CODE), extras.getString(PROFILE_TYPE), syncResult); return; } if (EXAMS.equals(extras.getSerializable(REQUEST_TYPE))) { syncExams(account, syncResult); return; } if (ACADEMIC_PATH.equals(extras.getSerializable(REQUEST_TYPE))) { syncAcademicPath(account, syncResult); return; } if (PROFILE_PIC.equals(extras.getSerializable(REQUEST_TYPE))) { syncProfilePic(extras.getString(CODE), account, syncResult); return; } if (TUITION.equals(extras.getSerializable(REQUEST_TYPE))) { syncTuition(account, syncResult); return; } if (TEACHING_SERVICE.equals(extras.getSerializable(REQUEST_TYPE))) { syncTeachingService(account, syncResult); return; } if (PRINTING_QUOTA.equals(extras.getSerializable(REQUEST_TYPE))) { syncPrintingQuota(account, syncResult); return; } if (NOTIFICATIONS.equals(extras.getSerializable(REQUEST_TYPE))) { syncNotifications(account, syncResult); return; } if (CANTEENS.equals(extras.getSerializable(REQUEST_TYPE))) { syncCanteens(account, syncResult); return; } if (SCHEDULE.equals(extras.getSerializable(REQUEST_TYPE))) { getSchedule(account, extras.getString(SCHEDULE_CODE), extras.getString(SCHEDULE_TYPE), extras.getString(SCHEDULE_INITIAL), extras.getString(SCHEDULE_FINAL), SyncStates.PRUNE, syncResult); return; } } else { Log.d(getClass().getSimpleName(), "Sync Sigarra"); syncProfiles(account, syncResult); syncExams(account, syncResult); syncTuition(account, syncResult); syncPrintingQuota(account, syncResult); syncSchedule(account, syncResult); syncNotifications(account, syncResult); syncCanteens(account, syncResult); final User user = AccountUtils.getUser(getContext(), account.name); if (user.getType().equals(SifeupAPI.STUDENT_TYPE)) { syncAcademicPath(account, syncResult); syncSubjects(account, syncResult); } else { syncTeachingService(account, syncResult); } } } catch (IOException e) { syncResult.stats.numIoExceptions++; if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO) syncResult.delayUntil = 3600; if (listeningToProblems) broadcastManager.sendBroadcast( new Intent(SIGARRASYNCADAPTER_STATUS).putExtra(SIGARRASYNCADAPTER_STATUS, NETWORK_ERROR)); e.printStackTrace(); } catch (AuthenticationException e) { e.printStackTrace(); mAccountManager.invalidateAuthToken(Constants.ACCOUNT_TYPE, null); syncResult.stats.numAuthExceptions++; if (listeningToProblems) broadcastManager.sendBroadcast(new Intent(SIGARRASYNCADAPTER_STATUS) .putExtra(SIGARRASYNCADAPTER_STATUS, AUTHENTICATION_ERROR)); } catch (Exception e) { if (listeningToProblems) broadcastManager.sendBroadcast( new Intent(SIGARRASYNCADAPTER_STATUS).putExtra(SIGARRASYNCADAPTER_STATUS, GENERAL_ERROR)); e.printStackTrace(); LogUtils.trackException(getContext(), e, null, true); } } private void syncCanteens(Account account, SyncResult syncResult) throws AuthenticationException, IOException { final String canteens = SifeupAPI.getReply(SifeupAPI.getCanteensUrl(), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.Canteens.ID, SigarraContract.Canteens.DEFAULT_ID); values.put(SigarraContract.Canteens.CONTENT, canteens); getContext().getContentResolver().insert(SigarraContract.Canteens.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void syncNotifications(Account account, SyncResult syncResult) throws AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String notificationReply = SifeupAPI.getReply(SifeupAPI.getNotificationsUrl(user.getUserCode()), account, getContext()); final Gson gson = GsonUtils.getGson(); final Notification[] notifications = gson.fromJson(notificationReply, Notification[].class); if (notifications == null) { syncResult.stats.numParseExceptions++; LogUtils.trackException(getContext(), new RuntimeException(), notificationReply, true); return; } ArrayList<String> fetchedNotCodes = new ArrayList<String>(); ArrayList<ContentValues> bulkValues = new ArrayList<ContentValues>(); for (Notification not : notifications) { final ContentValues values = new ContentValues(); values.put(SigarraContract.Notifcations.CONTENT, gson.toJson(not)); fetchedNotCodes.add(not.getCode()); if (getContext().getContentResolver().update(SigarraContract.Notifcations.CONTENT_URI, values, SigarraContract.Notifcations.UPDATE_NOTIFICATION, SigarraContract.Notifcations.getNotificationsSelectionArgs(account.name, not.getCode())) == 0) { values.put(SigarraContract.Notifcations.CODE, account.name); values.put(SigarraContract.Notifcations.ID_NOTIFICATION, not.getCode()); values.put(SigarraContract.Notifcations.STATE, SigarraContract.Notifcations.NEW); values.put(SigarraContract.Notifcations.CODE, account.name); bulkValues.add(values); } } // inserting the values if (bulkValues.size() > 0) { getContext().getContentResolver().bulkInsert(SigarraContract.Notifcations.CONTENT_URI, bulkValues.toArray(new ContentValues[0])); // if the account being synced is the current active accout // display notification if (AccountUtils.getActiveUserName(getContext()).equals(account.name)) { final NotificationManager mNotificationManager = (NotificationManager) getContext() .getSystemService(Context.NOTIFICATION_SERVICE); NotificationCompat.Builder notBuilder = new NotificationCompat.Builder(getContext()); notBuilder.setAutoCancel(true).setOnlyAlertOnce(true) .setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION)); if (bulkValues.size() == 1) { final Notification notification = gson.fromJson( bulkValues.get(0).getAsString(SigarraContract.Notifcations.CONTENT), Notification.class); Intent notifyIntent = new Intent(getContext(), NotificationsDescActivity.class) .putExtra(NotificationsDescFragment.NOTIFICATION, notification); // Creates the PendingIntent PendingIntent notifyPendingIntent = PendingIntent.getActivity(getContext(), 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); // Sets the Activity to start in a new, empty task notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); notBuilder.setSmallIcon(R.drawable.icon).setTicker(notification.getMessage()) .setContentTitle(notification.getSubject()).setContentText(notification.getMessage()) .setContentIntent(notifyPendingIntent) .setStyle(new NotificationCompat.BigTextStyle().bigText(notification.getMessage()) .setBigContentTitle(notification.getSubject()) .setSummaryText(notification.getMessage())); mNotificationManager.notify(notification.getCode().hashCode(), notBuilder.build()); } else { final String notTitle = getContext().getString(R.string.new_notifications, bulkValues.size()); Intent notifyIntent = new Intent(getContext(), NotificationsActivity.class); // Sets the Activity to start in a new, empty task notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); // Creates the PendingIntent PendingIntent notifyPendingIntent = PendingIntent.getActivity(getContext(), 0, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT); NotificationCompat.InboxStyle inboxStyle = new NotificationCompat.InboxStyle(); // Sets a title for the Inbox style big view inboxStyle.setBigContentTitle(notTitle); // Moves events into the big view for (ContentValues value : bulkValues) { final Notification notification = gson.fromJson( value.getAsString(SigarraContract.Notifcations.CONTENT), Notification.class); inboxStyle.addLine(notification.getSubject()); } // Moves the big view style object into the notification // object. notBuilder.setStyle(inboxStyle); notBuilder.setSmallIcon(R.drawable.icon).setTicker(notTitle).setContentTitle(notTitle) .setContentText("").setContentIntent(notifyPendingIntent); mNotificationManager.notify(NotificationsFragment.class.getName().hashCode(), notBuilder.build()); } } } final Cursor syncState = getContext().getContentResolver().query(SigarraContract.LastSync.CONTENT_URI, SigarraContract.LastSync.COLUMNS, SigarraContract.LastSync.PROFILE, SigarraContract.LastSync.getLastSyncSelectionArgs(AccountUtils.getActiveUserName(getContext())), null); try { if (syncState.moveToFirst()) { if (syncState.getLong(syncState.getColumnIndex(SigarraContract.LastSync.NOTIFICATIONS)) == 0) { // Report that we have checked the notifications final ContentValues values = new ContentValues(); values.put(SigarraContract.LastSync.NOTIFICATIONS, System.currentTimeMillis()); getContext().getContentResolver().update(SigarraContract.LastSync.CONTENT_URI, values, SigarraContract.LastSync.PROFILE, SigarraContract.LastSync.getLastSyncSelectionArgs(account.name)); } } } finally { syncState.close(); } ArrayList<String> notToDelete = new ArrayList<String>(); final Cursor cursor = getContext().getContentResolver().query(SigarraContract.Notifcations.CONTENT_URI, new String[] { SigarraContract.Notifcations.ID_NOTIFICATION }, SigarraContract.Notifcations.PROFILE, SigarraContract.Notifcations.getNotificationsSelectionArgs(account.name), null); try { if (cursor.moveToFirst()) { do { final String code = cursor.getString(0); if (!fetchedNotCodes.contains(code)) notToDelete.add(code); } while (cursor.moveToNext()); } else { // no notifications getContext().getContentResolver().notifyChange(SigarraContract.Notifcations.CONTENT_URI, null); } } finally { cursor.close(); } if (notToDelete.size() > 0) getContext().getContentResolver().delete(SigarraContract.Notifcations.CONTENT_URI, SigarraContract.Notifcations.getNotificationsDelete(notToDelete.toArray(new String[0])), SigarraContract.Notifcations.getNotificationsSelectionArgs(account.name, notToDelete.toArray(new String[0]))); syncResult.stats.numEntries += notifications.length; } private void syncSchedule(Account account, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String type; if (user.getType().equals(SifeupAPI.STUDENT_TYPE)) type = SigarraContract.Schedule.STUDENT; else type = SigarraContract.Schedule.EMPLOYEE; final Long mondayMillis = DateUtils.firstDayofWeek(); Time monday = new Time(DateUtils.TIME_REFERENCE); monday.set(mondayMillis); monday.normalize(false); String initialDay = monday.format("%Y%m%d"); // Friday monday.set(DateUtils.moveDayofWeek(mondayMillis, 4)); monday.normalize(false); String finalDay = monday.format("%Y%m%d"); getSchedule(account, user.getUserCode(), type, initialDay, finalDay, SyncStates.KEEP, syncResult); } private void getSchedule(Account account, String code, String type, String initialDay, String finalDay, String state, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final String page; if (SigarraContract.Schedule.STUDENT.equals(type)) page = SifeupAPI.getReply(SifeupAPI.getStudentScheduleUrl(code, initialDay, finalDay), account, getContext()); else if (SigarraContract.Schedule.EMPLOYEE.equals(type)) { page = SifeupAPI.getReply(SifeupAPI.getTeacherScheduleUrl(code, initialDay, finalDay), account, getContext()); } else if (SigarraContract.Schedule.ROOM.equals(type)) { page = SifeupAPI.getReply(SifeupAPI.getRoomScheduleUrl(code, initialDay, finalDay), account, getContext()); } else if (SigarraContract.Schedule.UC.equals(type)) { page = SifeupAPI.getReply(SifeupAPI.getUcScheduleUrl(code, initialDay, finalDay), account, getContext()); } else if (SigarraContract.Schedule.CLASS.equals(type)) { page = SifeupAPI.getReply(SifeupAPI.getClassScheduleUrl(code, initialDay, finalDay), account, getContext()); } else throw new RuntimeException("Unknown schedule type " + type); final ContentValues values = new ContentValues(); values.put(SigarraContract.ScheduleColumns.CODE, code); values.put(SigarraContract.ScheduleColumns.TYPE, type); values.put(SigarraContract.ScheduleColumns.CONTENT, page); values.put(SigarraContract.ScheduleColumns.INITIAL_DAY, initialDay); values.put(SigarraContract.ScheduleColumns.FINAL_DAY, finalDay); values.put(BaseColumns.COLUMN_STATE, state); getContext().getContentResolver().insert(SigarraContract.Schedule.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void syncPrintingQuota(Account account, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String printing = SifeupAPI.getReply(SifeupAPI.getPrintingUrl(user.getUserCode()), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.PrintingQuotaColumns.ID, account.name); values.put(SigarraContract.PrintingQuotaColumns.QUOTA, printing); values.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); getContext().getContentResolver().insert(SigarraContract.PrintingQuota.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void syncTuition(Account account, SyncResult syncResult) throws AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String tuition = SifeupAPI.getReply(SifeupAPI.getCurrentAccountUrl(user.getUserCode()), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.TuitionColumns.ID, account.name); values.put(SigarraContract.TuitionColumns.CONTENT, tuition); values.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); getContext().getContentResolver().insert(SigarraContract.Tuition.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void syncAcademicPath(Account account, SyncResult syncResult) throws AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String academicPath = SifeupAPI.getReply(SifeupAPI.getStudentAcademicPathUrl(user.getUserCode()), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.AcademicPathColumns.ID, account.name); values.put(SigarraContract.AcademicPathColumns.CONTENT, academicPath); values.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); getContext().getContentResolver().insert(SigarraContract.AcademicPath.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void syncExams(Account account, SyncResult syncResult) throws AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String exams; if (user.getType().equals(SifeupAPI.STUDENT_TYPE)) exams = SifeupAPI.getReply(SifeupAPI.getStudentExamsUrl(user.getUserCode()), account, getContext()); else exams = SifeupAPI.getReply(SifeupAPI.getEmployeeExamsUrl(user.getUserCode()), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.ExamsColumns.ID, account.name); values.put(SigarraContract.ExamsColumns.CONTENT, exams); values.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); getContext().getContentResolver().insert(SigarraContract.Exams.CONTENT_URI, values); syncResult.stats.numEntries += 1; } private void getProfile(Account account, String userCode, String type, SyncResult syncResult) throws AuthenticationException, IOException { final String profile; if (type.equals(SifeupAPI.STUDENT_TYPE)) profile = SifeupAPI.getReply(SifeupAPI.getStudenProfiletUrl(userCode), account, getContext()); else profile = SifeupAPI.getReply(SifeupAPI.getEmployeeProfileUrl(userCode), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.ProfileColumns.ID, userCode); values.put(SigarraContract.ProfileColumns.CONTENT, profile); values.put(BaseColumns.COLUMN_STATE, SyncStates.PRUNE); getContext().getContentResolver().insert(SigarraContract.Profiles.CONTENT_URI, values); // Getting pic final ContentValues pic = new ContentValues(); final String picPath = getProfilePic(userCode, account, syncResult); if (picPath != null) { pic.put(SigarraContract.ProfileColumns.PIC, picPath); getContext().getContentResolver().update(SigarraContract.Profiles.PIC_CONTENT_URI, pic, SigarraContract.Profiles.PROFILE, SigarraContract.Profiles.getProfilePicSelectionArgs(userCode)); } syncResult.stats.numEntries += 1; } private void syncProfiles(Account account, SyncResult syncResult) throws AuthenticationException, IOException, JSONException { final User user = AccountUtils.getUser(getContext(), account.name); final String profile; if (user.getType().equals(SifeupAPI.STUDENT_TYPE)) { profile = SifeupAPI.getReply(SifeupAPI.getStudenProfiletUrl(user.getUserCode()), account, getContext()); } else { profile = SifeupAPI.getReply(SifeupAPI.getEmployeeProfileUrl(user.getUserCode()), account, getContext()); } final String picPath = getProfilePic(user.getUserCode(), account, syncResult); final ContentValues values = new ContentValues(); values.put(SigarraContract.ProfileColumns.ID, user.getUserCode()); values.put(SigarraContract.ProfileColumns.CONTENT, profile); if (picPath != null) values.put(SigarraContract.ProfileColumns.PIC, picPath); values.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); getContext().getContentResolver().insert(SigarraContract.Profiles.CONTENT_URI, values); syncResult.stats.numEntries += 1; final Cursor c = getContext().getContentResolver().query(SigarraContract.Friends.CONTENT_URI, new String[] { SigarraContract.FriendsColumns.CODE_FRIEND, SigarraContract.FriendsColumns.TYPE_FRIEND }, SigarraContract.Friends.USER_FRIENDS, SigarraContract.Friends.getUserFriendsSelectionArgs(user.getUserCode()), null); try { if (c.moveToFirst()) { final ContentValues[] friends = new ContentValues[c.getCount()]; int i = 0; do { final ContentValues friendValues = new ContentValues(); final String friendCode = c .getString(c.getColumnIndex(SigarraContract.FriendsColumns.CODE_FRIEND)); final String friendPic = getProfilePic(friendCode, account, syncResult); friendValues.put(SigarraContract.ProfileColumns.ID, friendCode); final String friendType = c .getString(c.getColumnIndex(SigarraContract.FriendsColumns.TYPE_FRIEND)); final String friendPage; if (friendType.equals(SifeupAPI.STUDENT_TYPE)) { friendPage = SifeupAPI.getReply(SifeupAPI.getStudenProfiletUrl(friendCode), account, getContext()); } else { friendPage = SifeupAPI.getReply(SifeupAPI.getEmployeeProfileUrl(friendCode), account, getContext()); } friendValues.put(SigarraContract.ProfileColumns.CONTENT, friendPage); if (friendPic != null) friendValues.put(SigarraContract.ProfileColumns.PIC, friendPic); friendValues.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); friends[i++] = friendValues; } while (c.moveToNext()); getContext().getContentResolver().bulkInsert(SigarraContract.Profiles.CONTENT_URI, friends); syncResult.stats.numEntries += friends.length; } } finally { c.close(); } // Request sync for the contacts, if it is disabled in Settings // the sync won't be called ContentResolver.requestSync(account, ContactsContract.AUTHORITY, new Bundle()); } private void syncProfilePic(String userCode, Account account, SyncResult syncResult) throws AuthenticationException, IOException { final String picPath = getProfilePic(userCode, account, syncResult); if (picPath == null) return; final ContentValues values = new ContentValues(); values.put(SigarraContract.ProfileColumns.PIC, picPath); getContext().getContentResolver().update(SigarraContract.Profiles.PIC_CONTENT_URI, values, SigarraContract.Profiles.PROFILE, SigarraContract.Profiles.getProfilePicSelectionArgs(userCode)); } private String getProfilePic(String userCode, Account account, SyncResult syncResult) { final File f = FileUtils.getFile(getContext(), userCode); if (f == null) return null; Bitmap pic; try { pic = SifeupAPI.downloadBitmap(SifeupAPI.getPersonPicUrl(userCode), account, getContext()); if (pic == null) { return null; } FileUtils.writeFile(pic, f); return f.getAbsolutePath(); } catch (IOException e) { e.printStackTrace(); } catch (AuthenticationException e) { e.printStackTrace(); } return null; } private void getSubject(Account account, String code, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); if (TextUtils.isEmpty(code)) { if (user.getType().equals(SifeupAPI.STUDENT_TYPE)) syncSubjects(account, syncResult); else syncTeachingService(account, syncResult); return; } final String subjectContent = SifeupAPI.getReply(SifeupAPI.getSubjectProfileUrl(code), account, getContext()); final String subjectFiles = SifeupAPI.getReply(SifeupAPI.getSubjectFilestUrl(code), account, getContext()); final ContentValues values = new ContentValues(); values.put(SigarraContract.SubjectsColumns.USER_NAME, account.name); values.put(SigarraContract.SubjectsColumns.CODE, code); values.put(SigarraContract.SubjectsColumns.CONTENT, subjectContent); values.put(SigarraContract.SubjectsColumns.FILES, subjectFiles); values.put(BaseColumns.COLUMN_STATE, SyncStates.PRUNE); getContext().getContentResolver().insert(SigarraContract.Subjects.CONTENT_ITEM_URI, values); syncResult.stats.numEntries += 1; } private void syncSubjects(Account account, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); // Cleaning old values getContext().getContentResolver().delete(SigarraContract.Subjects.CONTENT_URI, SigarraContract.Subjects.USER_SUBJECTS, SigarraContract.Subjects.getUserSubjectsSelectionArgs(account.name)); final String subjectsPage = SifeupAPI.getReply(SifeupAPI.getStudentCurrentSubjectsUrl(user.getUserCode()), account, getContext()); final Gson gson = GsonUtils.getGson(); Type listType = new TypeToken<StudentCourse[]>() { }.getType(); final StudentCourse[] courses = gson.fromJson(subjectsPage, listType); if (courses == null) { syncResult.stats.numParseExceptions++; LogUtils.trackException(getContext(), new RuntimeException(), subjectsPage, true); return; } final List<ContentValues> values = new ArrayList<ContentValues>(); for (StudentCourse course : courses) { for (SubjectEntry subject : course.getSubjectEntries()) { final String subjectContent = SifeupAPI .getReply(SifeupAPI.getSubjectProfileUrl(subject.getOcorrid()), account, getContext()); final String subjectFiles = SifeupAPI.getReply(SifeupAPI.getSubjectFilestUrl(subject.getOcorrid()), account, getContext()); final ContentValues value = new ContentValues(); value.put(SigarraContract.SubjectsColumns.USER_NAME, account.name); value.put(SigarraContract.SubjectsColumns.CODE, subject.getOcorrid()); value.put(SigarraContract.SubjectsColumns.NAME_PT, subject.getUcurrnome()); value.put(SigarraContract.SubjectsColumns.NAME_EN, subject.getUcurrname()); value.put(SigarraContract.SubjectsColumns.PERIOD, subject.getPercodigo()); value.put(SigarraContract.SubjectsColumns.CONTENT, subjectContent); value.put(SigarraContract.SubjectsColumns.FILES, subjectFiles); value.put(SigarraContract.SubjectsColumns.COURSE_ID, course.getCourseId()); if (course.getCourseName() != null) value.put(SigarraContract.SubjectsColumns.COURSE_ACRONYM, course.getCourseAcronym() == null ? StringUtils.getAcronym(course.getCourseName()) : course.getCourseAcronym()); else value.put(SigarraContract.SubjectsColumns.COURSE_ACRONYM, course.getCourseTypeDesc()); value.put(SigarraContract.SubjectsColumns.COURSE_ENTRY, gson.toJson(subject)); value.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); values.add(value); } } if (values.size() > 0) getContext().getContentResolver().bulkInsert(SigarraContract.Subjects.CONTENT_URI, values.toArray(new ContentValues[0])); else { SigarraProvider.updateLastSyncState(getContext(), SubjectsTable.TABLE); getContext().getContentResolver().notifyChange(SigarraContract.Subjects.CONTENT_URI, null); } syncResult.stats.numEntries += values.size(); } private void syncTeachingService(Account account, SyncResult syncResult) throws JSONException, AuthenticationException, IOException { final User user = AccountUtils.getUser(getContext(), account.name); final String teachingServicePage = SifeupAPI .getReply(SifeupAPI.getTeachingServiceUrl(user.getUserCode(), null), account, getContext()); final TeachingService service = GsonUtils.getGson().fromJson(teachingServicePage, TeachingService.class); if (service == null) { syncResult.stats.numParseExceptions++; LogUtils.trackException(getContext(), new RuntimeException(), teachingServicePage, true); return; } final ContentValues teachingValue = new ContentValues(); teachingValue.put(SigarraContract.TeachingService.ID, account.name); teachingValue.put(SigarraContract.TeachingService.CONTENT, teachingServicePage); getContext().getContentResolver().insert(SigarraContract.TeachingService.CONTENT_URI, teachingValue); final List<ContentValues> values = new ArrayList<ContentValues>(); for (Subject subject : service.getService()) { final String subjectContent = SifeupAPI.getReply(SifeupAPI.getSubjectProfileUrl(subject.getOcorrId()), account, getContext()); final String subjectFiles = SifeupAPI.getReply(SifeupAPI.getSubjectFilestUrl(subject.getOcorrId()), account, getContext()); final ContentValues value = new ContentValues(); value.put(SigarraContract.SubjectsColumns.USER_NAME, account.name); value.put(SigarraContract.SubjectsColumns.CODE, subject.getOcorrId()); value.put(SigarraContract.SubjectsColumns.NAME_PT, subject.getUcurrName()); value.put(SigarraContract.SubjectsColumns.PERIOD, subject.getPeriodCode()); value.put(SigarraContract.SubjectsColumns.CONTENT, subjectContent); value.put(SigarraContract.SubjectsColumns.FILES, subjectFiles); value.put(SigarraContract.SubjectsColumns.COURSE_ACRONYM, subject.getCourse()); value.put(BaseColumns.COLUMN_STATE, SyncStates.KEEP); values.add(value); } if (values.size() > 0) getContext().getContentResolver().bulkInsert(SigarraContract.Subjects.CONTENT_URI, values.toArray(new ContentValues[0])); syncResult.stats.numEntries += values.size(); } }