Example usage for android.os Bundle containsKey

List of usage examples for android.os Bundle containsKey

Introduction

In this page you can find the example usage for android.os Bundle containsKey.

Prototype

public boolean containsKey(String key) 

Source Link

Document

Returns true if the given key is contained in the mapping of this Bundle.

Usage

From source file:com.yourkey.billing.util.InAppBilling.java

private String testItemOwned() {
    // assume item is not owned
    boolean itemOwned = false;
    String jsonItemData = null;//from   w ww . j a v  a 2s.  c  o m

    // Continuation token
    // This will be used if user owns many items and the system will
    // break it into multiple blocks.
    String continueToken = null;

    // loop in case of large numbers of owned items
    for (;;) {
        // define owned items bundle
        Bundle ownedItems = null;

        // load next block of owned items
        try {
            // get all items owned by the user
            ownedItems = inAppBillingService.getPurchases(IN_APP_BILLING_API_VERSION, packageName, itemType,
                    continueToken);
        }

        // system error
        catch (Exception e) {
            return (exceptionMessage(PLAY_STORE_LOAD_OWNED_PRODUCT_FAILED, e));
        }

        // extract the response code from the bundle
        int result = getResponseCodeFromBundle(ownedItems);
        if (result != RESULT_OK) {
            return (errorMessage(PLAY_STORE_LOAD_OWNED_PRODUCT_FAILED, result));
        }

        // response must have the following three key value pairs 
        if (!ownedItems.containsKey(RESPONSE_INAPP_ITEM_LIST)
                || !ownedItems.containsKey(RESPONSE_INAPP_PURCHASE_DATA_LIST)
                || !ownedItems.containsKey(RESPONSE_INAPP_SIGNATURE_LIST))
            return (errorMessage(PLAY_STORE_LOAD_OWNED_PRODUCT_FAILED));

        // get all items
        ArrayList<String> itemSkuArray = ownedItems.getStringArrayList(RESPONSE_INAPP_ITEM_LIST);
        ArrayList<String> itemDataArray = ownedItems.getStringArrayList(RESPONSE_INAPP_PURCHASE_DATA_LIST);
        ArrayList<String> signatureArray = ownedItems.getStringArrayList(RESPONSE_INAPP_SIGNATURE_LIST);

        // make sure all three arrays have the same size
        int arraySize = itemSkuArray.size();
        if (itemDataArray.size() != arraySize || signatureArray.size() != arraySize)
            return (errorMessage(PLAY_STORE_LOAD_OWNED_PRODUCT_FAILED));

        // verify signatures of all items
        for (int Index = 0; Index < arraySize; Index++) {
            // item information
            String ownedItemSku = itemSkuArray.get(Index);
            String ownedItemData = itemDataArray.get(Index);
            String signature = signatureArray.get(Index);

            // verify signature
            if (!verifySignature(ownedItemData, signature))
                return (errorMessage(PLAY_STORE_LOAD_OWNED_PRODUCT_FAILED));

            // test for our item sku
            if (ownedItemSku.equals(itemSku)) {
                // our item is owned by user
                itemOwned = true;
                jsonItemData = ownedItemData;
            }

            // NOTE TO PROGRAMMERS
            // the ownedItemData contains the following information
            // it must be converted to JSON object
            // JSONOBJECT jsonObject = new JSONOBJECT(ownedItemData);
            // "orderId":"12999763169054705758.1371079406387615"
            // "packageName":"com.example.app",
            // "productId":"exampleSku",
            // "purchaseTime":1345678900000, (msec since 1970/01/01)
            // "purchaseState":0,  // 0-purchased, 1 canceled, 2 refunded
            // "developerPayload":"example developer payload"
            // "purchaseToken" : "122333444455555",
        }

        // get continuation token
        continueToken = ownedItems.getString(INAPP_CONTINUATION_TOKEN);

        // if continuation token is blank or empty, break out of the loop
        if (TextUtils.isEmpty(continueToken))
            break;
    }

    // item is not owned
    if (!itemOwned)
        return (RESULT_TEXT_ITEM_NOT_OWNED);

    // purchase item
    if (!consumeActivity)
        return (RESULT_TEXT_ITEM_ALREADY_OWNED);

    // consume item
    // get the purchase token
    try {
        // create json object for item data
        JSONObject json = new JSONObject(jsonItemData);

        // get purchase token
        String itemPurchaseToken = json.optString(KEY_PURCHASE_TOKEN);

        // consume this item
        int result = inAppBillingService.consumePurchase(IN_APP_BILLING_API_VERSION, packageName,
                itemPurchaseToken);
        if (result != RESULT_OK) {
            return (errorMessage(PLAY_STORE_CONSUME_PRODUCT_FAILED, result));
        }
    }

    catch (Exception e) {
        return (exceptionMessage(PLAY_STORE_CONSUME_PRODUCT_FAILED, e));
    }

    // the item was consumed but return with already owned 
    return (RESULT_TEXT_ITEM_ALREADY_OWNED);
}

