use of android.content.OperationApplicationException in project SeriesGuide by UweTrottmann.
the class HexagonListsSync method pruneRemovedLists.
public boolean pruneRemovedLists() {
Timber.d("pruneRemovedLists");
HashSet<String> localListIds = ListsTools.getListIds(context);
if (localListIds == null) {
// query failed
return false;
}
if (localListIds.size() <= 1) {
// one or no list, can not remove any list
return true;
}
// get list of ids of lists on hexagon
List<String> hexagonListIds = new ArrayList<>(localListIds.size());
String cursor = null;
do {
try {
// get service each time to check if auth was removed
Lists listsService = hexagonTools.getListsService();
if (listsService == null) {
// no longer signed in
return false;
}
Lists.GetIds request = listsService.getIds();
if (!TextUtils.isEmpty(cursor)) {
request.setCursor(cursor);
}
SgListIds response = request.execute();
if (response == null) {
Timber.d("pruneRemovedLists: failed, response is null.");
return false;
}
List<String> listIds = response.getListIds();
if (listIds == null || listIds.size() == 0) {
// empty response, assume we got all ids
break;
}
hexagonListIds.addAll(listIds);
cursor = response.getCursor();
} catch (IOException | IllegalArgumentException e) {
// Note: JSON parser may throw IllegalArgumentException.
Errors.logAndReportHexagon("get list ids", e);
return false;
}
} while (// fetch next batch
!TextUtils.isEmpty(cursor));
if (hexagonListIds.size() <= 1) {
// one or no list on hexagon, can not remove any list
return true;
}
// exclude any lists that are on hexagon
for (String listId : hexagonListIds) {
localListIds.remove(listId);
}
// remove any list not on hexagon
if (localListIds.size() > 0) {
ArrayList<ContentProviderOperation> batch = new ArrayList<>();
for (String listId : localListIds) {
// note: this matches what RemoveListTask does
// delete all list items before the list to avoid violating foreign key constraints
batch.add(ContentProviderOperation.newDelete(SeriesGuideContract.ListItems.CONTENT_URI).withSelection(SeriesGuideContract.ListItems.SELECTION_LIST, new String[] { listId }).build());
// delete list
batch.add(ContentProviderOperation.newDelete(SeriesGuideContract.Lists.buildListUri(listId)).build());
}
try {
DBUtils.applyInSmallBatches(context, batch);
} catch (OperationApplicationException e) {
Timber.e(e, "pruneRemovedLists: deleting lists failed.");
return false;
}
}
return true;
}
use of android.content.OperationApplicationException in project SeriesGuide by UweTrottmann.
the class TraktRatingsSync method downloadForMovies.
/**
* Downloads trakt movie ratings and applies the latest ones to the database.
*
* <p> To apply all ratings, set {@link TraktSettings#KEY_LAST_MOVIES_RATED_AT} to 0.
*/
public boolean downloadForMovies(OffsetDateTime ratedAt) {
if (ratedAt == null) {
Timber.e("downloadForMovies: null rated_at");
return false;
}
long lastRatedAt = TraktSettings.getLastMoviesRatedAt(context);
if (!TimeTools.isAfterMillis(ratedAt, lastRatedAt)) {
// not initial sync, no ratings have changed
Timber.d("downloadForMovies: no changes since %tF %tT", lastRatedAt, lastRatedAt);
return true;
}
if (!TraktCredentials.get(context).hasCredentials()) {
return false;
}
// download rated shows
List<RatedMovie> ratedMovies;
try {
Response<List<RatedMovie>> response = traktSync.ratingsMovies(RatingsFilter.ALL, null, null, null).execute();
if (response.isSuccessful()) {
ratedMovies = response.body();
} else {
if (SgTrakt.isUnauthorized(context, response)) {
return false;
}
Errors.logAndReport("get movie ratings", response);
return false;
}
} catch (Exception e) {
Errors.logAndReport("get movie ratings", e);
return false;
}
if (ratedMovies == null) {
Timber.e("downloadForMovies: null response");
return false;
}
if (ratedMovies.isEmpty()) {
Timber.d("downloadForMovies: no ratings on trakt");
return true;
}
// trakt last activity rated_at timestamp is set after the rating timestamp
// so include ratings that are a little older
long ratedAtThreshold = lastRatedAt - 5 * DateUtils.MINUTE_IN_MILLIS;
// go through ratings, latest first (trakt sends in that order)
ArrayList<ContentProviderOperation> batch = new ArrayList<>();
for (RatedMovie movie : ratedMovies) {
if (movie.rating == null || movie.movie == null || movie.movie.ids == null || movie.movie.ids.tmdb == null) {
// skip, can't handle
continue;
}
if (movie.rated_at != null && TimeTools.isBeforeMillis(movie.rated_at, ratedAtThreshold)) {
// no need to apply older ratings again
break;
}
// if a movie does not exist, this update will do nothing
ContentProviderOperation op = ContentProviderOperation.newUpdate(SeriesGuideContract.Movies.buildMovieUri(movie.movie.ids.tmdb)).withValue(SeriesGuideContract.Movies.RATING_USER, movie.rating.value).build();
batch.add(op);
}
// apply database updates
try {
DBUtils.applyInSmallBatches(context, batch);
} catch (OperationApplicationException e) {
Timber.e(e, "downloadForMovies: database update failed");
return false;
}
// save last rated instant
long ratedAtTime = ratedAt.toInstant().toEpochMilli();
PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(TraktSettings.KEY_LAST_MOVIES_RATED_AT, ratedAtTime).apply();
Timber.d("downloadForMovies: success, last rated_at %tF %tT", ratedAtTime, ratedAtTime);
return true;
}
use of android.content.OperationApplicationException in project jpHolo by teusink.
the class ContactAccessorSdk5 method createNewContact.
/**
* Creates a new contact and stores it in the database
*
* @param contact the contact to be saved
* @param account the account to be saved under
*/
private String createNewContact(JSONObject contact, String accountType, String accountName) {
// Create a list of attributes to add to the contact database
ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
// Add contact type
ops.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI).withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, accountType).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, accountName).build());
// Add name
try {
JSONObject name = contact.optJSONObject("name");
String displayName = contact.getString("displayName");
if (displayName != null || name != null) {
ops.add(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, displayName).withValue(ContactsContract.CommonDataKinds.StructuredName.FAMILY_NAME, getJsonString(name, "familyName")).withValue(ContactsContract.CommonDataKinds.StructuredName.MIDDLE_NAME, getJsonString(name, "middleName")).withValue(ContactsContract.CommonDataKinds.StructuredName.GIVEN_NAME, getJsonString(name, "givenName")).withValue(ContactsContract.CommonDataKinds.StructuredName.PREFIX, getJsonString(name, "honorificPrefix")).withValue(ContactsContract.CommonDataKinds.StructuredName.SUFFIX, getJsonString(name, "honorificSuffix")).build());
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get name object");
}
// Add phone numbers
JSONArray phones = null;
try {
phones = contact.getJSONArray("phoneNumbers");
if (phones != null) {
for (int i = 0; i < phones.length(); i++) {
JSONObject phone = (JSONObject) phones.get(i);
insertPhone(ops, phone);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get phone numbers");
}
// Add emails
JSONArray emails = null;
try {
emails = contact.getJSONArray("emails");
if (emails != null) {
for (int i = 0; i < emails.length(); i++) {
JSONObject email = (JSONObject) emails.get(i);
insertEmail(ops, email);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get emails");
}
// Add addresses
JSONArray addresses = null;
try {
addresses = contact.getJSONArray("addresses");
if (addresses != null) {
for (int i = 0; i < addresses.length(); i++) {
JSONObject address = (JSONObject) addresses.get(i);
insertAddress(ops, address);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get addresses");
}
// Add organizations
JSONArray organizations = null;
try {
organizations = contact.getJSONArray("organizations");
if (organizations != null) {
for (int i = 0; i < organizations.length(); i++) {
JSONObject org = (JSONObject) organizations.get(i);
insertOrganization(ops, org);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get organizations");
}
// Add IMs
JSONArray ims = null;
try {
ims = contact.getJSONArray("ims");
if (ims != null) {
for (int i = 0; i < ims.length(); i++) {
JSONObject im = (JSONObject) ims.get(i);
insertIm(ops, im);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get emails");
}
// Add note
String note = getJsonString(contact, "note");
if (note != null) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Note.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Note.NOTE, note).build());
}
// Add nickname
String nickname = getJsonString(contact, "nickname");
if (nickname != null) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Nickname.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Nickname.NAME, nickname).build());
}
// Add urls
JSONArray websites = null;
try {
websites = contact.getJSONArray("urls");
if (websites != null) {
for (int i = 0; i < websites.length(); i++) {
JSONObject website = (JSONObject) websites.get(i);
insertWebsite(ops, website);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get websites");
}
// Add birthday
String birthday = getJsonString(contact, "birthday");
if (birthday != null) {
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI).withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE).withValue(ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.TYPE_BIRTHDAY).withValue(ContactsContract.CommonDataKinds.Event.START_DATE, birthday).build());
}
// Add photos
JSONArray photos = null;
try {
photos = contact.getJSONArray("photos");
if (photos != null) {
for (int i = 0; i < photos.length(); i++) {
JSONObject photo = (JSONObject) photos.get(i);
insertPhoto(ops, photo);
}
}
} catch (JSONException e) {
Log.d(LOG_TAG, "Could not get photos");
}
String newId = null;
// Add contact
try {
ContentProviderResult[] cpResults = mApp.getActivity().getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
if (cpResults.length >= 0) {
newId = cpResults[0].uri.getLastPathSegment();
}
} catch (RemoteException e) {
Log.e(LOG_TAG, e.getMessage(), e);
} catch (OperationApplicationException e) {
Log.e(LOG_TAG, e.getMessage(), e);
}
return newId;
}
use of android.content.OperationApplicationException in project Android-Developers-Samples by johnjohndoe.
the class SyncAdapter method onPerformSync.
/**
* Called by the Android system in response to a request to run the sync adapter. The work
* required to read data from the network, parse it, and store it in the content provider is
* done here. Extending AbstractThreadedSyncAdapter ensures that all methods within SyncAdapter
* run on a background thread. For this reason, blocking I/O and other long-running tasks can be
* run <em>in situ</em>, and you don't have to set up a separate thread for them.
* .
*
* <p>This is where we actually perform any work required to perform a sync.
* {@link android.content.AbstractThreadedSyncAdapter} guarantees that this will be called on a non-UI thread,
* so it is safe to peform blocking I/O here.
*
* <p>The syncResult argument allows you to pass information back to the method that triggered
* the sync.
*/
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
Log.i(TAG, "Beginning network synchronization");
try {
final URL location = new URL(FEED_URL);
InputStream stream = null;
try {
Log.i(TAG, "Streaming data from network: " + location);
stream = downloadUrl(location);
updateLocalFeedData(stream, syncResult);
// Makes sure that the InputStream is closed after the app is
// finished using it.
} finally {
if (stream != null) {
stream.close();
}
}
} catch (MalformedURLException e) {
Log.e(TAG, "Feed URL is malformed", e);
syncResult.stats.numParseExceptions++;
return;
} catch (IOException e) {
Log.e(TAG, "Error reading from network: " + e.toString());
syncResult.stats.numIoExceptions++;
return;
} catch (XmlPullParserException e) {
Log.e(TAG, "Error parsing feed: " + e.toString());
syncResult.stats.numParseExceptions++;
return;
} catch (ParseException e) {
Log.e(TAG, "Error parsing feed: " + e.toString());
syncResult.stats.numParseExceptions++;
return;
} catch (RemoteException e) {
Log.e(TAG, "Error updating database: " + e.toString());
syncResult.databaseError = true;
return;
} catch (OperationApplicationException e) {
Log.e(TAG, "Error updating database: " + e.toString());
syncResult.databaseError = true;
return;
}
Log.i(TAG, "Network synchronization complete");
}
use of android.content.OperationApplicationException in project YourAppIdea by Michenux.
the class TutorialSyncAdapter method onPerformSync.
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
((YourApplication) getContext().getApplicationContext()).setSyncAdapterRunning(true);
LocalBroadcastManager.getInstance(this.getContext()).sendBroadcast(new Intent(SYNC_STARTED));
try {
boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
WPJsonPost newPost = retrievePosts(AppUsageUtils.getLastSync(this.getContext()), provider);
if (BuildConfig.DEBUG) {
Log.d(YourApplication.LOG_TAG, "tutorialSyncAdapter.onPerformSync() - manual:" + manualSync);
}
if (newPost != null) {
// notification only if not manual sync
if (!manualSync) {
sendNotification(newPost);
}
} else {
if (BuildConfig.DEBUG) {
Log.d(YourApplication.LOG_TAG, " no new post");
}
}
if (!manualSync) {
mSyncHelper.adjustSyncInterval(TutorialSyncAdapter.this.getContext());
}
AppUsageUtils.updateLastSync(TutorialSyncAdapter.this.getContext());
} catch (ParseException e) {
Log.e(YourApplication.LOG_TAG, "tutorialSyncAdapter.onPerformSync()", e);
syncResult.stats.numParseExceptions++;
} catch (InterruptedException | ExecutionException | RemoteException | OperationApplicationException e) {
Log.e(YourApplication.LOG_TAG, "tutorialSyncAdapter.onPerformSync()", e);
syncResult.stats.numIoExceptions++;
} finally {
LocalBroadcastManager.getInstance(this.getContext()).sendBroadcast(new Intent(SYNC_FINISHED));
((YourApplication) getContext().getApplicationContext()).setSyncAdapterRunning(false);
}
}
Aggregations