【问题标题】:Does SyncAdapter get notified when AccountManager removes account?当 AccountManager 删除帐户时,SyncAdapter 会收到通知吗?
【发布时间】:2012-06-26 19:39:32
【问题描述】:

所以,我重申的问题是,当您转到“设置”->“帐户和同步”并选择您的 SyncAdapter 正在与云服务器同步的帐户,然后选择“删除帐户”时,会发生什么SyncAdapter 担心吗?将显示一个对话框,要求您确认,并且与该帐户关联的手机上的数据将被删除。我不能轻易相信该框架可以自动删除我的SyncAdapter 存储在本地数据库中的数据,但这似乎意味着删除帐户将(我同意应该)删除该数据。我的SyncAdapter 是否有一个补充,可以作为帐户删除的回调来处理从本地数据库中删除所有适当的数据?也许它必须通过AccountManager 来完成;当帐户被删除时,我的AccountManager 会收到通知,并且我可以在没有SyncAdapter 的情况下触发数据删除。

编辑: 在相关说明中,同步管理器是否为添加新帐户时同步的每个帐户调用我的SyncAdapter?当我添加一个帐户时,我看到一个 onPerformSync(...) 正在为先前添加的帐户以及刚刚添加的帐户执行,并希望停止它。

【问题讨论】:

    标签: android accountmanager android-syncadapter


    【解决方案1】:

    我发现解决方案是让应用程序的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);
    }
    

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

    【讨论】:

    • 您能否详细说明您的答案?你在说什么onCreate
    • ...ContentProvider,请仔细阅读第一行。我不知道你还想要什么“详细”
    • 是否可以在 ContentProviders 生命周期的相关点删除 OnAccountsUpdateListener?
    • 你确定你的监听器总是被调用吗?您指的是哪个 onCreate 方法?服务呢?
    • @RaB 你需要给我的不仅仅是“你确定......”,你有问题吗?至于哪个onCreate,它在答案中,我在这里的cmets中重复了它:ContentProvider
    【解决方案2】:

    不,但您的身份验证器可以[1]。该方法在账号被移除前调用:

    AbstractAccountAuthenticator.getAccountRemovalAllowed(AccountAuthenticatorResponse, Account) 
    

    Account 参数是要删除的帐户 - 默认行为是允许删除帐户:

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

    ..但我想这是一个钩子,您可以使用它来整理或阻止您希望删除的帐户。

    [1] - 这是一个肮脏的 hack;请参阅 Dandre 的评论。

    【讨论】:

    • 我不认为该方法旨在用于“整理”。鉴于其在AbstractAccountAuthenticator 中的名称和位置,它可能用于防止您可能用于您的应用程序的内部帐户在您的控制之外被删除。我个人没有找到用例。对我来说最大的意图是“get”作为前缀。您应该避免“get”方法的副作用,使流程难以遵循。您会怀疑“get”会删除您的所有数据吗?
    • 毫无疑问你是对的,这是一个肮脏的黑客。我将更新我的答案。
    【解决方案3】:

    另一种选择是注册AccountManager 发出的android.accounts.LOGIN_ACCOUNTS_CHANGED 广播。不幸的是,此广播在任何帐户发生更改时都会发送出去,并且该广播也不会提供更多信息,了解发生了什么变化。

    因此您必须查询客户经理并查看它还剩下多少“您的”帐户并删除丢失的数据。

    【讨论】:

    • 好吧,@Dandre Allison 以上的解决方案就是基于此。所以这个答案应该是首选。当您调用addOnAccountsUpdatedListener 时,AccountManager 正在注册一个动态广播接收器,该接收器在其onReceive 中调用侦听器。所以,基本上是一样的。每当设备中的任何帐户(Google 帐户、Twitter 帐户等)发生更改时,这两种解决方案都会收到通知。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-04
    • 2016-07-02
    相关资源
    最近更新 更多