Search in sources :

Example 46 with ContentProviderOperation

use of android.content.ContentProviderOperation in project Android-Developers-Samples by johnjohndoe.

the class SyncAdapter method updateLocalFeedData.

/**
     * Read XML from an input stream, storing it into the content provider.
     *
     * <p>This is where incoming data is persisted, committing the results of a sync. In order to
     * minimize (expensive) disk operations, we compare incoming data with what's already in our
     * database, and compute a merge. Only changes (insert/update/delete) will result in a database
     * write.
     *
     * <p>As an additional optimization, we use a batch operation to perform all database writes at
     * once.
     *
     * <p>Merge strategy:
     * 1. Get cursor to all items in feed<br/>
     * 2. For each item, check if it's in the incoming data.<br/>
     *    a. YES: Remove from "incoming" list. Check if data has mutated, if so, perform
     *            database UPDATE.<br/>
     *    b. NO: Schedule DELETE from database.<br/>
     * (At this point, incoming database only contains missing items.)<br/>
     * 3. For any items remaining in incoming list, ADD to database.
     */
public void updateLocalFeedData(final InputStream stream, final SyncResult syncResult) throws IOException, XmlPullParserException, RemoteException, OperationApplicationException, ParseException {
    final FeedParser feedParser = new FeedParser();
    final ContentResolver contentResolver = getContext().getContentResolver();
    Log.i(TAG, "Parsing stream as Atom feed");
    final List<FeedParser.Entry> entries = feedParser.parse(stream);
    Log.i(TAG, "Parsing complete. Found " + entries.size() + " entries");
    ArrayList<ContentProviderOperation> batch = new ArrayList<ContentProviderOperation>();
    // Build hash table of incoming entries
    HashMap<String, FeedParser.Entry> entryMap = new HashMap<String, FeedParser.Entry>();
    for (FeedParser.Entry e : entries) {
        entryMap.put(e.id, e);
    }
    // Get list of all items
    Log.i(TAG, "Fetching local entries for merge");
    // Get all entries
    Uri uri = FeedContract.Entry.CONTENT_URI;
    Cursor c = contentResolver.query(uri, PROJECTION, null, null, null);
    assert c != null;
    Log.i(TAG, "Found " + c.getCount() + " local entries. Computing merge solution...");
    // Find stale data
    int id;
    String entryId;
    String title;
    String link;
    long published;
    while (c.moveToNext()) {
        syncResult.stats.numEntries++;
        id = c.getInt(COLUMN_ID);
        entryId = c.getString(COLUMN_ENTRY_ID);
        title = c.getString(COLUMN_TITLE);
        link = c.getString(COLUMN_LINK);
        published = c.getLong(COLUMN_PUBLISHED);
        FeedParser.Entry match = entryMap.get(entryId);
        if (match != null) {
            // Entry exists. Remove from entry map to prevent insert later.
            entryMap.remove(entryId);
            // Check to see if the entry needs to be updated
            Uri existingUri = FeedContract.Entry.CONTENT_URI.buildUpon().appendPath(Integer.toString(id)).build();
            if ((match.title != null && !match.title.equals(title)) || (match.link != null && !match.link.equals(link)) || (match.published != published)) {
                // Update existing record
                Log.i(TAG, "Scheduling update: " + existingUri);
                batch.add(ContentProviderOperation.newUpdate(existingUri).withValue(FeedContract.Entry.COLUMN_NAME_TITLE, title).withValue(FeedContract.Entry.COLUMN_NAME_LINK, link).withValue(FeedContract.Entry.COLUMN_NAME_PUBLISHED, published).build());
                syncResult.stats.numUpdates++;
            } else {
                Log.i(TAG, "No action: " + existingUri);
            }
        } else {
            // Entry doesn't exist. Remove it from the database.
            Uri deleteUri = FeedContract.Entry.CONTENT_URI.buildUpon().appendPath(Integer.toString(id)).build();
            Log.i(TAG, "Scheduling delete: " + deleteUri);
            batch.add(ContentProviderOperation.newDelete(deleteUri).build());
            syncResult.stats.numDeletes++;
        }
    }
    c.close();
    // Add new items
    for (FeedParser.Entry e : entryMap.values()) {
        Log.i(TAG, "Scheduling insert: entry_id=" + e.id);
        batch.add(ContentProviderOperation.newInsert(FeedContract.Entry.CONTENT_URI).withValue(FeedContract.Entry.COLUMN_NAME_ENTRY_ID, e.id).withValue(FeedContract.Entry.COLUMN_NAME_TITLE, e.title).withValue(FeedContract.Entry.COLUMN_NAME_LINK, e.link).withValue(FeedContract.Entry.COLUMN_NAME_PUBLISHED, e.published).build());
        syncResult.stats.numInserts++;
    }
    Log.i(TAG, "Merge solution ready. Applying batch update");
    mContentResolver.applyBatch(FeedContract.CONTENT_AUTHORITY, batch);
    mContentResolver.notifyChange(// URI where data was modified
    FeedContract.Entry.CONTENT_URI, // No local observer
    null, // IMPORTANT: Do not sync to network
    false);
// This sample doesn't support uploads, but if *your* code does, make sure you set
// syncToNetwork=false in the line above to prevent duplicate syncs.
}
Also used : ContentProviderOperation(android.content.ContentProviderOperation) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) Uri(android.net.Uri) ContentResolver(android.content.ContentResolver) FeedParser(com.example.android.basicsyncadapter.net.FeedParser)

