List of usage examples for android.content ContentProviderOperation newUpdate
public static Builder newUpdate(Uri uri)
From source file:org.mythtv.service.dvr.v26.RecordedHelperV26.java
private void processProgramGroups(final Context context, final LocationProfile locationProfile, Program[] programs) throws RemoteException, OperationApplicationException { Log.v(TAG, "processProgramGroups : enter"); if (null == context) throw new RuntimeException("RecordedHelperV26 is not initialized"); Map<String, ProgramGroup> programGroups = new TreeMap<String, ProgramGroup>(); for (Program program : programs) { if (null != program.getRecording()) { if (null != program.getRecording().getRecGroup() && !"livetv".equalsIgnoreCase(program.getRecording().getRecGroup()) && !"deleted".equalsIgnoreCase(program.getRecording().getRecGroup())) { String cleaned = ArticleCleaner.clean(program.getTitle()); if (!programGroups.containsKey(cleaned)) { ProgramGroup programGroup = new ProgramGroup(); programGroup.setTitle(program.getTitle()); programGroup.setCategory(program.getCategory()); programGroup.setInetref(program.getInetref()); programGroup.setSort(0); programGroups.put(cleaned, programGroup); }/* w ww . j a v a 2 s. com*/ } } } int processed = -1; int count = 0; ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); Log.v(TAG, "processProgramGroups : adding 'All' program group in programGroups"); ProgramGroup all = new ProgramGroup(null, "All", "All", "All", "", 1); programGroups.put(all.getProgramGroup(), all); String[] programGroupProjection = new String[] { ProgramGroupConstants._ID }; String programGroupSelection = ProgramGroupConstants.FIELD_PROGRAM_GROUP + " = ?"; programGroupSelection = appendLocationHostname(context, locationProfile, programGroupSelection, null); for (String key : programGroups.keySet()) { Log.v(TAG, "processProgramGroups : processing programGroup '" + key + "'"); ProgramGroup programGroup = programGroups.get(key); ContentValues programValues = convertProgramGroupToContentValues(locationProfile, programGroup); Cursor programGroupCursor = context.getContentResolver().query(ProgramGroupConstants.CONTENT_URI, programGroupProjection, programGroupSelection, new String[] { key }, null); if (programGroupCursor.moveToFirst()) { Long id = programGroupCursor .getLong(programGroupCursor.getColumnIndexOrThrow(ProgramGroupConstants._ID)); ops.add(ContentProviderOperation .newUpdate(ContentUris.withAppendedId(ProgramGroupConstants.CONTENT_URI, id)) .withValues(programValues).withYieldAllowed(true).build()); } else { ops.add(ContentProviderOperation.newInsert(ProgramGroupConstants.CONTENT_URI) .withValues(programValues).withYieldAllowed(true).build()); } programGroupCursor.close(); count++; if (count > 100) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } } if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : remove deleted program groups"); ops = new ArrayList<ContentProviderOperation>(); DateTime lastModified = new DateTime(); lastModified = lastModified.minusHours(1); String deleteProgramGroupSelection = ProgramGroupConstants.FIELD_LAST_MODIFIED_DATE + " < ?"; String[] deleteProgramGroupArgs = new String[] { String.valueOf(lastModified.getMillis()) }; deleteProgramGroupSelection = appendLocationHostname(context, locationProfile, deleteProgramGroupSelection, ProgramGroupConstants.TABLE_NAME); ops.add(ContentProviderOperation.newDelete(ProgramGroupConstants.CONTENT_URI) .withSelection(deleteProgramGroupSelection, deleteProgramGroupArgs).withYieldAllowed(true).build()); if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : exit"); }
From source file:edu.mit.mobile.android.locast.sync.SyncEngine.java
/** * @param toSync/*from w w w . j av a 2s. com*/ * @param account * @param extras * @param provider * @param syncResult * @return true if the item was sync'd successfully. Soft errors will cause this to return * false. * @throws RemoteException * @throws SyncException * @throws JSONException * @throws IOException * @throws NetworkProtocolException * @throws NoPublicPath * @throws OperationApplicationException * @throws InterruptedException */ public boolean sync(Uri toSync, Account account, Bundle extras, ContentProviderClient provider, SyncResult syncResult) throws RemoteException, SyncException, JSONException, IOException, NetworkProtocolException, NoPublicPath, OperationApplicationException, InterruptedException { String pubPath = null; // // Handle http or https uris separately. These require the // destination uri. // if ("http".equals(toSync.getScheme()) || "https".equals(toSync.getScheme())) { pubPath = toSync.toString(); if (!extras.containsKey(EXTRA_DESTINATION_URI)) { throw new IllegalArgumentException("missing EXTRA_DESTINATION_URI when syncing HTTP URIs"); } toSync = Uri.parse(extras.getString(EXTRA_DESTINATION_URI)); } final String type = provider.getType(toSync); final boolean isDir = type.startsWith(CONTENT_TYPE_PREFIX_DIR); final boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false); // skip any items already sync'd if (!manualSync && mLastUpdated.isUpdatedRecently(toSync)) { if (DEBUG) { Log.d(TAG, "not syncing " + toSync + " as it's been updated recently"); } syncResult.stats.numSkippedEntries++; return false; } // the sync map will convert the json data to ContentValues final SyncMap syncMap = MediaProvider.getSyncMap(provider, toSync); final Uri toSyncWithoutQuerystring = toSync.buildUpon().query(null).build(); final HashMap<String, SyncStatus> syncStatuses = new HashMap<String, SyncEngine.SyncStatus>(); final ArrayList<ContentProviderOperation> cpo = new ArrayList<ContentProviderOperation>(); final LinkedList<String> cpoPubUris = new LinkedList<String>(); // // first things first, upload any content that needs to be // uploaded. // try { uploadUnpublished(toSync, account, provider, syncMap, syncStatuses, syncResult); if (Thread.interrupted()) { throw new InterruptedException(); } // this should ensure that all items have a pubPath when we // query it below. if (pubPath == null) { // we should avoid calling this too much as it // can be expensive pubPath = MediaProvider.getPublicPath(mContext, toSync); } } catch (final NoPublicPath e) { // TODO this is a special case and this is probably not the best place to handle this. // Ideally, this should be done in such a way as to reduce any extra DB queries - // perhaps by doing a join with the parent. if (syncMap.isFlagSet(SyncMap.FLAG_PARENT_MUST_SYNC_FIRST)) { if (DEBUG) { Log.d(TAG, "skipping " + toSync + " whose parent hasn't been sync'd first"); } syncResult.stats.numSkippedEntries++; return false; } // if it's an item, we can handle it. if (isDir) { throw e; } } if (pubPath == null) { // this should have been updated already by the initial // upload, so something must be wrong throw new SyncException("never got a public path for " + toSync); } if (DEBUG) { Log.d(TAG, "sync(toSync=" + toSync + ", account=" + account + ", extras=" + extras + ", manualSync=" + manualSync + ",...)"); Log.d(TAG, "pubPath: " + pubPath); } final long request_time = System.currentTimeMillis(); HttpResponse hr = mNetworkClient.get(pubPath); final long response_time = System.currentTimeMillis(); // the time compensation below allows a time-based synchronization to function even if the // local clock is entirely wrong. The server's time is extracted using the Date header and // all are compared relative to the respective clock reference. Any data that's stored on // the mobile should be stored relative to the local clock and the server will respect the // same. long serverTime; try { serverTime = getServerTime(hr); } catch (final DateParseException e) { Log.w(TAG, "could not retrieve date from server. Using local time, which may be incorrect.", e); serverTime = System.currentTimeMillis(); } // TODO check out // http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html final long response_delay = response_time - request_time; if (DEBUG) { Log.d(TAG, "request took " + response_delay + "ms"); } final long localTime = request_time; // add this to the server time to get the local time final long localOffset = (localTime - serverTime); if (Math.abs(localOffset) > 30 * 60 * 1000) { Log.w(TAG, "local clock is off by " + localOffset + "ms"); } if (Thread.interrupted()) { throw new InterruptedException(); } final HttpEntity ent = hr.getEntity(); String selection; String selectionInverse; String[] selectionArgs; if (isDir) { final JSONArray ja = new JSONArray(StreamUtils.inputStreamToString(ent.getContent())); ent.consumeContent(); final int len = ja.length(); selectionArgs = new String[len]; // build the query to see which items are already in the // database final StringBuilder sb = new StringBuilder(); sb.append("("); for (int i = 0; i < len; i++) { if (Thread.interrupted()) { throw new InterruptedException(); } final SyncStatus syncStatus = loadItemFromJsonObject(ja.getJSONObject(i), syncMap, serverTime); syncStatuses.put(syncStatus.remote, syncStatus); selectionArgs[i] = syncStatus.remote; // add in a placeholder for the query sb.append('?'); if (i != (len - 1)) { sb.append(','); } } sb.append(")"); final String placeholders = sb.toString(); selection = JsonSyncableItem._PUBLIC_URI + " IN " + placeholders; selectionInverse = JsonSyncableItem._PUBLIC_URI + " NOT IN " + placeholders; } else { final JSONObject jo = new JSONObject(StreamUtils.inputStreamToString(ent.getContent())); ent.consumeContent(); final SyncStatus syncStatus = loadItemFromJsonObject(jo, syncMap, serverTime); syncStatuses.put(syncStatus.remote, syncStatus); selection = JsonSyncableItem._PUBLIC_URI + "=?"; selectionInverse = JsonSyncableItem._PUBLIC_URI + "!=?"; selectionArgs = new String[] { syncStatus.remote }; } // first check without the querystring. This will ensure that we // properly mark things that we already have in the database. final Cursor check = provider.query(toSyncWithoutQuerystring, SYNC_PROJECTION, selection, selectionArgs, null); // these items are on both sides try { final int pubUriCol = check.getColumnIndex(JsonSyncableItem._PUBLIC_URI); final int idCol = check.getColumnIndex(JsonSyncableItem._ID); // All the items in this cursor should be found on both // the client and the server. for (check.moveToFirst(); !check.isAfterLast(); check.moveToNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } final long id = check.getLong(idCol); final Uri localUri = ContentUris.withAppendedId(toSync, id); final String pubUri = check.getString(pubUriCol); final SyncStatus itemStatus = syncStatuses.get(pubUri); itemStatus.state = SyncState.BOTH_UNKNOWN; itemStatus.local = localUri; // make the status searchable by both remote and // local uri syncStatuses.put(localUri.toString(), itemStatus); } } finally { check.close(); } Cursor c = provider.query(toSync, SYNC_PROJECTION, selection, selectionArgs, null); // these items are on both sides try { final int pubUriCol = c.getColumnIndex(JsonSyncableItem._PUBLIC_URI); final int localModifiedCol = c.getColumnIndex(JsonSyncableItem._MODIFIED_DATE); final int serverModifiedCol = c.getColumnIndex(JsonSyncableItem._SERVER_MODIFIED_DATE); final int idCol = c.getColumnIndex(JsonSyncableItem._ID); // All the items in this cursor should be found on both // the client and the server. for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { if (Thread.interrupted()) { throw new InterruptedException(); } final long id = c.getLong(idCol); final Uri localUri = ContentUris.withAppendedId(toSync, id); final String pubUri = c.getString(pubUriCol); final SyncStatus itemStatus = syncStatuses.get(pubUri); if (itemStatus.state == SyncState.ALREADY_UP_TO_DATE || itemStatus.state == SyncState.NOW_UP_TO_DATE) { if (DEBUG) { Log.d(TAG, localUri + "(" + pubUri + ")" + " is already up to date."); } continue; } itemStatus.local = localUri; // make the status searchable by both remote and local uri syncStatuses.put(localUri.toString(), itemStatus); // last modified as stored in the DB, in phone time final long itemLocalModified = c.getLong(localModifiedCol); // last modified as stored in the DB, in server time final long itemServerModified = c.getLong(serverModifiedCol); final long localAge = localTime - itemLocalModified; final long remoteAge = serverTime - itemStatus.remoteModifiedTime; final long ageDifference = Math.abs(localAge - remoteAge); // up to date, as far remote -> local goes if (itemServerModified == itemStatus.remoteModifiedTime) { itemStatus.state = SyncState.ALREADY_UP_TO_DATE; if (DEBUG) { Log.d(TAG, pubUri + " is up to date."); } // need to download } else if (localAge > remoteAge) { if (DEBUG) { final long serverModified = itemStatus.remoteModifiedTime; Log.d(TAG, pubUri + " : local is " + ageDifference + "ms older (" + android.text.format.DateUtils.formatDateTime(mContext, itemLocalModified, FORMAT_ARGS_DEBUG) + ") than remote (" + android.text.format.DateUtils.formatDateTime(mContext, serverModified, FORMAT_ARGS_DEBUG) + "); updating local copy..."); } itemStatus.state = SyncState.REMOTE_DIRTY; final ContentProviderOperation.Builder b = ContentProviderOperation.newUpdate(localUri); // update this so it's in the local timescale correctServerOffset(itemStatus.remoteCVs, JsonSyncableItem._CREATED_DATE, JsonSyncableItem._CREATED_DATE, localOffset); correctServerOffset(itemStatus.remoteCVs, JsonSyncableItem._SERVER_MODIFIED_DATE, JsonSyncableItem._MODIFIED_DATE, localOffset); b.withValues(itemStatus.remoteCVs); b.withExpectedCount(1); cpo.add(b.build()); cpoPubUris.add(pubUri); syncResult.stats.numUpdates++; // need to upload } else if (localAge < remoteAge) { if (DEBUG) { final long serverModified = itemStatus.remoteModifiedTime; Log.d(TAG, pubUri + " : local is " + ageDifference + "ms newer (" + android.text.format.DateUtils.formatDateTime(mContext, itemLocalModified, FORMAT_ARGS_DEBUG) + ") than remote (" + android.text.format.DateUtils.formatDateTime(mContext, serverModified, FORMAT_ARGS_DEBUG) + "); publishing to server..."); } itemStatus.state = SyncState.LOCAL_DIRTY; mNetworkClient.putJson(pubPath, JsonSyncableItem.toJSON(mContext, localUri, c, syncMap)); } mLastUpdated.markUpdated(localUri); syncResult.stats.numEntries++; } // end for } finally { c.close(); } /* * Apply updates in bulk */ if (cpo.size() > 0) { if (DEBUG) { Log.d(TAG, "applying " + cpo.size() + " bulk updates..."); } final ContentProviderResult[] r = provider.applyBatch(cpo); if (DEBUG) { Log.d(TAG, "Done applying updates. Running postSync handler..."); } for (int i = 0; i < r.length; i++) { final ContentProviderResult res = r[i]; final SyncStatus ss = syncStatuses.get(cpoPubUris.get(i)); if (ss == null) { Log.e(TAG, "can't get sync status for " + res.uri); continue; } syncMap.onPostSyncItem(mContext, account, ss.local, ss.remoteJson, res.count != null ? res.count == 1 : true); ss.state = SyncState.NOW_UP_TO_DATE; } if (DEBUG) { Log.d(TAG, "done running postSync handler."); } cpo.clear(); cpoPubUris.clear(); } if (Thread.interrupted()) { throw new InterruptedException(); } /* * Look through the SyncState.state values and find ones that need to be stored. */ for (final Map.Entry<String, SyncStatus> entry : syncStatuses.entrySet()) { if (Thread.interrupted()) { throw new InterruptedException(); } final String pubUri = entry.getKey(); final SyncStatus status = entry.getValue(); if (status.state == SyncState.REMOTE_ONLY) { if (DEBUG) { Log.d(TAG, pubUri + " is not yet stored locally, adding..."); } // update this so it's in the local timescale correctServerOffset(status.remoteCVs, JsonSyncableItem._CREATED_DATE, JsonSyncableItem._CREATED_DATE, localOffset); correctServerOffset(status.remoteCVs, JsonSyncableItem._SERVER_MODIFIED_DATE, JsonSyncableItem._MODIFIED_DATE, localOffset); final ContentProviderOperation.Builder b = ContentProviderOperation.newInsert(toSync); b.withValues(status.remoteCVs); cpo.add(b.build()); cpoPubUris.add(pubUri); syncResult.stats.numInserts++; } } /* * Execute the content provider operations in bulk. */ if (cpo.size() > 0) { if (DEBUG) { Log.d(TAG, "bulk inserting " + cpo.size() + " items..."); } final ContentProviderResult[] r = provider.applyBatch(cpo); if (DEBUG) { Log.d(TAG, "applyBatch completed. Processing results..."); } int successful = 0; for (int i = 0; i < r.length; i++) { final ContentProviderResult res = r[i]; if (res.uri == null) { syncResult.stats.numSkippedEntries++; Log.e(TAG, "result from content provider bulk operation returned null"); continue; } final String pubUri = cpoPubUris.get(i); final SyncStatus ss = syncStatuses.get(pubUri); if (ss == null) { syncResult.stats.numSkippedEntries++; Log.e(TAG, "could not find sync status for " + cpoPubUris.get(i)); continue; } ss.local = res.uri; if (DEBUG) { Log.d(TAG, "onPostSyncItem(" + res.uri + ", ...); pubUri: " + pubUri); } syncMap.onPostSyncItem(mContext, account, res.uri, ss.remoteJson, res.count != null ? res.count == 1 : true); ss.state = SyncState.NOW_UP_TO_DATE; successful++; } if (DEBUG) { Log.d(TAG, successful + " batch inserts successfully applied."); } } else { if (DEBUG) { Log.d(TAG, "no updates to perform."); } } /** * Look through all the items that we didn't already find on the server side, but which * still have a public uri. They should be checked to make sure they're not deleted. */ c = provider.query(toSync, SYNC_PROJECTION, ProviderUtils.addExtraWhere(selectionInverse, JsonSyncableItem._PUBLIC_URI + " NOT NULL"), selectionArgs, null); try { final int idCol = c.getColumnIndex(JsonSyncableItem._ID); final int pubUriCol = c.getColumnIndex(JsonSyncableItem._PUBLIC_URI); cpo.clear(); for (c.moveToFirst(); !c.isAfterLast(); c.moveToNext()) { final String pubUri = c.getString(pubUriCol); SyncStatus ss = syncStatuses.get(pubUri); final Uri item = isDir ? ContentUris.withAppendedId(toSyncWithoutQuerystring, c.getLong(idCol)) : toSync; if (ss == null) { ss = syncStatuses.get(item.toString()); } if (DEBUG) { Log.d(TAG, item + " was not found in the main list of items on the server (" + pubPath + "), but appears to be a child of " + toSync); if (ss != null) { Log.d(TAG, "found sync status for " + item + ": " + ss); } } if (ss != null) { switch (ss.state) { case ALREADY_UP_TO_DATE: case NOW_UP_TO_DATE: if (DEBUG) { Log.d(TAG, item + " is already up to date. No need to see if it was deleted."); } continue; case BOTH_UNKNOWN: if (DEBUG) { Log.d(TAG, item + " was found on both sides, but has an unknown sync status. Skipping..."); } continue; default: Log.w(TAG, "got an unexpected state for " + item + ": " + ss); } } else { ss = new SyncStatus(pubUri, SyncState.LOCAL_ONLY); ss.local = item; hr = mNetworkClient.head(pubUri); switch (hr.getStatusLine().getStatusCode()) { case 200: if (DEBUG) { Log.d(TAG, "HEAD " + pubUri + " returned 200"); } ss.state = SyncState.BOTH_UNKNOWN; break; case 404: if (DEBUG) { Log.d(TAG, "HEAD " + pubUri + " returned 404. Deleting locally..."); } ss.state = SyncState.DELETED_REMOTELY; final ContentProviderOperation deleteOp = ContentProviderOperation .newDelete(ContentUris.withAppendedId(toSyncWithoutQuerystring, c.getLong(idCol))) .build(); cpo.add(deleteOp); break; default: syncResult.stats.numIoExceptions++; Log.w(TAG, "HEAD " + pubUri + " got unhandled result: " + hr.getStatusLine()); } } syncStatuses.put(pubUri, ss); } // for cursor if (cpo.size() > 0) { final ContentProviderResult[] results = provider.applyBatch(cpo); for (final ContentProviderResult result : results) { if (result.count != 1) { throw new SyncException("Error deleting item"); } } } } finally { c.close(); } syncStatuses.clear(); mLastUpdated.markUpdated(toSync); return true; }
From source file:org.mythtv.service.dvr.v25.RecordedHelperV25.java
private void processProgramGroups(final Context context, final LocationProfile locationProfile, Program[] programs) throws RemoteException, OperationApplicationException { Log.v(TAG, "processProgramGroups : enter"); if (null == context) throw new RuntimeException("RecordedHelperV25 is not initialized"); Map<String, ProgramGroup> programGroups = new TreeMap<String, ProgramGroup>(); for (Program program : programs) { if (null != program.getRecording()) { if (null != program.getRecording().getRecGroup() && !"livetv".equalsIgnoreCase(program.getRecording().getRecGroup()) && !"deleted".equalsIgnoreCase(program.getRecording().getRecGroup())) { String cleaned = ArticleCleaner.clean(program.getTitle()); if (!programGroups.containsKey(cleaned)) { ProgramGroup programGroup = new ProgramGroup(); programGroup.setTitle(program.getTitle()); programGroup.setCategory(program.getCategory()); programGroup.setInetref(program.getInetref()); programGroup.setSort(0); programGroups.put(cleaned, programGroup); }//from w w w . jav a2 s.com } } } int processed = -1; int count = 0; ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); Log.v(TAG, "processProgramGroups : adding 'All' program group in programGroups"); ProgramGroup all = new ProgramGroup(null, "All", "All", "All", "", 1); programGroups.put(all.getProgramGroup(), all); String[] programGroupProjection = new String[] { ProgramGroupConstants._ID }; String programGroupSelection = ProgramGroupConstants.FIELD_PROGRAM_GROUP + " = ?"; programGroupSelection = appendLocationHostname(context, locationProfile, programGroupSelection, null); for (String key : programGroups.keySet()) { Log.v(TAG, "processProgramGroups : processing programGroup '" + key + "'"); ProgramGroup programGroup = programGroups.get(key); ContentValues programValues = convertProgramGroupToContentValues(locationProfile, programGroup); Cursor programGroupCursor = context.getContentResolver().query(ProgramGroupConstants.CONTENT_URI, programGroupProjection, programGroupSelection, new String[] { key }, null); if (programGroupCursor.moveToFirst()) { Long id = programGroupCursor .getLong(programGroupCursor.getColumnIndexOrThrow(ProgramGroupConstants._ID)); ops.add(ContentProviderOperation .newUpdate(ContentUris.withAppendedId(ProgramGroupConstants.CONTENT_URI, id)) .withValues(programValues).withYieldAllowed(true).build()); } else { ops.add(ContentProviderOperation.newInsert(ProgramGroupConstants.CONTENT_URI) .withValues(programValues).withYieldAllowed(true).build()); } programGroupCursor.close(); count++; if (count > 100) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } } if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : remove deleted program groups"); ops = new ArrayList<ContentProviderOperation>(); DateTime lastModified = new DateTime(); lastModified = lastModified.minusHours(1); String deleteProgramGroupSelection = ProgramGroupConstants.FIELD_LAST_MODIFIED_DATE + " < ?"; String[] deleteProgramGroupArgs = new String[] { String.valueOf(lastModified.getMillis()) }; deleteProgramGroupSelection = appendLocationHostname(context, locationProfile, deleteProgramGroupSelection, ProgramGroupConstants.TABLE_NAME); ops.add(ContentProviderOperation.newDelete(ProgramGroupConstants.CONTENT_URI) .withSelection(deleteProgramGroupSelection, deleteProgramGroupArgs).withYieldAllowed(true).build()); if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : exit"); }
From source file:org.totschnig.myexpenses.model.Account.java
/** * deletes all expenses and updates account according to value of handleDelete * * @param filter if not null only expenses matched by filter will be deleted * @param handleDelete if equals {@link #EXPORT_HANDLE_DELETED_UPDATE_BALANCE} opening balance will * be adjusted to account for the deleted expenses, * if equals {@link #EXPORT_HANDLE_DELETED_CREATE_HELPER} a helper transaction * @param helperComment/*from w ww . j a v a 2s . c om*/ */ public void reset(WhereFilter filter, int handleDelete, String helperComment) { ArrayList<ContentProviderOperation> ops = new ArrayList<>(); ContentProviderOperation handleDeleteOperation = null; if (handleDelete == EXPORT_HANDLE_DELETED_UPDATE_BALANCE) { long currentBalance = getFilteredBalance(filter).getAmountMinor(); openingBalance.setAmountMinor(currentBalance); handleDeleteOperation = ContentProviderOperation .newUpdate(CONTENT_URI.buildUpon().appendPath(String.valueOf(getId())).build()) .withValue(KEY_OPENING_BALANCE, currentBalance).build(); } else if (handleDelete == EXPORT_HANDLE_DELETED_CREATE_HELPER) { Transaction helper = new Transaction(this, getTransactionSum(filter)); helper.comment = helperComment; helper.status = STATUS_HELPER; handleDeleteOperation = ContentProviderOperation.newInsert(Transaction.CONTENT_URI) .withValues(helper.buildInitialValues()).build(); } String rowSelect = buildTransactionRowSelect(filter); String[] selectionArgs = new String[] { String.valueOf(getId()) }; if (filter != null && !filter.isEmpty()) { selectionArgs = Utils.joinArrays(selectionArgs, filter.getSelectionArgs(false)); } ops.add(updateTransferPeersForTransactionDelete(rowSelect, selectionArgs)); ops.add(ContentProviderOperation.newDelete(Transaction.CONTENT_URI) .withSelection(KEY_ROWID + " IN (" + rowSelect + ")", selectionArgs).build()); //needs to be last, otherwise helper transaction would be deleted if (handleDeleteOperation != null) ops.add(handleDeleteOperation); try { cr().applyBatch(TransactionProvider.AUTHORITY, ops); } catch (Exception e) { AcraHelper.report(e); e.printStackTrace(); } }
From source file:com.appsimobile.appsii.module.home.HomeAdapter.java
private void fixHomeItemRows(List<HomeItem> homeItems) { int lastRowPosition = -1; int newRowIdx = 0; int N = homeItems.size(); ArrayList<ContentProviderOperation> ops = new ArrayList<>(8); boolean done; for (int i = 0; i < N; i++) { HomeItem item = homeItems.get(i); done = false;/*from w ww. j a v a 2s . c o m*/ if (lastRowPosition == -1 || lastRowPosition != item.mRowPosition) { lastRowPosition = item.mRowPosition; Uri uri = ContentUris.withAppendedId(HomeContract.Rows.CONTENT_URI, item.mRowId); ops.add(ContentProviderOperation.newUpdate(uri).withValue(HomeContract.Rows.POSITION, newRowIdx) .build()); newRowIdx++; done = true; } // handle the last row if (i == mHomeItems.size() - 1 && !done) { Uri uri = ContentUris.withAppendedId(HomeContract.Rows.CONTENT_URI, item.mRowId); ops.add(ContentProviderOperation.newUpdate(uri).withValue(HomeContract.Rows.POSITION, newRowIdx) .build()); } } try { mContext.getContentResolver().applyBatch(HomeContract.AUTHORITY, ops); } catch (RemoteException | OperationApplicationException e) { Log.w("HomeAdapter", "error fixing bad row numbers", e); } }
From source file:org.voidsink.anewjkuapp.update.ImportCalendarTask.java
@Override public Void call() throws Exception { if (mProvider == null) { return null; }/*from www. j a v a 2 s.c om*/ if ((ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) || (ContextCompat.checkSelfPermission(mContext, Manifest.permission.READ_CALENDAR) != PackageManager.PERMISSION_GRANTED)) { return null; } if (!CalendarUtils.getSyncCalendar(mContext, this.mCalendarName)) { return null; } if (mShowProgress) { mUpdateNotification = new SyncNotification(mContext, R.string.notification_sync_calendar); mUpdateNotification.show(mContext.getString(R.string.notification_sync_calendar_loading, CalendarUtils.getCalendarName(mContext, this.mCalendarName))); } CalendarChangedNotification mNotification = new CalendarChangedNotification(mContext, CalendarUtils.getCalendarName(mContext, this.mCalendarName)); try { Log.d(TAG, "setup connection"); updateNotify(mContext.getString(R.string.notification_sync_connect)); if (KusssHandler.getInstance().isAvailable(mContext, AppUtils.getAccountAuthToken(mContext, mAccount), AppUtils.getAccountName(mContext, mAccount), AppUtils.getAccountPassword(mContext, mAccount))) { updateNotify(mContext.getString(R.string.notification_sync_calendar_loading, CalendarUtils.getCalendarName(mContext, this.mCalendarName))); Log.d(TAG, "loading calendar"); Calendar iCal; String kusssIdPrefix; // {{ Load calendar events from resource switch (this.mCalendarName) { case CalendarUtils.ARG_CALENDAR_EXAM: iCal = KusssHandler.getInstance().getExamIcal(mContext, mCalendarBuilder); kusssIdPrefix = "at-jku-kusss-exam-"; break; case CalendarUtils.ARG_CALENDAR_COURSE: iCal = KusssHandler.getInstance().getLVAIcal(mContext, mCalendarBuilder); kusssIdPrefix = "at-jku-kusss-coursedate-"; break; default: { Log.w(TAG, "calendar not found: " + this.mCalendarName); return null; } } if (iCal == null) { Log.w(TAG, "calendar not loaded: " + this.mCalendarName); mSyncResult.stats.numParseExceptions++; return null; } List<?> events = iCal.getComponents(Component.VEVENT); Log.d(TAG, String.format("got %d events", events.size())); updateNotify(mContext.getString(R.string.notification_sync_calendar_updating, CalendarUtils.getCalendarName(mContext, this.mCalendarName))); ArrayList<ContentProviderOperation> batch = new ArrayList<>(); // modify events: move courseId/term and lecturer to description String lineSeparator = System.getProperty("line.separator"); if (lineSeparator == null) lineSeparator = ", "; Map<String, VEvent> eventsMap = new HashMap<>(); for (Object e : events) { if (VEvent.class.isInstance(e)) { VEvent ev = ((VEvent) e); String summary = ev.getSummary().getValue().trim(); String description = ev.getDescription().getValue().trim(); Matcher courseIdTermMatcher = courseIdTermPattern.matcher(summary); // (courseId/term) if (courseIdTermMatcher.find()) { if (!description.isEmpty()) { description += lineSeparator; description += lineSeparator; } description += summary.substring(courseIdTermMatcher.start()); summary = summary.substring(0, courseIdTermMatcher.start()); } else { Matcher lecturerMatcher = lecturerPattern.matcher(summary); if (lecturerMatcher.find()) { if (!description.isEmpty()) { description += lineSeparator; description += lineSeparator; } description += summary.substring(lecturerMatcher.start()); summary = summary.substring(0, lecturerMatcher.start()); } } summary = summary.trim().replaceAll("([\\r\\n]|\\\\n)+", ", ").trim(); description = description.trim(); ev.getProperty(Property.SUMMARY).setValue(summary); ev.getProperty(Property.DESCRIPTION).setValue(description); } } // Build hash table of incoming entries for (Object e : events) { if (VEvent.class.isInstance(e)) { VEvent ev = ((VEvent) e); String uid = ev.getUid().getValue(); // compense DST eventsMap.put(uid, ev); } } String calendarId = CalendarUtils.getCalIDByName(mContext, mAccount, mCalendarName, true); if (calendarId == null) { Log.w(TAG, "calendarId not found"); return null; } String mCalendarAccountName = mAccount.name; String mCalendarAccountType = mAccount.type; try { Cursor c = mProvider.query(CalendarContractWrapper.Calendars.CONTENT_URI(), CalendarUtils.CALENDAR_PROJECTION, null, null, null); if (c != null) { while (c.moveToNext()) { if (calendarId.equals(c.getString(CalendarUtils.COLUMN_CAL_ID))) { mCalendarAccountName = c.getString(CalendarUtils.COLUMN_CAL_ACCOUNT_NAME); mCalendarAccountType = c.getString(CalendarUtils.COLUMN_CAL_ACCOUNT_TYPE); break; } } c.close(); } } catch (Exception e) { return null; } Log.d(TAG, "Fetching local entries for merge with: " + calendarId); Uri calUri = CalendarContractWrapper.Events.CONTENT_URI(); Cursor c = CalendarUtils.loadEvent(mProvider, calUri, calendarId); if (c == null) { Log.w(TAG, "selection failed"); } else { Log.d(TAG, String.format("Found %d local entries. Computing merge solution...", c.getCount())); // find stale data String eventId; String eventKusssId; String eventLocation; String eventTitle; String eventDescription; long eventDTStart; long eventDTEnd; boolean eventDirty; boolean eventDeleted; // calc date for notifiying only future changes // max update interval is 1 week long notifyFrom = new Date().getTime() - (DateUtils.DAY_IN_MILLIS * 7); while (c.moveToNext()) { mSyncResult.stats.numEntries++; eventId = c.getString(CalendarUtils.COLUMN_EVENT_ID); // Log.d(TAG, "---------"); eventKusssId = null; // get kusssId from extended properties Cursor c2 = mProvider.query(CalendarContract.ExtendedProperties.CONTENT_URI, CalendarUtils.EXTENDED_PROPERTIES_PROJECTION, CalendarContract.ExtendedProperties.EVENT_ID + " = ?", new String[] { eventId }, null); if (c2 != null) { while (c2.moveToNext()) { // String extra = ""; // for (int i = 0; i < c2.getColumnCount(); i++) { // extra = extra + i + "=" + c2.getString(i) + ";"; // } // Log.d(TAG, "Extended: " + extra); if (c2.getString(1).contains(CalendarUtils.EXTENDED_PROPERTY_NAME_KUSSS_ID)) { eventKusssId = c2.getString(2); } } c2.close(); } if (TextUtils.isEmpty(eventKusssId)) { eventKusssId = c.getString(CalendarUtils.COLUMN_EVENT_KUSSS_ID_LEGACY); } eventTitle = c.getString(CalendarUtils.COLUMN_EVENT_TITLE); Log.d(TAG, "Title: " + eventTitle); eventLocation = c.getString(CalendarUtils.COLUMN_EVENT_LOCATION); eventDescription = c.getString(CalendarUtils.COLUMN_EVENT_DESCRIPTION); eventDTStart = c.getLong(CalendarUtils.COLUMN_EVENT_DTSTART); eventDTEnd = c.getLong(CalendarUtils.COLUMN_EVENT_DTEND); eventDirty = "1".equals(c.getString(CalendarUtils.COLUMN_EVENT_DIRTY)); eventDeleted = "1".equals(c.getString(CalendarUtils.COLUMN_EVENT_DELETED)); if (eventKusssId != null && kusssIdPrefix != null && eventKusssId.startsWith(kusssIdPrefix)) { VEvent match = eventsMap.get(eventKusssId); if (match != null && !eventDeleted) { // Entry exists. Remove from entry // map to prevent insert later eventsMap.remove(eventKusssId); // update only changes after notifiyFrom if ((match.getStartDate().getDate().getTime() > notifyFrom || eventDTStart > notifyFrom) && // check to see if the entry needs to be updated ((match.getStartDate().getDate().getTime() != eventDTStart) || (match.getEndDate().getDate().getTime() != eventDTEnd) || (!match.getSummary().getValue().trim().equals(eventTitle.trim())) || (!match.getSummary().getValue().trim().equals(eventTitle.trim())) || (!match.getLocation().getValue().trim() .equals(eventLocation.trim())) || (!match.getDescription().getValue().trim() .equals(eventDescription.trim())))) { Uri existingUri = calUri.buildUpon().appendPath(eventId).build(); // Update existing record Log.d(TAG, "Scheduling update: " + existingUri + " dirty=" + eventDirty); batch.add(ContentProviderOperation.newUpdate(existingUri) .withValues(getContentValuesFromEvent(match)).build()); mSyncResult.stats.numUpdates++; mNotification.addUpdate(getEventString(mContext, match)); } else { mSyncResult.stats.numSkippedEntries++; } } else { if (eventDTStart > (mSyncFromNow - DateUtils.DAY_IN_MILLIS)) { // Entry doesn't exist. Remove only newer events from the database. Uri deleteUri = calUri.buildUpon().appendPath(eventId).build(); Log.d(TAG, "Scheduling delete: " + deleteUri); // notify only future changes if (eventDTStart > notifyFrom && !eventDeleted) { mNotification.addDelete(AppUtils.getEventString(mContext, eventDTStart, eventDTEnd, eventTitle, false)); } batch.add(ContentProviderOperation.newDelete(deleteUri).build()); mSyncResult.stats.numDeletes++; } else { mSyncResult.stats.numSkippedEntries++; } } } else { Log.i(TAG, "Event UID not set, ignore event: uid=" + eventKusssId + " dirty=" + eventDirty + " title=" + eventTitle); } } c.close(); Log.d(TAG, String.format("Cursor closed, %d events left", eventsMap.size())); updateNotify(mContext.getString(R.string.notification_sync_calendar_adding, CalendarUtils.getCalendarName(mContext, this.mCalendarName))); // Add new items for (VEvent v : eventsMap.values()) { if (v.getUid().getValue().startsWith(kusssIdPrefix)) { // notify only future changes if (v.getStartDate().getDate().getTime() > notifyFrom) { mNotification.addInsert(getEventString(mContext, v)); } Builder builder = ContentProviderOperation .newInsert(CalendarContractWrapper.Events.CONTENT_URI()); builder.withValue(CalendarContractWrapper.Events.CALENDAR_ID(), calendarId) .withValues(getContentValuesFromEvent(v)) .withValue(CalendarContractWrapper.Events.EVENT_TIMEZONE(), TimeZone.getDefault().getID()); if (mCalendarName.equals(CalendarUtils.ARG_CALENDAR_EXAM)) { builder.withValue(CalendarContractWrapper.Events.AVAILABILITY(), CalendarContractWrapper.Events.AVAILABILITY_BUSY()); } else { builder.withValue(CalendarContractWrapper.Events.AVAILABILITY(), CalendarContractWrapper.Events.AVAILABILITY_FREE()); } builder.withValue(CalendarContract.Events.STATUS, CalendarContract.Events.STATUS_TENTATIVE); builder.withValue(CalendarContract.Events.HAS_ALARM, "0"); builder.withValue(CalendarContract.Events.HAS_ATTENDEE_DATA, "0"); builder.withValue(CalendarContract.Events.HAS_EXTENDED_PROPERTIES, "1"); ContentProviderOperation op = builder.build(); Log.d(TAG, "Scheduling insert: " + v.getUid().getValue()); batch.add(op); int eventIndex = batch.size() - 1; // add kusssid as extendet property batch.add(ContentProviderOperation .newInsert(KusssContentContract.asEventSyncAdapter( CalendarContract.ExtendedProperties.CONTENT_URI, mAccount.name, mAccount.type)) .withValueBackReference(CalendarContract.ExtendedProperties.EVENT_ID, eventIndex) .withValue(CalendarContract.ExtendedProperties.NAME, CalendarUtils.EXTENDED_PROPERTY_NAME_KUSSS_ID) .withValue(CalendarContract.ExtendedProperties.VALUE, v.getUid().getValue()) .build()); // add location extra for google maps batch.add(ContentProviderOperation .newInsert(KusssContentContract.asEventSyncAdapter( CalendarContract.ExtendedProperties.CONTENT_URI, mAccount.name, mAccount.type)) .withValueBackReference(CalendarContract.ExtendedProperties.EVENT_ID, eventIndex) .withValue(CalendarContract.ExtendedProperties.NAME, CalendarUtils.EXTENDED_PROPERTY_LOCATION_EXTRA) .withValue(CalendarContract.ExtendedProperties.VALUE, getLocationExtra(v)) .build()); mSyncResult.stats.numInserts++; } else { mSyncResult.stats.numSkippedEntries++; } } if (batch.size() > 0) { updateNotify(mContext.getString(R.string.notification_sync_calendar_saving, CalendarUtils.getCalendarName(mContext, this.mCalendarName))); Log.d(TAG, "Applying batch update"); mProvider.applyBatch(batch); Log.d(TAG, "Notify resolver"); mResolver.notifyChange(calUri.buildUpon().appendPath(calendarId).build(), // URI // where // data // was // modified null, // No local observer false); // IMPORTANT: Do not sync to // network } else { Log.w(TAG, "No batch operations found! Do nothing"); } } KusssHandler.getInstance().logout(mContext); } else { mSyncResult.stats.numAuthExceptions++; } } catch (Exception e) { Analytics.sendException(mContext, e, true); Log.e(TAG, "import calendar failed", e); } if (mUpdateNotification != null) { mUpdateNotification.cancel(); } mNotification.show(); if (mReleaseProvider) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { mProvider.close(); } else { mProvider.release(); } } return null; }
From source file:fr.mixit.android.io.JsonHandlerApplyMembers.java
private void parseSharedLinks(String itemId, JSONArray sharedLinks, ContentResolver resolver) throws JSONException { final HashSet<String> sharedLinksIds = Sets.newHashSet(); for (int j = 0; j < sharedLinks.length(); j++) { final JSONObject sharedLink = sharedLinks.getJSONObject(j); final String id = sharedLink.getString(TAG_ID); sharedLinksIds.add(id);//from www . j av a2 s .c o m final Uri sharedLinkUri = MixItContract.SharedLinks.buildSharedLinkUri(id); boolean sharedLinkUpdated = false; boolean newSharedLink = false; boolean build = false; ContentProviderOperation.Builder builder; if (ProviderParsingUtils.isRowExisting(sharedLinkUri, MixItContract.SharedLinks.PROJ.PROJECTION, resolver)) { builder = ContentProviderOperation.newUpdate(sharedLinkUri); sharedLinkUpdated = isSharedLinkUpdated(sharedLinkUri, itemId, sharedLink, resolver); } else { newSharedLink = true; builder = ContentProviderOperation.newInsert(MixItContract.SharedLinks.CONTENT_URI); builder.withValue(MixItContract.SharedLinks.SHARED_LINK_ID, id); build = true; } if (newSharedLink || sharedLinkUpdated) { if (sharedLink.has(TAG_ORDER_NUM)) { builder.withValue(MixItContract.SharedLinks.ORDER_NUM, sharedLink.getInt(TAG_ORDER_NUM)); } if (sharedLink.has(TAG_NAME)) { builder.withValue(MixItContract.SharedLinks.NAME, sharedLink.getString(TAG_NAME)); } if (sharedLink.has(TAG_URL)) { builder.withValue(MixItContract.SharedLinks.URL, sharedLink.getString(TAG_URL)); } builder.withValue(MixItContract.SharedLinks.MEMBER_ID, itemId); build = true; } if (build) { ProviderParsingUtils.addOpeAndApplyBatch(mAuthority, resolver, mBatch, false, builder.build()); } } mItemSharedLinksIds.put(itemId, sharedLinksIds); }
From source file:org.mythtv.service.dvr.v27.RecordedHelperV27.java
private void processProgramGroups(final Context context, final LocationProfile locationProfile, Program[] programs) throws RemoteException, OperationApplicationException { Log.v(TAG, "processProgramGroups : enter"); if (null == context) throw new RuntimeException("RecordedHelperV27 is not initialized"); Map<String, ProgramGroup> programGroups = new TreeMap<String, ProgramGroup>(); for (Program program : programs) { if (null != program.getRecording()) { if (null != program.getRecording().getRecGroup() && !"livetv".equalsIgnoreCase(program.getRecording().getRecGroup()) && !"deleted".equalsIgnoreCase(program.getRecording().getRecGroup())) { String cleaned = ArticleCleaner.clean(program.getTitle()); if (!programGroups.containsKey(cleaned)) { ProgramGroup programGroup = new ProgramGroup(); programGroup.setTitle(program.getTitle()); programGroup.setCategory(program.getCategory()); programGroup.setInetref(program.getInetref()); programGroup.setSort(0); programGroups.put(cleaned, programGroup); }/*from ww w . j a v a2s.c o m*/ } } } int processed = -1; int count = 0; ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>(); Log.v(TAG, "processProgramGroups : adding 'All' program group in programGroups"); ProgramGroup all = new ProgramGroup(null, "All", "All", "All", "", 1); programGroups.put(all.getProgramGroup(), all); String[] programGroupProjection = new String[] { ProgramGroupConstants._ID }; String programGroupSelection = ProgramGroupConstants.FIELD_PROGRAM_GROUP + " = ?"; programGroupSelection = appendLocationHostname(context, locationProfile, programGroupSelection, null); for (String key : programGroups.keySet()) { Log.v(TAG, "processProgramGroups : processing programGroup '" + key + "'"); ProgramGroup programGroup = programGroups.get(key); ContentValues programValues = convertProgramGroupToContentValues(locationProfile, programGroup); Cursor programGroupCursor = context.getContentResolver().query(ProgramGroupConstants.CONTENT_URI, programGroupProjection, programGroupSelection, new String[] { key }, null); if (programGroupCursor.moveToFirst()) { Long id = programGroupCursor .getLong(programGroupCursor.getColumnIndexOrThrow(ProgramGroupConstants._ID)); ops.add(ContentProviderOperation .newUpdate(ContentUris.withAppendedId(ProgramGroupConstants.CONTENT_URI, id)) .withValues(programValues).withYieldAllowed(true).build()); } else { ops.add(ContentProviderOperation.newInsert(ProgramGroupConstants.CONTENT_URI) .withValues(programValues).withYieldAllowed(true).build()); } programGroupCursor.close(); count++; if (count > 100) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } } if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : remove deleted program groups"); ops = new ArrayList<ContentProviderOperation>(); DateTime lastModified = new DateTime(); lastModified = lastModified.minusHours(1); String deleteProgramGroupSelection = ProgramGroupConstants.FIELD_LAST_MODIFIED_DATE + " < ?"; String[] deleteProgramGroupArgs = new String[] { String.valueOf(lastModified.getMillis()) }; deleteProgramGroupSelection = appendLocationHostname(context, locationProfile, deleteProgramGroupSelection, ProgramGroupConstants.TABLE_NAME); ops.add(ContentProviderOperation.newDelete(ProgramGroupConstants.CONTENT_URI) .withSelection(deleteProgramGroupSelection, deleteProgramGroupArgs).withYieldAllowed(true).build()); if (!ops.isEmpty()) { Log.v(TAG, "processProgramGroups : applying batch for '" + count + "' transactions"); processBatch(context, ops, processed, count); } Log.v(TAG, "processProgramGroups : exit"); }
From source file:nl.privacybarometer.privacyvandaag.service.FetcherService.java
private void mobilizeAllEntries() { ContentResolver cr = getContentResolver(); Cursor cursor = cr.query(TaskColumns.CONTENT_URI, new String[] { TaskColumns._ID, TaskColumns.ENTRY_ID, TaskColumns.NUMBER_ATTEMPT }, TaskColumns.IMG_URL_TO_DL + Constants.DB_IS_NULL, null, null); ArrayList<ContentProviderOperation> operations = new ArrayList<>(); while (cursor != null && cursor.moveToNext()) { long taskId = cursor.getLong(0); long entryId = cursor.getLong(1); int nbAttempt = 0; if (!cursor.isNull(2)) { nbAttempt = cursor.getInt(2); }//from ww w .j a v a2s . c o m boolean success = false; Uri entryUri = EntryColumns.CONTENT_URI(entryId); Cursor entryCursor = cr.query(entryUri, null, null, null, null); if (entryCursor != null && entryCursor.moveToFirst()) { if (entryCursor.isNull(entryCursor.getColumnIndex(EntryColumns.MOBILIZED_HTML))) { // If we didn't already mobilized it int linkPos = entryCursor.getColumnIndex(EntryColumns.LINK); int abstractHtmlPos = entryCursor.getColumnIndex(EntryColumns.ABSTRACT); int feedIdPos = entryCursor.getColumnIndex(EntryColumns.FEED_ID); HttpURLConnection connection = null; try { String link = entryCursor.getString(linkPos); String feedId = entryCursor.getString(feedIdPos); Cursor cursorFeed = cr.query(FeedColumns.CONTENT_URI(feedId), null, null, null, null); cursorFeed.moveToNext(); int cookieNamePosition = cursorFeed.getColumnIndex(FeedColumns.COOKIE_NAME); int cookieValuePosition = cursorFeed.getColumnIndex(FeedColumns.COOKIE_VALUE); String cookieName = cursorFeed.getString(cookieNamePosition); String cookieValue = cursorFeed.getString(cookieValuePosition); cursorFeed.close(); // Take substring from RSS content and use it // to try to find a text indicator for better content extraction String contentIndicator = null; String text = entryCursor.getString(abstractHtmlPos); if (!TextUtils.isEmpty(text)) { text = Html.fromHtml(text).toString(); if (text.length() > 60) { contentIndicator = text.substring(20, 40); } } connection = NetworkUtils.setupConnection(link, cookieName, cookieValue); String mobilizedHtml = ArticleTextExtractor.extractContent(connection.getInputStream(), contentIndicator); if (mobilizedHtml != null) { mobilizedHtml = HtmlUtils.improveHtmlContent(mobilizedHtml, NetworkUtils.getBaseUrl(link)); ContentValues values = new ContentValues(); values.put(EntryColumns.MOBILIZED_HTML, mobilizedHtml); ArrayList<String> imgUrlsToDownload = null; if (NetworkUtils.needDownloadPictures()) { imgUrlsToDownload = HtmlUtils.getImageURLs(mobilizedHtml); } String mainImgUrl; if (imgUrlsToDownload != null) { mainImgUrl = HtmlUtils.getMainImageURL(imgUrlsToDownload); } else { mainImgUrl = HtmlUtils.getMainImageURL(mobilizedHtml); } if (mainImgUrl != null) { values.put(EntryColumns.IMAGE_URL, mainImgUrl); } if (cr.update(entryUri, values, null, null) > 0) { success = true; operations.add(ContentProviderOperation.newDelete(TaskColumns.CONTENT_URI(taskId)) .build()); if (imgUrlsToDownload != null && !imgUrlsToDownload.isEmpty()) { addImagesToDownload(String.valueOf(entryId), imgUrlsToDownload); } } } } catch (Throwable ignored) { if (connection != null) { connection.disconnect(); } } finally { if (connection != null) { connection.disconnect(); } } } else { // We already mobilized it success = true; operations.add(ContentProviderOperation.newDelete(TaskColumns.CONTENT_URI(taskId)).build()); } } if (entryCursor != null) entryCursor.close(); if (!success) { if (nbAttempt + 1 > MAX_TASK_ATTEMPT) { operations.add(ContentProviderOperation.newDelete(TaskColumns.CONTENT_URI(taskId)).build()); } else { ContentValues values = new ContentValues(); values.put(TaskColumns.NUMBER_ATTEMPT, nbAttempt + 1); operations.add(ContentProviderOperation.newUpdate(TaskColumns.CONTENT_URI(taskId)) .withValues(values).build()); } } } if (cursor != null) cursor.close(); if (!operations.isEmpty()) { try { cr.applyBatch(FeedData.AUTHORITY, operations); } catch (Throwable ignored) { } } }
From source file:nl.privacybarometer.privacyvandaag.service.FetcherService.java
private void downloadAllImages() { ContentResolver cr = MainApplication.getContext().getContentResolver(); Cursor cursor = cr.query(TaskColumns.CONTENT_URI, new String[] { TaskColumns._ID, TaskColumns.ENTRY_ID, TaskColumns.IMG_URL_TO_DL, TaskColumns.NUMBER_ATTEMPT }, TaskColumns.IMG_URL_TO_DL + Constants.DB_IS_NOT_NULL, null, null); ArrayList<ContentProviderOperation> operations = new ArrayList<>(); while (cursor != null && cursor.moveToNext()) { long taskId = cursor.getLong(0); long entryId = cursor.getLong(1); String imgPath = cursor.getString(2); int nbAttempt = 0; if (!cursor.isNull(3)) { nbAttempt = cursor.getInt(3); }//from ww w.j av a2s. c om try { NetworkUtils.downloadImage(entryId, imgPath); // If we are here, everything is OK operations.add(ContentProviderOperation.newDelete(TaskColumns.CONTENT_URI(taskId)).build()); } catch (Exception e) { if (nbAttempt + 1 > MAX_TASK_ATTEMPT) { operations.add(ContentProviderOperation.newDelete(TaskColumns.CONTENT_URI(taskId)).build()); } else { ContentValues values = new ContentValues(); values.put(TaskColumns.NUMBER_ATTEMPT, nbAttempt + 1); operations.add(ContentProviderOperation.newUpdate(TaskColumns.CONTENT_URI(taskId)) .withValues(values).build()); } } } if (cursor != null) cursor.close(); if (!operations.isEmpty()) { try { cr.applyBatch(FeedData.AUTHORITY, operations); } catch (Throwable ignored) { } } }