From source file:com.bodeme.easycloud.syncadapter.DavSyncAdapter.java

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
        SyncResult syncResult) {/*  w w w  . j a va  2s  . c om*/
    Log.i(TAG, "Performing sync for authority " + authority);

    // set class loader for iCal4j ResourceLoader
    Thread.currentThread().setContextClassLoader(getContext().getClassLoader());

    // create httpClient, if necessary
    httpClientLock.writeLock().lock();
    if (httpClient == null) {
        Log.d(TAG, "Creating new DavHttpClient");
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getContext());
        httpClient = DavHttpClient.create(settings.getBoolean(Constants.SETTING_DISABLE_COMPRESSION, false),
                settings.getBoolean(Constants.SETTING_NETWORK_LOGGING, false),
                !settings.getBoolean(Constants.IGNORE_SSL_ERRORS, false));
    }

    // prevent httpClient shutdown until we're ready by holding a read lock
    // acquiring read lock before releasing write lock will downgrade the write lock to a read lock
    httpClientLock.readLock().lock();
    httpClientLock.writeLock().unlock();

    try {
        // get local <-> remote collection pairs
        Map<LocalCollection<?>, RemoteCollection<?>> syncCollections = getSyncPairs(account, provider);
        if (syncCollections == null)
            Log.i(TAG, "Nothing to synchronize");
        else
            try {
                for (Map.Entry<LocalCollection<?>, RemoteCollection<?>> entry : syncCollections.entrySet())
                    new SyncManager(entry.getKey(), entry.getValue())
                            .synchronize(extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL), syncResult);

            } catch (DavException ex) {
                syncResult.stats.numParseExceptions++;
                Log.e(TAG, "Invalid DAV response", ex);

            } catch (HttpException ex) {
                if (ex.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                    Log.e(TAG, "HTTP Unauthorized " + ex.getCode(), ex);
                    syncResult.stats.numAuthExceptions++;
                } else if (ex.isClientError()) {
                    Log.e(TAG, "Hard HTTP error " + ex.getCode(), ex);
                    syncResult.stats.numParseExceptions++;
                } else {
                    Log.w(TAG, "Soft HTTP error " + ex.getCode() + " (Android will try again later)", ex);
                    syncResult.stats.numIoExceptions++;
                }

            } catch (LocalStorageException ex) {
                syncResult.databaseError = true;
                Log.e(TAG, "Local storage (content provider) exception", ex);
            } catch (IOException ex) {
                syncResult.stats.numIoExceptions++;
                Log.e(TAG, "I/O error (Android will try again later)", ex);
            }
    } finally {
        // allow httpClient shutdown
        httpClientLock.readLock().unlock();
    }

    Log.i(TAG, "Sync complete for " + authority);
}

From source file:com.codeim.coxin.LoginActivity.java

