@Override public void process(JsonElement element) { for (Video video : new Gson().fromJson(element, Video[].class)) { if (TextUtils.isEmpty(video.id)) { LOGW(TAG, "Video without valid ID. Using VID instead: " + video.vid); video.id = video.vid; } mVideos.put(video.id, video); } }
@Override public void makeContentProviderOperations(ArrayList<ContentProviderOperation> list) { Uri uri = ScheduleContractHelper.setUriAsCalledFromSyncAdapter(ScheduleContract.Videos.CONTENT_URI); HashMap<String, String> videoHashcodes = loadVideoHashcodes(); HashSet<String> videosToKeep = new HashSet<String>(); boolean isIncrementalUpdate = videoHashcodes != null && videoHashcodes.size() > 0; if (isIncrementalUpdate) { LOGD(TAG, "Doing incremental update for videos."); } else { LOGD(TAG, "Doing FULL (non incremental) update for videos."); list.add(ContentProviderOperation.newDelete(uri).build()); } int updatedVideos = 0; for (Video video : mVideos.values()) { String hashCode = video.getImportHashcode(); videosToKeep.add(video.id); // add video, if necessary if (!isIncrementalUpdate || !videoHashcodes.containsKey(video.id) || !videoHashcodes.get(video.id).equals(hashCode)) { ++updatedVideos; boolean isNew = !isIncrementalUpdate || !videoHashcodes.containsKey(video.id); buildVideo(isNew, video, list); } } int deletedVideos = 0; if (isIncrementalUpdate) { for (String videoId : videoHashcodes.keySet()) { if (!videosToKeep.contains(videoId)) { buildDeleteOperation(videoId, list); ++deletedVideos; } } } LOGD( TAG, "Videos: " + (isIncrementalUpdate ? "INCREMENTAL" : "FULL") + " update. " + updatedVideos + " to update, " + deletedVideos + " to delete. New total: " + mVideos.size()); }
private void buildVideo(boolean isInsert, Video video, ArrayList<ContentProviderOperation> list) { Uri allVideosUri = ScheduleContractHelper.setUriAsCalledFromSyncAdapter(ScheduleContract.Videos.CONTENT_URI); Uri thisVideoUri = ScheduleContractHelper.setUriAsCalledFromSyncAdapter( ScheduleContract.Videos.buildVideoUri(video.id)); ContentProviderOperation.Builder builder; if (isInsert) { builder = ContentProviderOperation.newInsert(allVideosUri); } else { builder = ContentProviderOperation.newUpdate(thisVideoUri); } if (TextUtils.isEmpty(video.vid)) { LOGW(TAG, "Ignoring video with missing video ID."); return; } String thumbUrl = video.thumbnailUrl; if (TextUtils.isEmpty(thumbUrl)) { // Oops, missing thumbnail URL. Let's improvise. // NOTE: this method of obtaining a thumbnail URL from the video ID // is unofficial and might not work in the future; that's why we use // it only as a fallback in case we don't get a thumbnail URL in the incoming data. thumbUrl = String.format(Locale.US, Config.VIDEO_LIBRARY_FALLBACK_THUMB_URL_FMT, video.vid); LOGW(TAG, "Video with missing thumbnail URL: " + video.vid + ". Using fallback: " + thumbUrl); } list.add( builder .withValue(ScheduleContract.Videos.VIDEO_ID, video.id) .withValue(ScheduleContract.Videos.VIDEO_YEAR, video.year) .withValue(ScheduleContract.Videos.VIDEO_TITLE, video.title.trim()) .withValue(ScheduleContract.Videos.VIDEO_DESC, video.desc) .withValue(ScheduleContract.Videos.VIDEO_VID, video.vid) .withValue(ScheduleContract.Videos.VIDEO_TOPIC, video.topic) .withValue(ScheduleContract.Videos.VIDEO_SPEAKERS, video.speakers) .withValue(ScheduleContract.Videos.VIDEO_THUMBNAIL_URL, thumbUrl) .withValue(ScheduleContract.Videos.VIDEO_IMPORT_HASHCODE, video.getImportHashcode()) .build()); }