List of usage examples for android.accounts Account Account
public Account(@NonNull Account other, @NonNull String accessId)
From source file:com.hybris.mobile.app.commerce.CommerceApplicationBase.java
/** * Add a default account to the sync adapter *//*from w w w . j a v a 2s. c o m*/ private void addCatalogSyncAdapterDefaultAccount() { AccountManager accountManager = (AccountManager) getSystemService(ACCOUNT_SERVICE); accountManager.addAccountExplicitly( new Account(getString(R.string.account_name), getString(R.string.account_type)), null, null); }
From source file:org.opendatakit.sync.aggregate.AggregateSynchronizer.java
public String updateAccessToken() throws InvalidAuthTokenException { AccountManager accountManager = AccountManager.get(context); try {/*from ww w . j a v a 2s . c om*/ SyncPreferences prefs = new SyncPreferences(context, appName); Account account = new Account(prefs.getAccount(), ACCOUNT_TYPE_G); this.accessToken = accountManager.blockingGetAuthToken(account, authString, true); return accessToken; } catch (Exception e) { e.printStackTrace(); throw new InvalidAuthTokenException("unable to update access token -- please re-authorize"); } }
From source file:org.mozilla.gecko.fxa.authenticator.AndroidFxAccount.java
public static AndroidFxAccount addAndroidAccount(Context context, String email, String profile, String idpServerURI, String tokenServerURI, String profileServerURI, State state, final Map<String, Boolean> authoritiesToSyncAutomaticallyMap, final int accountVersion, final boolean fromPickle, ExtendedJSONObject bundle) throws UnsupportedEncodingException, GeneralSecurityException, URISyntaxException { if (email == null) { throw new IllegalArgumentException("email must not be null"); }//ww w .j a v a2 s . c o m if (profile == null) { throw new IllegalArgumentException("profile must not be null"); } if (idpServerURI == null) { throw new IllegalArgumentException("idpServerURI must not be null"); } if (tokenServerURI == null) { throw new IllegalArgumentException("tokenServerURI must not be null"); } if (profileServerURI == null) { throw new IllegalArgumentException("profileServerURI must not be null"); } if (state == null) { throw new IllegalArgumentException("state must not be null"); } // TODO: Add migration code. if (accountVersion != CURRENT_ACCOUNT_VERSION) { throw new IllegalStateException("Could not create account of version " + accountVersion + ". Current version is " + CURRENT_ACCOUNT_VERSION + "."); } // Android has internal restrictions that require all values in this // bundle to be strings. *sigh* Bundle userdata = new Bundle(); userdata.putString(ACCOUNT_KEY_ACCOUNT_VERSION, "" + CURRENT_ACCOUNT_VERSION); userdata.putString(ACCOUNT_KEY_IDP_SERVER, idpServerURI); userdata.putString(ACCOUNT_KEY_TOKEN_SERVER, tokenServerURI); userdata.putString(ACCOUNT_KEY_PROFILE_SERVER, profileServerURI); userdata.putString(ACCOUNT_KEY_PROFILE, profile); if (bundle == null) { bundle = new ExtendedJSONObject(); // TODO: How to upgrade? bundle.put(BUNDLE_KEY_BUNDLE_VERSION, CURRENT_BUNDLE_VERSION); } bundle.put(BUNDLE_KEY_STATE_LABEL, state.getStateLabel().name()); bundle.put(BUNDLE_KEY_STATE, state.toJSONObject().toJSONString()); userdata.putString(ACCOUNT_KEY_DESCRIPTOR, bundle.toJSONString()); Account account = new Account(email, FxAccountConstants.ACCOUNT_TYPE); AccountManager accountManager = AccountManager.get(context); // We don't set an Android password, because we don't want to persist the // password (or anything else as powerful as the password). Instead, we // internally manage a sessionToken with a remotely owned lifecycle. boolean added = accountManager.addAccountExplicitly(account, null, userdata); if (!added) { return null; } // Try to work around an intermittent issue described at // http://stackoverflow.com/a/11698139. What happens is that tests that // delete and re-create the same account frequently will find the account // missing all or some of the userdata bundle, possibly due to an Android // AccountManager caching bug. for (String key : userdata.keySet()) { accountManager.setUserData(account, key, userdata.getString(key)); } AndroidFxAccount fxAccount = new AndroidFxAccount(context, account); if (!fromPickle) { fxAccount.clearSyncPrefs(); } fxAccount.setAuthoritiesToSyncAutomaticallyMap(authoritiesToSyncAutomaticallyMap); return fxAccount; }
From source file:saschpe.birthdays.service.CalendarSyncService.java
private static Cursor getContactsEvents(Context context, ContentResolver contentResolver) { // Account blacklist from our provider List<Account> accountBlacklist = AccountProviderHelper.getAccountList(context); List<String> addedEventsIdentifiers = new ArrayList<>(); /* 1. Get all raw contacts with their corresponding Account name and type (only raw * contacts get Account affiliation) */ Uri rawContactsUri = ContactsContract.RawContacts.CONTENT_URI; String[] rawContactsProjection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.CONTACT_ID, ContactsContract.RawContacts.DISPLAY_NAME_PRIMARY, ContactsContract.RawContacts.ACCOUNT_NAME, ContactsContract.RawContacts.ACCOUNT_TYPE }; Cursor rawContacts = contentResolver.query(rawContactsUri, rawContactsProjection, null, null, null); /* 2. Go over all raw contacts and check if the Account is allowed. If account is allowed, * get display name and lookup key and all events for this contact. Build a new * MatrixCursor out of this data that can be used. */ String[] columns = new String[] { BaseColumns._ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.LOOKUP_KEY, ContactsContract.CommonDataKinds.Event.START_DATE, ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.LABEL, }; MatrixCursor mc = new MatrixCursor(columns); int mcIndex = 0; try {//from w w w. j a v a 2s . co m while (rawContacts != null && rawContacts.moveToNext()) { long rawId = rawContacts.getLong(rawContacts.getColumnIndex(ContactsContract.RawContacts._ID)); String accountType = rawContacts .getString(rawContacts.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_TYPE)); String accountName = rawContacts .getString(rawContacts.getColumnIndex(ContactsContract.RawContacts.ACCOUNT_NAME)); // 2a. Check if Account is allowed (not in blacklist) boolean addEvent; if (TextUtils.isEmpty(accountType) || TextUtils.isEmpty(accountName)) { // Workaround: Simply add events without proper Account addEvent = true; } else { Account account = new Account(accountName, accountType); addEvent = !accountBlacklist.contains(account); } if (addEvent) { String displayName = null; String lookupKey = null; // 2b. Get display name and lookup key from normal contact table String[] displayProjection = new String[] { ContactsContract.Data.RAW_CONTACT_ID, ContactsContract.Data.DISPLAY_NAME, ContactsContract.Data.LOOKUP_KEY }; String displayWhere = ContactsContract.Data.RAW_CONTACT_ID + "= ?"; String[] displaySelectionArgs = new String[] { String.valueOf(rawId) }; Cursor displayCursor = contentResolver.query(ContactsContract.Data.CONTENT_URI, displayProjection, displayWhere, displaySelectionArgs, null); try { if (displayCursor != null && displayCursor.moveToNext()) { displayName = displayCursor .getString(displayCursor.getColumnIndex(ContactsContract.Data.DISPLAY_NAME)); lookupKey = displayCursor .getString(displayCursor.getColumnIndex(ContactsContract.Data.LOOKUP_KEY)); } } finally { if (displayCursor != null && !displayCursor.isClosed()) { displayCursor.close(); } } /* 2c. Get all events for this raw contact. We don't get this information for * the (merged) contact table, but from the raw contact. If we would query * this information from the contact table, we would also get events that * should have been filtered. */ Uri thisRawContactUri = ContentUris.withAppendedId(ContactsContract.RawContacts.CONTENT_URI, rawId); Uri entityUri = Uri.withAppendedPath(thisRawContactUri, ContactsContract.RawContacts.Entity.CONTENT_DIRECTORY); String[] eventsProjection = new String[] { ContactsContract.RawContacts._ID, ContactsContract.RawContacts.Entity.DATA_ID, ContactsContract.CommonDataKinds.Event.START_DATE, ContactsContract.CommonDataKinds.Event.TYPE, ContactsContract.CommonDataKinds.Event.LABEL }; String eventsWhere = ContactsContract.RawContacts.Entity.MIMETYPE + " = ? AND " + ContactsContract.RawContacts.Entity.DATA_ID + " IS NOT NULL"; String[] eventsSelectionArgs = new String[] { ContactsContract.CommonDataKinds.Event.CONTENT_ITEM_TYPE }; Cursor eventsCursor = contentResolver.query(entityUri, eventsProjection, eventsWhere, eventsSelectionArgs, null); try { while (eventsCursor != null && eventsCursor.moveToNext()) { String startDate = eventsCursor.getString( eventsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.START_DATE)); int type = eventsCursor.getInt( eventsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.TYPE)); String label = eventsCursor.getString( eventsCursor.getColumnIndex(ContactsContract.CommonDataKinds.Event.LABEL)); /* 2d. Add this information to our MatrixCursor if not already added * previously. If two Event Reminder accounts have the same contact * with duplicated events, the event will already be in the HashSet * addedEventsIdentifiers. * * eventIdentifier does not include startDate, because the * String formats of startDate differ between accounts. */ //String eventIdentifier = lookupKey + type + label; String eventIdentifier = lookupKey + type; if (addedEventsIdentifiers.contains(eventIdentifier)) { Log.d(TAG, "Duplicate event was not added!"); } else { Log.d(TAG, "Event was added with identifier " + eventIdentifier); addedEventsIdentifiers.add(eventIdentifier); mc.newRow().add(mcIndex).add(displayName).add(lookupKey).add(startDate).add(type) .add(label); mcIndex++; } } } finally { if (eventsCursor != null && !eventsCursor.isClosed()) { eventsCursor.close(); } } } } } finally { if (rawContacts != null && !rawContacts.isClosed()) { rawContacts.close(); } } /*if (BuildConfig.DEBUG) { DatabaseUtils.dumpCursor(mc); }*/ return mc; }
From source file:com.oxplot.contactphotosync.AssignContactPhotoActivity.java
@SuppressWarnings("unchecked") @Override//from w w w. j a va 2s . co m public boolean onMenuItemSelected(int featureId, MenuItem item) { switch (item.getItemId()) { case android.R.id.home: Intent upIntent = new Intent(this, SelectAccountActivity.class); if (NavUtils.shouldUpRecreateTask(this, upIntent)) { TaskStackBuilder.create(this).addNextIntent(upIntent).startActivities(); } else { NavUtils.navigateUpTo(this, upIntent); } return true; case R.id.menu_sync_now: // This is a convenient way of enabling and running the contact photo // sync. Account a = new Account(account, ACCOUNT_TYPE); ContentResolver.setSyncAutomatically(a, CONTACT_PHOTO_AUTHORITY, true); ContentResolver.requestSync(a, CONTACT_PHOTO_AUTHORITY, new Bundle()); Toast.makeText(this, getResources().getString(R.string.sync_requested), Toast.LENGTH_LONG).show(); break; case R.id.menu_download_all: case R.id.menu_upload_all: new DownloadUploadTask(item.getItemId() == R.id.menu_download_all ? DownloadUploadTask.TYPE_DOWNLOAD : DownloadUploadTask.TYPE_UPLOAD) .execute(((ContactAdapter) contactList.getAdapter()).getBackingList()); break; case R.id.menu_refresh: // XXX This is ugly and hackish. This of course doesn't stop us from being // lazy and using it here. onPause(); onResume(); break; } return super.onOptionsItemSelected(item); }
From source file:com.amazonaws.mobile.auth.google.GoogleSignInProvider.java
private String getGoogleAuthToken(final String accountEmail) throws GoogleAuthException, IOException { Log.d(LOG_TAG, "Google provider getting token..."); final Account googleAccount = new Account(accountEmail, GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE); final String scopes = "audience:server:client_id:" + getGoogleClientId(); // Retrieve the Google token. final String token = GoogleAuthUtil.getToken(context, googleAccount, scopes); // UserRecoverableAuthException will be thrown from GoogleAuthUtil.getToken() if not signed in. if (token != null) { Log.d(LOG_TAG, "Google Token is OK. Token hashcode = " + token.hashCode()); } else {//from w w w.j a v a2 s .c o m Log.d(LOG_TAG, "Google Token is NULL."); } return token; }
From source file:com.busticket.amedora.busticketsrl.TicketingHomeActivity.java
/** * Create a new dummy account for the sync adapter * * @param context The application context *//*from w w w . j a va2s . c o m*/ public static Account CreateSyncAccount(Context context) { // Create the account type and default account Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE); // Get an instance of the Android account manager AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); /* * Add the account and account type, no password or user data * If successful, return the Account object, otherwise report an error. */ if (accountManager.addAccountExplicitly(newAccount, null, null)) { /* * If you don't set android:syncable="true" in * in your <provider> element in the manifest, * then call context.setIsSyncable(account, AUTHORITY, 1) * here. */ } else { /* * The account exists or some other error occurred. Log this, report it, * or handle it internally. */ Log.d("SYNC ERR", "The account exists or some other error occurred. Log this, report it,"); } return newAccount; }
From source file:com.grepsound.activities.MainActivity.java
/** * Create a new dummy account for the sync adapter * * @param context The application context *///from w w w . j av a 2s. c om public static Account CreateSyncAccount(Context context) { // Create the account type and default account Account newAccount = new Account(ACCOUNT, ACCOUNT_TYPE); // Get an instance of the Android account manager AccountManager accountManager = (AccountManager) context.getSystemService(ACCOUNT_SERVICE); /* * Add the account and account type, no password or user data * If successful, return the Account object, otherwise report an error. */ if (accountManager.addAccountExplicitly(newAccount, null, null)) { /* * If you don't set android:syncable="true" in * in your <provider> element in the manifest, * then call context.setIsSyncable(account, AUTHORITY, 1) * here. */ } else { /* * The account exists or some other error occurred. Log this, report it, * or handle it internally. */ } return newAccount; }
From source file:com.kiddobloom.bucketlist.AuthenticatorActivity.java
@Override public void onCompleted(GraphUser user, Response response) { // TODO Auto-generated method stub //Log.d("tagaa", "FacebookGetMe: oncomplete me request"); if (response != null) { FacebookRequestError error = response.getError(); if (error != null) { // failed to get user info from facebook - TOAST //Log.d("tagaa", "FacebookGetMe: failed to get user info from facebook: " + error); Toast.makeText(getApplicationContext(), "Failed to retrieve information from Facebook - OFFLINE mode", Toast.LENGTH_SHORT).show(); saveState(StateMachine.OFFLINE_STATE); saveStatus(StateMachine.ERROR_STATUS); saveError(StateMachine.FB_GET_ME_FAILED_ERROR); goToBucketListActivity();/*from ww w. j a v a2s . c o m*/ return; } } if (user != null) { boolean registered = false; final Account account; // if we get to this point, we know that the network is OK // we can continue server registration //Log.d("tagaa", "FacebookGetMe: me = " + user); // check whether (com.kidobloom) type account has been created for the fb-userid // if account db is empty - create a new account using the fb-userid // else if an account already exists, check to see if it matches the current fb-userid // if account exists and matches the fb-userid, do nothing // otherwise replace the account with the new fb-userid AccountManager accountManager = AccountManager.get(getApplicationContext()); Account[] accounts = accountManager.getAccountsByType("com.kiddobloom"); if (accounts.length <= 0) { //Log.d("tagaa", "FacebookGetMe: no account exists"); // create a new account account = new Account(user.getId(), Constants.ACCOUNT_TYPE); am.addAccountExplicitly(account, null, null); ContentResolver.setSyncAutomatically(account, MyContentProvider.AUTHORITY, true); registered = false; } else { // get the first account //Log.d("tagaa", "FacebookGetMe: account = " + accounts[0].name); if (accounts[0].name.equals(user.getId())) { registered = true; //Log.d("tagaa", "FacebookGetMe: account for facebookId = " + user.getId() + " already created"); } else { //Log.d("tag", "FacebookGetMe: user switched account"); // remove the account first am.removeAccount(accounts[0], null, null); // add new account with the new facebook userid account = new Account(user.getId(), Constants.ACCOUNT_TYPE); am.addAccountExplicitly(account, null, null); ContentResolver.setSyncAutomatically(account, MyContentProvider.AUTHORITY, true); // update the registered flag so facebook ID gets re-registered registered = false; } } // at this point, an account should already be created // store the userid and registered boolean in preferences db saveFbUserId(user.getId()); saveUserIdRegistered(registered); saveState(StateMachine.FB_GET_FRIENDS_STATE); saveStatus(StateMachine.TRANSACTING_STATUS); saveError(StateMachine.NO_ERROR); // request facebook friends list Request.executeMyFriendsRequestAsync(response.getRequest().getSession(), this); } else { // throw an exception here - facebook does not indicate error but user is null //Log.d("tagaa", "FacebookGetMe: failed to get user info from facebook - OFFLINE mode"); Toast.makeText(getApplicationContext(), "Failed to retrieve information from Facebook", Toast.LENGTH_SHORT).show(); saveState(StateMachine.OFFLINE_STATE); saveStatus(StateMachine.ERROR_STATUS); saveError(StateMachine.FB_GET_ME_FAILED_ERROR); goToBucketListActivity(); } }
From source file:mobisocial.musubi.service.AddressBookUpdateHandler.java
@Override public void onChange(boolean selfChange) { final DatabaseManager dbManager = new DatabaseManager(mContext); if (!dbManager.getIdentitiesManager().hasConnectedAccounts()) { Log.w(TAG, "no connected accounts, skipping friend import"); return;/*ww w . j a va2s . c om*/ } //a new meta contact appears (and the previous ones disappear) if the user merges //or if a new entry is added, we can detect the ones that have changed by //this condition long highestContactIdAlreadySeen = dbManager.getContactDataVersionManager().getMaxContactIdSeen(); //a new data item corresponds with a new contact, but its possible //that a users just adds a new contact method to an existing contact //and we need to detect that long highestDataIdAlreadySeen = dbManager.getContactDataVersionManager().getMaxDataIdSeen(); // BJD -- this didn't end up being faster once all import features were added. /*if (highestContactIdAlreadySeen == -1) { importFullAddressBook(mContext); return; }*/ long now = System.currentTimeMillis(); if (mLastRun + ONCE_PER_PERIOD > now) { //wake up when the period expires if (!mScheduled) { new Handler(mThread.getLooper()).postDelayed(new Runnable() { @Override public void run() { mScheduled = false; dispatchChange(false); } }, ONCE_PER_PERIOD - (now - mLastRun) + 1); } mScheduled = true; //skip this update return; } Log.i(TAG, "waking up to handle contact changes..."); boolean identityAdded = false, profileDataChanged = false; Date start = new Date(); assert (SYNC_EMAIL); String account_type_selection = getAccountSelectionString(); Cursor c = mContext.getContentResolver().query( ContactsContract.Data.CONTENT_URI, new String[] { ContactsContract.Data._ID, ContactsContract.Data.DATA_VERSION, ContactsContract.Data.CONTACT_ID }, "(" + ContactsContract.Data.DATA_VERSION + ">0 OR " + //maybe updated ContactsContract.Data.CONTACT_ID + ">? OR " + //definitely new or merged ContactsContract.Data._ID + ">? " + //definitely added a data item ") AND (" + ContactsContract.RawContacts.ACCOUNT_TYPE + "<>'" + mAccountType + "'" + ") AND (" + NAME_OR_OTHER_SELECTION + account_type_selection + ")", // All known contacts. new String[] { String.valueOf(highestContactIdAlreadySeen), String.valueOf(highestDataIdAlreadySeen) }, null); if (c == null) { Log.e(TAG, "no valid cursor", new Throwable()); mContext.getContentResolver().notifyChange(MusubiService.ADDRESS_BOOK_SCANNED, this); return; } HashMap<Pair<String, String>, MMyAccount> account_mapping = new HashMap<Pair<String, String>, MMyAccount>(); int max_changes = c.getCount(); TLongArrayList raw_data_ids = new TLongArrayList(max_changes); TLongArrayList versions = new TLongArrayList(max_changes); long new_max_data_id = highestDataIdAlreadySeen; long new_max_contact_id = highestContactIdAlreadySeen; TLongHashSet potentially_changed = new TLongHashSet(); try { //the cursor points to a list of raw contact data items that may have changed //the items will include a type specific field that we are interested in updating //it is possible that multiple data item entries mention the same identifier //so we build a list of contacts to update and then perform synchronization //by refreshing given that we know the top level contact id. if (DBG) Log.d(TAG, "Scanning " + c.getCount() + " contacts..."); while (c.moveToNext()) { if (DBG) Log.v(TAG, "check for updates of contact " + c.getLong(0)); long raw_data_id = c.getLong(0); long version = c.getLong(1); long contact_id = c.getLong(2); //if the contact was split or merged, then we get a higher contact id //so if we have a higher id, data version doesnt really matter if (contact_id <= highestContactIdAlreadySeen) { //the data associated with this contact may not be dirty //we just can't do the join against our table because thise //api is implmented over the content provider if (dbManager.getContactDataVersionManager().getVersion(raw_data_id) == version) continue; } else { new_max_contact_id = Math.max(new_max_contact_id, contact_id); } raw_data_ids.add(raw_data_id); versions.add(version); potentially_changed.add(contact_id); new_max_data_id = Math.max(new_max_data_id, raw_data_id); } if (DBG) Log.d(TAG, "Finished iterating over " + c.getCount() + " contacts for " + potentially_changed.size() + " candidates."); } finally { c.close(); } if (potentially_changed.size() == 0) { Log.w(TAG, "possible bug, woke up to update contacts, but no change was detected; there are extra wakes so it could be ok"); } final SQLiteDatabase db = dbManager.getDatabase(); Pattern emailPattern = getEmailPattern(); Pattern numberPattern = getNumberPattern(); //slice it up so we don't use too much system resource on keeping a lot of state in memory int total = potentially_changed.size(); sAddressBookTotal = total; sAddressBookPosition = 0; final TLongArrayList slice_of_changed = new TLongArrayList(BATCH_SIZE); final StringBuilder to_fetch = new StringBuilder(); final HashMap<Pair<String, String>, TLongHashSet> ids_for_account = new HashMap<Pair<String, String>, TLongHashSet>(); final TLongObjectHashMap<String> names = new TLongObjectHashMap<String>(); TLongIterator it = potentially_changed.iterator(); for (int i = 0; i < total && it.hasNext();) { sAddressBookPosition = i; if (BootstrapActivity.isBootstrapped()) { try { Thread.sleep(mSleepTime * SLEEP_SCALE); } catch (InterruptedException e) { } } slice_of_changed.clear(); ids_for_account.clear(); names.clear(); int max = i + BATCH_SIZE; for (; i < max && it.hasNext(); ++i) { slice_of_changed.add(it.next()); } if (DBG) Log.v(TAG, "looking up names "); to_fetch.setLength(0); to_fetch.append(ContactsContract.Contacts._ID + " IN "); SQLClauseHelper.appendArray(to_fetch, slice_of_changed.iterator()); //lookup the fields we care about from a user profile perspective c = mContext.getContentResolver().query(ContactsContract.Contacts.CONTENT_URI, new String[] { ContactsContract.Contacts._ID, ContactsContract.Contacts.DISPLAY_NAME, }, to_fetch.toString(), null, null); try { while (c.moveToNext()) { long id = c.getLong(0); String name = c.getString(1); if (name == null) continue; //reject names that are just the email address or are just a number //the default for android is just to propagate this as the name //if there is no name if (emailPattern.matcher(name).matches() || numberPattern.matcher(name).matches()) continue; names.put(id, name); } } finally { c.close(); } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { db.beginTransactionNonExclusive(); } else { db.beginTransaction(); } long before = SystemClock.elapsedRealtime(); SliceUpdater updater = new SliceUpdater(dbManager, slice_of_changed, ids_for_account, names, account_type_selection); long after = SystemClock.elapsedRealtime(); mSleepTime = (mSleepTime + after - before) / 2; slice_of_changed.forEach(updater); profileDataChanged |= updater.profileDataChanged; identityAdded |= updater.identityAdded; db.setTransactionSuccessful(); db.endTransaction(); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { db.beginTransactionNonExclusive(); } else { db.beginTransaction(); } //add all detected members to account feed for (Entry<Pair<String, String>, TLongHashSet> e : ids_for_account.entrySet()) { Pair<String, String> k = e.getKey(); TLongHashSet v = e.getValue(); MMyAccount cached_account = account_mapping.get(k); if (cached_account == null) { cached_account = lookupOrCreateAccount(dbManager, k.getValue0(), k.getValue1()); prepareAccountWhitelistFeed(dbManager.getMyAccountManager(), dbManager.getFeedManager(), cached_account); account_mapping.put(k, cached_account); } final MMyAccount account = cached_account; v.forEach(new TLongProcedure() { @Override public boolean execute(long id) { dbManager.getFeedManager().ensureFeedMember(account.feedId_, id); db.yieldIfContendedSafely(75); return true; } }); } db.setTransactionSuccessful(); db.endTransaction(); } sAddressBookTotal = sAddressBookPosition = 0; //TODO: handle deleted //for all android data ids in our table, check if they still exist in the //contacts table, probably in batches of 100 or something. if they don't //null them out. this is annoyingly non-differential. //TODO: adding friend should update accepted feed status, however, //if a crashe happens for whatever reason, then its possible that this may need to //be run for identities which actually exist in the db. so this update code //needs to do the feed accepted status change for all users that were touched //by the profile update process //update the version ids so we can be faster on subsequent runs if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { db.beginTransactionNonExclusive(); } else { db.beginTransaction(); } int changed_data_rows = raw_data_ids.size(); for (int i = 0; i < changed_data_rows; ++i) { dbManager.getContactDataVersionManager().setVersion(raw_data_ids.get(i), versions.get(i)); } db.setTransactionSuccessful(); db.endTransaction(); dbManager.getContactDataVersionManager().setMaxDataIdSeen(new_max_data_id); dbManager.getContactDataVersionManager().setMaxContactIdSeen(new_max_contact_id); ContentResolver resolver = mContext.getContentResolver(); Date end = new Date(); double time = end.getTime() - start.getTime(); time /= 1000; Log.w(TAG, "update address book " + mChangeCount++ + " took " + time + " seconds"); if (identityAdded) { //wake up the profile push resolver.notifyChange(MusubiService.WHITELIST_APPENDED, this); } if (profileDataChanged) { //refresh the ui... resolver.notifyChange(MusubiService.PRIMARY_CONTENT_CHANGED, this); } if (identityAdded || profileDataChanged) { //update the our musubi address book as needed. String accountName = mContext.getString(R.string.account_name); String accountType = mContext.getString(R.string.account_type); Account account = new Account(accountName, accountType); ContentResolver.requestSync(account, ContactsContract.AUTHORITY, new Bundle()); } dbManager.close(); mLastRun = new Date().getTime(); resolver.notifyChange(MusubiService.ADDRESS_BOOK_SCANNED, this); }