@Override
protected void onCreate(Bundle savedInstanceState) {
    Log.d(TAG, "onCreate");
    super.onCreate(savedInstanceState);

    // No Title bar
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    requestWindowFeature(Window.FEATURE_PROGRESS);

    mPreferences = PreferenceManager.getDefaultSharedPreferences(this);

    setContentView(R.layout.newlogin);/*from ww w .  java 2 s  .  c o  m*/

    mUsernameEdit = (EditText) findViewById(R.id.username_edit);
    mPasswordEdit = (EditText) findViewById(R.id.password_edit);
    mUsernameEdit.setText("");
    mPasswordEdit.setText("");

    //mWeibo = Weibo.getInstance(ConstantS.APP_KEY, ConstantS.REDIRECT_URL, ConstantS.SCOPE);

    // mUsernameEdit.setOnKeyListener(enterKeyHandler);
    mPasswordEdit.setOnKeyListener(enterKeyHandler);
    mSigninButton = (Button) findViewById(R.id.signin_button);
    mRegisterButton = (Button) findViewById(R.id.register_button);
    mBrowseButton = (Button) findViewById(R.id.browse_button);
    mWeiboSigninButton = (Button) findViewById(R.id.weibo_signin_button);

    if (savedInstanceState != null) {
        if (savedInstanceState.containsKey(SIS_RUNNING_KEY)) {
            if (savedInstanceState.getBoolean(SIS_RUNNING_KEY)) {
                Log.d(TAG, "Was previously logging in. Restart action.");
                doLogin();
            }
        }
    }

    mSigninButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            doLogin();
        }
    });

    mRegisterButton.setOnClickListener(new View.OnClickListener() {
        public void onClick(View v) {
            Intent intent = new Intent(LoginActivity.this, RegisterActivity.class);
            startActivity(intent);
            // finish();
        }
    });

    //      mBrowseButton.setOnClickListener(new View.OnClickListener() {
    //         public void onClick(View v) {
    //            Intent intent = new Intent(LoginActivity.this, BrowseActivity.class);
    //            startActivity(intent);
    //            // finish();
    //         }
    //      });

    //      mWeiboSigninButton.setOnClickListener(new View.OnClickListener() {
    //         
    //         @Override
    //         public void onClick(View v) {
    //            mSsoHandler = new SsoHandler(LoginActivity.this, mWeibo);
    //                mSsoHandler.authorize(new AuthDialogListener(), null);
    //         }
    //      }); 
}

From source file:app.helloworld.ruichen.nicta.helloworld.GcmIntentService.java

@Override
protected void onHandleIntent(Intent intent) {
    Bundle extras = intent.getExtras();
    passExtra = extras;//from  w  w w . java  2s.c o  m
    GoogleCloudMessaging gcm = GoogleCloudMessaging.getInstance(this);
    // The getMessageType() intent parameter must be the intent you received
    // in your BroadcastReceiver.
    String messageType = gcm.getMessageType(intent);

    if (!extras.isEmpty()) { // has effect of unparcelling Bundle
        /*
         * Filter messages based on message type. Since it is likely that GCM will be
         * extended in the future with new message types, just ignore any message types you're
         * not interested in, or that you don't recognize.
         */
        if (GoogleCloudMessaging.MESSAGE_TYPE_SEND_ERROR.equals(messageType)) {
            sendNotification("Send error: " + extras.toString());
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_DELETED.equals(messageType)) {
            sendNotification("Deleted messages on server: " + extras.toString());
            // If it's a regular GCM message, do some work.
        } else if (GoogleCloudMessaging.MESSAGE_TYPE_MESSAGE.equals(messageType)) {
            // This loop represents the service doing some work.
            for (int i = 0; i < 5; i++) {
                Log.i(TAG, "Working... " + (i + 1) + "/5 @ " + SystemClock.elapsedRealtime());
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                }
            }
            Log.i(TAG, "Completed work @ " + SystemClock.elapsedRealtime());
            // Post notification of received message.
            sendNotification("Received: " + extras.toString());

            Log.i(TAG, "Received: " + extras.toString());
            if (extras.containsKey("latitude"))
                Log.i(TAG, "New Latitude: " + extras.get("latitude").toString() + "\tNew Longtitude: "
                        + extras.get("longtitude").toString());
        }
    }
    // Release the wake lock provided by the WakefulBroadcastReceiver.
    GcmBroadcastReceiver.completeWakefulIntent(intent);
}

From source file:at.bitfire.davdroid.syncadapter.DavSyncAdapter.java