Example 47 with ContentProviderOperation

use of android.content.ContentProviderOperation in project PermissionsDispatcher by hotchemi.

the class ContactsFragment method insertDummyContact.

/**
     * Accesses the Contacts content provider directly to insert a new contact.
     * <p>
     * The contact is called "__DUMMY ENTRY" and only contains a name.
     */
private void insertDummyContact() {
    // Two operations are needed to insert a new contact.
    ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2);
    // First, set up a new raw contact.
    ContentProviderOperation.Builder op = ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null);
    operations.add(op.build());
    // Next, set the name for the contact.
    op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, DUMMY_CONTACT_NAME);
    operations.add(op.build());
    // Apply the operations.
    ContentResolver resolver = getActivity().getContentResolver();
    try {
        resolver.applyBatch(ContactsContract.AUTHORITY, operations);
    } catch (RemoteException e) {
        Log.d(TAG, "Could not add a new contact: " + e.getMessage());
    } catch (OperationApplicationException e) {
        Log.d(TAG, "Could not add a new contact: " + e.getMessage());
    }
}
Also used : ContentProviderOperation(android.content.ContentProviderOperation) ArrayList(java.util.ArrayList) RemoteException(android.os.RemoteException) OperationApplicationException(android.content.OperationApplicationException) ContentResolver(android.content.ContentResolver)

Example 48 with ContentProviderOperation

use of android.content.ContentProviderOperation in project iosched by google.

the class VideosHandler method buildVideo.

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());
}
Also used : ContentProviderOperation(android.content.ContentProviderOperation) Uri(android.net.Uri)

Example 49 with ContentProviderOperation

use of android.content.ContentProviderOperation in project iosched by google.

the class BlocksHandler method outputBlock.

private static void outputBlock(Block block, ArrayList<ContentProviderOperation> list) {
    Uri uri = ScheduleContractHelper.setUriAsCalledFromSyncAdapter(ScheduleContract.Blocks.CONTENT_URI);
    ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
    String title = block.title != null ? block.title : "";
    String meta = block.subtitle != null ? block.subtitle : "";
    String type = block.type;
    if (!ScheduleContract.Blocks.isValidBlockType(type)) {
        LOGW(TAG, "block from " + block.start + " to " + block.end + " has unrecognized type (" + type + "). Using " + ScheduleContract.Blocks.BLOCK_TYPE_BREAK + " instead.");
        type = ScheduleContract.Blocks.BLOCK_TYPE_BREAK;
    }
    long startTimeL = ParserUtils.parseTime(block.start);
    long endTimeL = ParserUtils.parseTime(block.end);
    final String blockId = ScheduleContract.Blocks.generateBlockId(startTimeL, endTimeL);
    builder.withValue(ScheduleContract.Blocks.BLOCK_ID, blockId);
    builder.withValue(ScheduleContract.Blocks.BLOCK_TITLE, title);
    builder.withValue(ScheduleContract.Blocks.BLOCK_START, startTimeL);
    builder.withValue(ScheduleContract.Blocks.BLOCK_END, endTimeL);
    builder.withValue(ScheduleContract.Blocks.BLOCK_TYPE, type);
    builder.withValue(ScheduleContract.Blocks.BLOCK_SUBTITLE, meta);
    list.add(builder.build());
}
Also used : ContentProviderOperation(android.content.ContentProviderOperation) Uri(android.net.Uri)

