当AccountManager删除帐户时,SyncAdapter会收到通知吗?

Dan*_*son 6 android accountmanager android-syncadapter

所以,我重申的问题是,当您转到设置 - >帐户和同步并选择您SyncAdapter正在与云服务器同步创建的帐户时,并选择删除帐户,就您SyncAdapter而言会发生什么?将显示一个对话框,要求您确认,并且将删除与该帐户关联的电话上的数据.我不能轻易相信框架可以自动删除我SyncAdapter存储在本地数据库中的数据,但似乎暗示删除帐户将(并且我同意应该)删除该数据.我SyncAdapter是否会添加一些作为删除帐户的回调来处理从本地数据库中删除所有适当的数据?也许必须通过AccountManager反而完成; AccountManager当帐户被删除时我得到通知,从那里我可以触发数据删除而不用SyncAdapter.

编辑:在相关的说明中,同步管理员SyncAdapter是否为添加新帐户时同步的每个帐户调用我的帐户?我onPerformSync(...)在添加帐户时看到正在执行以前添加的帐户以及刚刚添加的帐户,并且想要停止该操作.

Dan*_*son 7

我发现解决方案是使应用程序ContentProvider实现OnAccountsUpdateListener.ContentProvider在其onCreate方法中附加作为侦听器account_manager.addOnAccountsUpdatedListener(this, null, false),然后实现接口方法

@Override
public void onAccountsUpdated(final Account[] accounts) {
    Ln.i("Accounts updated.");
    final Iterable<String> account_list = new Iterable<String>() {
        @Override
        public Iterator<String> iterator() {
            return new Iterator<String>() {
                private final Iterator<Account> account_list = Arrays.asList(accounts).iterator();

                @Override
                public boolean hasNext() {
                    return account_list.hasNext();
                }

                /** Extracts the next account name and wraps it in single quotes. */
                @Override
                public String next() {
                    return "'" + account_list.next().name + "'";
                }

                @Override
                public void remove() { throw new UnsupportedOperationException("Not implemented"); }
            };
        }
    };
    final String account_set = TextUtils.join(", ", account_list);
    Ln.i("Current accounts: %s", account_set);

    // Removes content that is associated with accounts that are not currently connected
    final SelectionBuilder builder = new SelectionBuilder();
    builder.table(Tables.CALENDARS)
           .where(Calendars.CALENDAR_USER + " NOT IN (?)", account_set);

    new SafeAsyncTask() {
        @Override
        public Void call() throws Exception {
            _model.openWritableDatabase();
            _model.delete(builder);
            return null;
        }
    }.execute();


    getContext().getContentResolver().notifyChange(Calendars.NO_SYNC_URI, null, false);
}
Run Code Online (Sandbox Code Playgroud)

我构建了一个String当前连接的帐户,然后用它构建一个SQL查询String.我在该查询的后台线程中对数据库执行删除操作,以删除与当前未连接的帐户关联的数据.我通知内容已更改,但不需要与服务器同步.


fr1*_*50n 5

不,但你的身份验证员确实[1].在删除帐户之前调用此方法:

AbstractAccountAuthenticator.getAccountRemovalAllowed(AccountAuthenticatorResponse, Account) 
Run Code Online (Sandbox Code Playgroud)

帐户参数是该帐户被删除-默认行为是允许移除帐户:

return super.getAccountRemovalAllowed(response, account); // returns Bundle[{booleanResult=true}]
Run Code Online (Sandbox Code Playgroud)

..但我想这是一个钩子,你可以用来整理东西或阻止你想要删除的帐户.

[1] - 这是一个肮脏的黑客; 请看Dandre的评论.

  • 我不相信这种方法可以用来"整理".鉴于其在"AbstractAccountAuthenticator"中的名称和位置,它可能用于防止您可能用于应用程序的内部帐户在您的控件之外删除.我个人没有找到用例.我的主要意图是"获取"作为前缀.您应该避免"获取"方法中的副作用,使流程难以遵循.你会怀疑"获取"删除所有数据吗? (2认同)