@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
@Override//from w ww .ja  va  2s.  co m
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
        SyncResult syncResult) {
    Log.i(TAG, "Performing sync for authority " + authority);

    /* Set class loader for iCal4j ResourceLoader  this is required because the various
     * sync adapters (contacts, events, tasks) share the same :sync process (see AndroidManifest */
    Thread.currentThread().setContextClassLoader(getContext().getClassLoader());

    // create httpClient, if necessary
    httpClientLock.writeLock().lock();
    if (httpClient == null) {
        Log.d(TAG, "Creating new DavHttpClient");
        httpClient = DavHttpClient.create();
    }

    // prevent httpClient shutdown until we're ready by holding a read lock
    // acquiring read lock before releasing write lock will downgrade the write lock to a read lock
    httpClientLock.readLock().lock();
    httpClientLock.writeLock().unlock();

    Exception exceptionToShow = null; // exception to show notification for
    Intent exceptionIntent = null; // what shall happen when clicking on the exception notification
    try {
        // get local <-> remote collection pairs
        Map<LocalCollection<?>, WebDavCollection<?>> syncCollections = getSyncPairs(account, provider);
        if (syncCollections == null)
            Log.i(TAG, "Nothing to synchronize");
        else
            try {
                for (Map.Entry<LocalCollection<?>, WebDavCollection<?>> entry : syncCollections.entrySet())
                    new SyncManager(entry.getKey(), entry.getValue())
                            .synchronize(extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL), syncResult);

            } catch (DavException ex) {
                syncResult.stats.numParseExceptions++;
                Log.e(TAG, "Invalid DAV response", ex);
                exceptionToShow = ex;

            } catch (HttpException ex) {
                if (ex.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                    Log.e(TAG, "HTTP Unauthorized " + ex.getCode(), ex);
                    syncResult.stats.numAuthExceptions++; // hard error

                    exceptionToShow = ex;
                    exceptionIntent = new Intent(context, AccountActivity.class);
                    exceptionIntent.putExtra(AccountActivity.EXTRA_ACCOUNT, account);
                } else if (ex.isClientError()) {
                    Log.e(TAG, "Hard HTTP error " + ex.getCode(), ex);
                    syncResult.stats.numParseExceptions++; // hard error
                    exceptionToShow = ex;
                } else {
                    Log.w(TAG, "Soft HTTP error " + ex.getCode() + " (Android will try again later)", ex);
                    syncResult.stats.numIoExceptions++; // soft error
                }
            } catch (LocalStorageException ex) {
                syncResult.databaseError = true; // hard error
                Log.e(TAG, "Local storage (content provider) exception", ex);
                exceptionToShow = ex;
            } catch (IOException ex) {
                syncResult.stats.numIoExceptions++; // soft error
                Log.e(TAG, "I/O error (Android will try again later)", ex);
                if (ex instanceof SSLException) // always notify on SSL/TLS errors
                    exceptionToShow = ex;
            } catch (URISyntaxException ex) {
                syncResult.stats.numParseExceptions++; // hard error
                Log.e(TAG, "Invalid URI (file name) syntax", ex);
                exceptionToShow = ex;
            }
    } finally {
        // allow httpClient shutdown
        httpClientLock.readLock().unlock();
    }

    // show sync errors as notification
    if (exceptionToShow != null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        if (exceptionIntent == null)
            exceptionIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(Constants.WEB_URL_VIEW_LOGS));

        PendingIntent contentIntent = PendingIntent.getActivity(context, 0, exceptionIntent, 0);
        Notification.Builder builder = new Notification.Builder(context).setSmallIcon(R.drawable.ic_launcher)
                .setPriority(Notification.PRIORITY_LOW).setOnlyAlertOnce(true)
                .setWhen(System.currentTimeMillis())
                .setContentTitle(context.getString(R.string.sync_error_title))
                .setContentText(exceptionToShow.getLocalizedMessage()).setContentInfo(account.name)
                .setStyle(new Notification.BigTextStyle()
                        .bigText(account.name + ":\n" + ExceptionUtils.getStackTrace(exceptionToShow)))
                .setContentIntent(contentIntent);

        NotificationManager notificationManager = (NotificationManager) context
                .getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(account.name.hashCode(), builder.build());
    }

    Log.i(TAG, "Sync complete for " + authority);
}

From source file:ch.gianulli.flashcards.BoardsFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
    View v = inflater.inflate(R.layout.fragment_boards, container, false);

    mProgressIndicator = v.findViewById(R.id.progress_indicator);

    mNoBoardsIndicator = v.findViewById(R.id.no_boards);

    mTrelloNotAccessibleIndicator = v.findViewById(R.id.trello_not_accessible);

    mRefreshLayout = (SwipeRefreshLayout) v.findViewById(R.id.refresh_layout);
    mRefreshLayout.setColorSchemeResources(R.color.color1, R.color.color2, R.color.color3);
    mRefreshLayout.setOnRefreshListener(this);

    mRecyclerView = (RecyclerView) v.findViewById(R.id.recycler_view);
    mRecyclerView.setItemAnimator(new DefaultItemAnimator());
    mLayoutManager = new GridLayoutManager(getActivity(), getNumberOfGridColumns());
    mRecyclerView.addItemDecoration(new MarginItemDecoration(getActivity(), 16, this));
    mRecyclerView.setLayoutManager(mLayoutManager);
    mRecyclerView.setAdapter(mAdapter);/*ww  w . java2s. co  m*/

    mRecyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
        @Override
        public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
            super.onScrollStateChanged(recyclerView, newState);
        }

        @Override
        public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
            mRefreshLayout.setEnabled(
                    mAdapter.isEmpty() || mLayoutManager.findFirstCompletelyVisibleItemPosition() == 0);
        }
    });

    // Restore state
    if (savedInstanceState != null && savedInstanceState.containsKey(KEY_ACTIVE_PAGE)) {
        setActivePage(Page.values()[savedInstanceState.getInt(KEY_ACTIVE_PAGE)]);
    }

    // Set title
    getActivity().setTitle(R.string.title_activity_main);

    return v;
}

