List of usage examples for android.os Bundle containsKey
public boolean containsKey(String key)
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); } }