6

だから、私の質問は、[設定]-> [アカウントと同期]に移動しSyncAdapterて、クラウドサーバーと同期している作成されたアカウントを選択し、[アカウントの削除]を選択すると、あなたSyncAdapterに関する限りどうなりますか?確認を求めるダイアログが表示され、そのアカウントに関連付けられている電話のデータが削除されます。フレームワークがローカルデータベースに保存したデータを自動的に削除できるとは簡単に信じられませんがSyncAdapter、アカウントを削除するとそのデータが削除されることを意味しているようです(そうすべきであることに同意します)。SyncAdapterローカルデータベースからのすべての適切なデータの削除を処理するためのアカウント削除のコールバックとして機能する追加機能はありますか?多分それはを通して行われなければならないAccountManager代わりは; AccountManagerアカウントが削除されると通知が届き、そこから。なしでデータの削除をトリガーできますSyncAdapter

SyncAdapter編集:関連するメモで、同期マネージャーは、新しいアカウントが追加されたときに同期するアカウントごとに自分を呼び出していますか?onPerformSync(...)アカウントを追加すると、以前に追加したアカウントと追加したばかりのアカウントが実行されているのがわかります。それを停止したいと思います。

4

3 に答える 3

7

解決策は、アプリのContentProvider実装を作成することであることがわかりOnAccountsUpdateListenerました。をそのメソッドにContentProviderリスナーとしてアタッチしてから、次のようなインターフェイスメソッドを実装します。onCreateaccount_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し、それを使用してSQLクエリを作成しますString。そのクエリのバックグラウンドスレッドでデータベースの削除を実行して、現在接続されていないアカウントに関連付けられているデータを削除します。また、コンテンツが変更されたことを通知しますが、サーバーと同期する必要はありません。

于 2012-08-15T16:42:25.727 に答える
5

いいえ、しかしあなたのオーセンティケーターはそうします[1]。このメソッドは、アカウントが削除される前に呼び出されます。

AbstractAccountAuthenticator.getAccountRemovalAllowed(AccountAuthenticatorResponse, Account) 

Account paramは、削除されるアカウントです。デフォルトの動作では、アカウントの削除が許可されます。

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

..しかし、必要に応じて、整理したり、アカウントの削除をブロックしたりするために使用できるフックだと思います。

[1]-これは汚いハックです。Dandreのコメントをご覧ください。

于 2013-05-20T14:18:35.117 に答える
4

もう1つのオプションは、送信するandroid.accounts.LOGIN_ACCOUNTS_CHANGEDブロードキャストに登録することです。AccountManager残念ながら、このブロードキャストは、アカウントが変更されるたびに送信され、変更された内容についての詳細情報はブロードキャストされません。

そのため、アカウントマネージャーに問い合わせて、残っている「自分の」アカウントの数を確認し、不足しているアカウントのデータを削除する必要があります。

于 2014-08-07T08:10:17.153 に答える