From source file:at.bitfire.davdroid.mirakel.syncadapter.DavSyncAdapter.java

@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
        SyncResult syncResult) {/*  w  ww.jav  a  2s .  com*/
    Log.i(TAG, "Performing sync for authority " + authority);
    // set class loader for iCal4j ResourceLoader
    Thread.currentThread().setContextClassLoader(getContext().getClassLoader());

    // create httpClient, if necessary
    httpClientLock.writeLock().lock();
    if (httpClient == null) {
        Log.d(TAG, "Creating new DavHttpClient");
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getContext());
        httpClient = DavHttpClient.create(settings.getBoolean(Constants.SETTING_DISABLE_COMPRESSION, false),
                settings.getBoolean(Constants.SETTING_NETWORK_LOGGING, false));
    }

    // prevent httpClient shutdown until we're ready by holding a read lock
    // acquiring read lock before releasing write lock will downgrade the write lock to a read lock
    httpClientLock.readLock().lock();
    httpClientLock.writeLock().unlock();

    // TODO use VCard 4.0 if possible
    AccountSettings accountSettings = new AccountSettings(getContext(), account);
    Log.d(TAG, "Server supports VCard version " + accountSettings.getAddressBookVCardVersion());

    try {
        // get local <-> remote collection pairs
        Map<LocalCollection<?>, RemoteCollection<?>> syncCollections = getSyncPairs(account, provider);
        if (syncCollections == null)
            Log.i(TAG, "Nothing to synchronize");
        else
            try {
                for (Map.Entry<LocalCollection<?>, RemoteCollection<?>> entry : syncCollections.entrySet())
                    new SyncManager(entry.getKey(), entry.getValue())
                            .synchronize(extras.containsKey(ContentResolver.SYNC_EXTRAS_MANUAL), syncResult);

            } catch (DavException ex) {
                syncResult.stats.numParseExceptions++;
                Log.e(TAG, "Invalid DAV response", ex);
            } catch (HttpException ex) {
                if (ex.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                    Log.e(TAG, "HTTP Unauthorized " + ex.getCode(), ex);
                    syncResult.stats.numAuthExceptions++;
                } else if (ex.isClientError()) {
                    Log.e(TAG, "Hard HTTP error " + ex.getCode(), ex);
                    syncResult.stats.numParseExceptions++;
                } else {
                    Log.w(TAG, "Soft HTTP error " + ex.getCode() + " (Android will try again later)", ex);
                    syncResult.stats.numIoExceptions++;
                }

            } catch (LocalStorageException ex) {
                syncResult.databaseError = true;
                Log.e(TAG, "Local storage (content provider) exception", ex);
            } catch (IOException ex) {
                syncResult.stats.numIoExceptions++;
                Log.e(TAG, "I/O error (Android will try again later)", ex);
            }
    } finally {
        // allow httpClient shutdown
        httpClientLock.readLock().unlock();
    }

    Log.i(TAG, "Sync complete for " + authority);
}

From source file:ca.qc.bdeb.info.horus.ForecastFragment.java

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {

    // The ForecastAdapter will take data from a source and
    // use it to populate the ListView it's attached to.
    mForecastAdapter = new ForecastAdapter(getActivity(), null, 0);

    View rootView = inflater.inflate(R.layout.fragment_main, container, false);

    // Get a reference to the ListView, and attach this adapter to it.
    mListView = (ListView) rootView.findViewById(R.id.listview_forecast);
    mListView.setAdapter(mForecastAdapter);
    // We'll call our MainActivity
    mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

        @Override//from   w w w.ja  v  a2s .  co m
        public void onItemClick(AdapterView<?> adapterView, View view, int position, long l) {
            // CursorAdapter returns a cursor at the correct position for getItem(), or null
            // if it cannot seek to that position.
            Cursor cursor = (Cursor) adapterView.getItemAtPosition(position);
            if (cursor != null) {
                String locationSetting = Utility.getPreferredLocation(getActivity());
                ((Callback) getActivity()).onItemSelected(WeatherContract.WeatherEntry
                        .buildWeatherLocationWithDate(locationSetting, cursor.getLong(COL_WEATHER_DATE)));
            }
            mPosition = position;
        }
    });

    // If there's instance state, mine it for useful information.
    // The end-goal here is that the user never knows that turning their device sideways
    // does crazy lifecycle related things.  It should feel like some stuff stretched out,
    // or magically appeared to take advantage of room, but data or place in the app was never
    // actually *lost*.
    if (savedInstanceState != null && savedInstanceState.containsKey(SELECTED_KEY)) {
        // The listview probably hasn't even been populated yet.  Actually perform the
        // swapout in onLoadFinished.
        mPosition = savedInstanceState.getInt(SELECTED_KEY);
    }

    mForecastAdapter.setUseTodayLayout(mUseTodayLayout);

    return rootView;
}