Example 50 with ContentProviderOperation

use of android.content.ContentProviderOperation in project iosched by google.

the class CardHandler method makeContentProviderOperations.

@Override
public void makeContentProviderOperations(ArrayList<ContentProviderOperation> list) {
    LOGI(TAG, "Creating content provider operations for cards: " + mCards.size());
    Uri uri = ScheduleContractHelper.setUriAsCalledFromSyncAdapter(ScheduleContract.Cards.CONTENT_URI);
    // The list of cards is not large, so for simplicity we delete all of them and repopulate
    list.add(ContentProviderOperation.newDelete(uri).build());
    for (Card card : mCards.values()) {
        ContentProviderOperation.Builder builder = ContentProviderOperation.newInsert(uri);
        builder.withValue(ScheduleContract.Cards.ACTION_COLOR, card.mActionColor);
        builder.withValue(ScheduleContract.Cards.ACTION_TEXT, card.mActionText);
        builder.withValue(ScheduleContract.Cards.ACTION_URL, card.mActionUrl);
        builder.withValue(ScheduleContract.Cards.ACTION_TYPE, card.mActionType);
        builder.withValue(ScheduleContract.Cards.ACTION_EXTRA, card.mActionExtra);
        builder.withValue(ScheduleContract.Cards.BACKGROUND_COLOR, card.mBackgroundColor);
        builder.withValue(ScheduleContract.Cards.CARD_ID, card.mId);
        try {
            long startTime = Card.getEpochMillisFromTimeString(card.mValidFrom);
            LOGI(TAG, "Processing card with epoch start time: " + startTime);
            builder.withValue(ScheduleContract.Cards.DISPLAY_START_DATE, startTime);
        } catch (IllegalArgumentException exception) {
            LOGE(TAG, "Card time disabled, invalid display start date defined for card: " + card.mTitle + " " + card.mValidFrom);
            builder.withValue(ScheduleContract.Cards.DISPLAY_START_DATE, Long.MAX_VALUE);
        }
        try {
            long endTime = Card.getEpochMillisFromTimeString(card.mValidUntil);
            LOGI(TAG, "Processing card with epoch end time: " + endTime);
            builder.withValue(ScheduleContract.Cards.DISPLAY_END_DATE, endTime);
        } catch (IllegalArgumentException exception) {
            LOGE(TAG, "Card time disabled, invalid display end date defined for card: " + card.mTitle + " " + card.mValidUntil);
            builder.withValue(ScheduleContract.Cards.DISPLAY_END_DATE, 0L);
        }
        builder.withValue(ScheduleContract.Cards.MESSAGE, card.mShortMessage);
        builder.withValue(ScheduleContract.Cards.TEXT_COLOR, card.mTextColor);
        builder.withValue(ScheduleContract.Cards.TITLE, card.mTitle);
        list.add(builder.build());
    }
}
Also used : ContentProviderOperation(android.content.ContentProviderOperation) Uri(android.net.Uri) Card(com.google.samples.apps.iosched.io.model.Card)

Aggregations

ContentProviderOperation (android.content.ContentProviderOperation)75 ArrayList (java.util.ArrayList)53 OperationApplicationException (android.content.OperationApplicationException)34 Uri (android.net.Uri)27 ContentValues (android.content.ContentValues)25 RemoteException (android.os.RemoteException)22 Cursor (android.database.Cursor)14 ContentProviderResult (android.content.ContentProviderResult)13 ContentResolver (android.content.ContentResolver)9 LinkedList (java.util.LinkedList)8 IOException (java.io.IOException)7 JSONArray (org.json.JSONArray)6 JSONException (org.json.JSONException)6 JSONObject (org.json.JSONObject)6 Intent (android.content.Intent)5 List (java.util.List)5 SuppressLint (android.annotation.SuppressLint)4 BroadcastReceiver (android.content.BroadcastReceiver)4 Context (android.content.Context)4 IntentFilter (android.content.IntentFilter)4