contacts 账户同步
来源:互联网 发布:360软件助手 编辑:程序博客网 时间:2024/06/12 02:40
本流程图基于MTK平台 Android 7.0,本流程只作为沟通学习使用
工作中遇到一个问题,手机登陆Google账户并同步账户里面的contacts后,本地保存的联系人数据被无缘无故的删除了,甚是奇怪,通过对比前后的数据库我们发现,同步后直接把我们的本地账户给删除了,所以导致属于这个账户的所有联系人都不见了,那么无缘无故为什么会删除本地账户呢?我们先抛出问题,等我们看完整个流程再回来看看真是什么。前提,我们的手机是被客制化过,不是android原生系统。
整体流程图
部分流程说明
我们重点看看updateAccountsInBackground这个方法
后台更新账户,判断账户是否合法,不合法就删除合法就保存
private boolean updateAccountsInBackground(Account[] systemAccounts) { if (!haveAccountsChanged(systemAccounts)) { //判断当前账户是否有改变 return false; }..... Log.i(TAG, "Accounts changed"); invalidateFastScrollingIndexCache(); final ContactsDatabaseHelper dbHelper = mDbHelper.get(); final SQLiteDatabase db = dbHelper.getWritableDatabase();..... try { // First, remove stale rows from raw_contacts, groups, and related tables. // All accounts that are used in raw_contacts and/or groups. final Set<AccountWithDataSet> knownAccountsWithDataSets = dbHelper.getAllAccountsWithDataSets(); // Find the accounts that have been removed. final List<AccountWithDataSet> accountsWithDataSetsToDelete = Lists.newArrayList(); for (AccountWithDataSet knownAccountWithDataSet : knownAccountsWithDataSets) { if (knownAccountWithDataSet.isLocalAccount() || !canDeleteAccount(knownAccountWithDataSet) || knownAccountWithDataSet.inSystemAccounts(systemAccounts, mSkipRemoval)) { continue; } accountsWithDataSetsToDelete.add(knownAccountWithDataSet);//保存需要删除的账户,后面如果这个list不为空就删除里面账户的相关信息 } if (!accountsWithDataSetsToDelete.isEmpty()) { for (AccountWithDataSet accountWithDataSet : accountsWithDataSetsToDelete) {.....做一些数据库删除操作,把这个账户相关的数据都删除 } } // Second, remove stale rows from Tables.SETTINGS and Tables.DIRECTORIES removeStaleAccountRows( Tables.SETTINGS, Settings.ACCOUNT_NAME, Settings.ACCOUNT_TYPE, systemAccounts); removeStaleAccountRows(Tables.DIRECTORIES, Directory.ACCOUNT_NAME, Directory.ACCOUNT_TYPE, systemAccounts);.....一些删除操作 /// @} // Third, remaining tasks that must be done in a transaction. // TODO: Should sync state take data set into consideration? dbHelper.getSyncState().onAccountsChanged(db, systemAccounts); saveAccounts(systemAccounts);//保存新加的账户 db.setTransactionSuccessful(); } finally {..... mAccountWritability.clear(); updateContactsAccountCount(systemAccounts); updateProviderStatus(); return true; }
haveAccountsChanged
查看账户是否有变更
@VisibleForTesting boolean haveAccountsChanged(Account[] currentSystemAccounts) { final ContactsDatabaseHelper dbHelper = mDbHelper.get(); final Set<Account> knownAccountSet; try { knownAccountSet = stringToAccounts(dbHelper.getProperty(DbProperties.KNOWN_ACCOUNTS, "")); } catch (IllegalArgumentException e) { // Failed to get the last known accounts for an unknown reason. Let's just // treat as if accounts have changed. return true; } final Set<Account> currentAccounts = Sets.newHashSet(currentSystemAccounts); return !knownAccountSet.equals(currentAccounts); }
isLocalAccount
通过账户类型判断当前账户是否是本地账户
public static final String ACCOUNT_TYPE_LOCAL_PHONE = "Local Phone Account"; private static final String ACCOUNT_TYPE_SIM = "SIM Account"; private static final String ACCOUNT_TYPE_USIM = "USIM Account"; private static final String ACCOUNT_TYPE_RUIM = "RUIM Account"; private static final String ACCOUNT_TYPE_CSIM = "CSIM Account"; private static final String LOCAL_ACCOUNT_TYPES = "('" + ACCOUNT_TYPE_LOCAL_PHONE + "' , '" + ACCOUNT_TYPE_SIM + "' , '" + ACCOUNT_TYPE_USIM + "' , '" + ACCOUNT_TYPE_RUIM + "' , '" + ACCOUNT_TYPE_CSIM + "')"; /** * Check if the account is local account */ public static boolean isLocalAccount(String accountType, String accountName) { return (accountType == null && accountName == null) || (accountType != null && LOCAL_ACCOUNT_TYPES.contains(accountType)); }
inSystemAccounts
判断当前账户是不是系统合法账户
public boolean inSystemAccounts(Account[] systemAccounts, boolean skip) { // Note we don't want to create a new Account object from this instance, as it may contain // null account name/type, which Account wouldn't accept. So we need to compare field by // field. for (Account systemAccount : systemAccounts) { if (Objects.equal(systemAccount.name, getAccountName())//通过获取账户名和账户类型来判断 && Objects.equal(systemAccount.type, getAccountType())) { return true; } } return false; }
saveAccounts
将合法账户保存下来并更新一些值
@VisibleForTesting void saveAccounts(Account[] systemAccounts) { final ContactsDatabaseHelper dbHelper = mDbHelper.get(); dbHelper.setProperty( DbProperties.KNOWN_ACCOUNTS, accountsToString(Sets.newHashSet(systemAccounts))); }
问题解决
回顾我们的问题,我们是发现登陆账户同步联系人后,本地账户被删除了,然而我们本地账户是被客制化了的,根据上面的流程我们可以知道,添加账户后会检查已存在的账户和加入的账户是否是本地账户,并检查账户是否合法,那么我们就有怀疑点了,是否是我们的本地账户类型不合法呢?所以我们就有了解决办法。
1.把我们预置的本地账户类型改成代码中本地账户合法的类型
2.把我们预置的本地账户类型添加到LOCAL_ACCOUNT_TYPES 中,让其成为一个合法的本地账户类型
阅读全文
0 0
- contacts 账户同步
- Firefox Sync账户同步
- Contacts
- Contacts
- Android账户同步备份机制
- 小米账户的同步问题
- TFS域账户手动同步
- chrome浏览器与GOOGLE账户同步
- 同步AD账户到MOSS中
- Google账户和手机联系人同步
- 安卓系统的账户与同步
- android 账户管理和同步机制
- ADFS 账户同步到 SharePoint 使用
- Domino与AD账户同步(一)
- Domino与AD账户同步(二)
- 账户
- 手工同步IWAM和IUSR账户,解决HTTP-500错误
- 在iOS上轻松同步你的Google账户
- bat脚本设置系统环境变量即时生效
- 发送邮件增加同步锁
- Tomcat的HTTP与AJP协议
- Simple Java Mail的使用
- Android静默拍照实现(界面无卡顿)
- contacts 账户同步
- 数据库连接池
- SpringMVC配置web.xml文件详解(列举常用的配置)
- quartz详解2:quartz由浅入深
- 个人博客学习说明(转)
- Spring MVC rest接收json中文格式数据显示乱码
- qt批量插入数据
- 单链表的基本操作(创建、插入、删除......)
- Effective Java 对于所用对象都通用的方法 10.始终要覆盖toString,玩转toString