From source file:edu.mit.mobile.android.locast.sync.SyncEngine.java

/**
 * @param toSync/*from w  ww.  ja  v a 2s.co m*/
 * @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:com.partypoker.poker.engagement.reach.EngagementReachAgent.java

/**
 * Called when a new content is received.
 * @param payload native push payload.//from  w  w w .j  a  va 2 s .c  o  m
 */
void onContentReceived(Bundle payload) {
    /* Parse campaign id before everything else for early feedbacks */
    String ci = payload.getString(CAMPAIGN_ID);
    com.microsoft.azure.engagement.reach.CampaignId campaignId;
    try {
        campaignId = new com.microsoft.azure.engagement.reach.CampaignId(ci);
    } catch (Exception e) {
        /* If even campaign id parsing fails, we cannot send any feedback */
        return;
    }

    /* Convert String Bundle to typed ContentValues (storage format), handle default values here. */
    ContentValues values = new ContentValues();
    values.put(CAMPAIGN_ID, ci);
    values.put(DLC, parseInt(payload, DLC, 0));
    values.put(DLC_ID, payload.getString(DLC_ID));
    values.put(CATEGORY, payload.getString(CATEGORY));
    values.put(DELIVERY_TIME, payload.containsKey(DELIVERY_TIME) ? payload.getString(DELIVERY_TIME) : "a");
    values.put(TTL, parseLong(payload, TTL));
    values.put(USER_TIME_ZONE, parseInt(payload, USER_TIME_ZONE, 0));
    values.put(NOTIFICATION_TYPE,
            payload.containsKey(NOTIFICATION_TYPE) ? payload.getString(NOTIFICATION_TYPE) : "p");
    values.put(NOTIFICATION_ICON, parseInt(payload, NOTIFICATION_ICON, 1));
    values.put(NOTIFICATION_CLOSEABLE, parseInt(payload, NOTIFICATION_CLOSEABLE, 1));
    values.put(NOTIFICATION_VIBRATION, parseInt(payload, NOTIFICATION_VIBRATION, 0));
    values.put(NOTIFICATION_SOUND, parseInt(payload, NOTIFICATION_SOUND, 0));
    values.put(NOTIFICATION_TITLE, payload.getString(NOTIFICATION_TITLE));
    values.put(NOTIFICATION_MESSAGE, payload.getString(NOTIFICATION_MESSAGE));
    values.put(NOTIFICATION_BIG_TEXT, payload.getString(NOTIFICATION_BIG_TEXT));
    values.put(NOTIFICATION_BIG_PICTURE, payload.getString(NOTIFICATION_BIG_PICTURE));
    values.put(ACTION_URL, payload.getString(ACTION_URL));

    /* Parse content */
    EngagementReachContent content;
    try {
        content = parseContent(campaignId, values);
    } catch (Exception e) {
        /* Send dropped feedback */
        campaignId.sendFeedBack(mContext, "dropped", null);
        return;
    }

    /* Content is parsed, send delivered feedback */
    campaignId.sendFeedBack(mContext, "delivered", null);

    /* Proceed */
    try {
        /* Store content in SQLite */
        long localId = mDB.put(values);
        content.setLocalId(localId);

        /*
         * If we don't know device id yet, keep it for later. If we are idle, check if the content
         * notification can be shown during the current U.I context. Datapush can be "notified" even
         * when not idle.
         */
        if (mInjectedParams.containsKey("{deviceid}"))
            notifyContent(content, false);
    } catch (Exception e) {
        /* Drop content on error */
        content.dropContent(mContext);
    }
}