9

組み込みのアカウントシステム(AccountManager APIを使用)を利用して、Androidアプリケーションのログインシステムを実装しています。

Android 2.2以降ではすべて問題ありませんが、SyncAdapterが含まれていないAndroid 2.1では、アカウント設定画面で再起動が発生します(http://code.google.com/p/android/issues/detail?id=5009およびAccountManagerを参照)。 SyncAdapterなし?

これを回避するために、nullから戻るだけのスタブSyncAdapterを実装しIBinder onBind(Intent intent)、関連するものをマニフェストに追加しました。これにより、Android2.1での再起動の問題が解決されます。

ただし、さらに問題が発生します。アカウントが追加された後、Androidシステムはしばらくしてからアカウントの同期を開始します。エラーは発生しませんが(実際、SyncAdapterは何もしませんが、戻るまでエラーを発生させる方法はありませんnull)、同期アイコンは上部の通知バーに留まります。これにより、Android同期システムは永続的なウェイクロックを維持し、デバイスがスリープ状態になるのを防ぎます。

アカウントは、アカウント設定画面([データと同期]ヘッダーの下)に同期可能なコンポーネントを一覧表示せず、アカウントのリストの同期ステータスに対して常に[同期はオフ]と表示されます(同期アイコンが通知バー)。アカウントの同期を無効にしても、問題は解決しません。アカウントを削除すると、問題が発生しなくなります。

私の推測では、nullを返すべきではありません。ThreadedSyncAdapterの基本的な実装を返す必要がありますか?2.1および2.2以降で適切に機能する同期が関連付けられていないアカウントシステムを取得するためのヘルプは大歓迎です。

4

2 に答える 2

6

これは、この問題に関連して私が見た唯一の質問であるため、1年以上遅れた回答があります。また、Android システムがカスタム アカウントを自動的に同期するため、永続的なウェイクロックの問題に遭遇しました。

これを処理する最良の方法は、最小限のコードを必要とし、実際には、コードで同期するように特別に呼び出されない限り、アカウントが同期しないようにすることです。

ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);

これには、アカウントを作成した瞬間に、この静的メソッドを呼び出す必要があります。最初のパラメーターはこの設定を設定するアカウント、2 番目のパラメーターは使用されるコンテンツ プロバイダーの権限、3 番目のパラメーターは整数で、正の数に設定すると同期が有効になり、0 に設定すると同期が無効になり、それ以外に設定すると整数になります。不明にします。使用する権限は、「sync_something.xml」内の contentAuthority 属性の下にあり、 SyncAdapter によって使用されます。

<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
android:contentAuthority="com.android.contacts" 
android:accountType="com.myapp.account"/> <!-- This being your own account type-->

上記の xml ファイルは、AndroidManifest.xml のサービス部分内で指定されています。

<service android:name=".DummySyncAdapterService"
        exported="true"
        android:process=":contacts">
        <intent-filter>
            <action android:name="android.content.SyncAdapter" />
        </intent-filter>
        <meta-data android:name="android.content.SyncAdapter" 
            android:resource="@xml/sync_something" /> <!--This points to your SyncAdapter XML-->
    </service>

これは、LoginActivity 内でカスタム アカウントを作成するために使用するコード スニペットです。

Account account = new Account("John Doe", "com.myapp.account");
ContentResolver.setIsSyncable(account, ContactsContract.AUTHORITY, 0);
AccountManager am = AccountManager.get(LoginActivity.this);
boolean accountCreated = am.addAccountExplicitly(account, "Password", null);
Bundle extras = LoginActivity.this.getIntent().getExtras();
if(extras != null){
    if (accountCreated) { 
        AccountAuthenticatorResponse response = extras.getParcelable(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE);
        Bundle result = new Bundle();
        result.putString(AccountManager.KEY_ACCOUNT_NAME, "John Doe");
        result.putString(AccountManager.KEY_ACCOUNT_TYPE, "com.myapp.account");
        response.onResult(result);
    }
}

これの重要な部分は、システムがサービスを同期しようとするときに、サービスが同期可能かどうかを最初に確認し、false に設定されている場合は同期をキャンセルすることです。これで、独自に作成する必要ContentProviderContentProvider、データと同期の下に表示される必要もなくなりました。ただし、onBind メソッド内で IBinder を返す AbstractThreadedSyncAdapter のスタブ実装が必要です。最後になりましたが、アプリ内に機能を追加しない限り、ユーザーは同期を有効にしたり、このアカウントの [今すぐ同期] ボタンを使用したりできません。

于 2012-11-07T09:19:37.897 に答える
2

私は自分の問題を解決しました。サービスのメソッドnullから戻ることはできません。onBindIBinderAbstractThreadedSyncAdapter

これにより、アカウント設定ページの [データと同期] セクションにエントリが追加されるという望ましくない効果があります。ただし、私の実装でAbstractThreadedSyncAdapterは何もしません。私はこれを避けたいと思っていました。

要約すると、Android でアカウント システムを利用するには、次のことを行う必要があります。

  • IntentFilterforを持つサービスを実装しますandroid.content.SyncAdapter
  • IBinderこのサービスは、そのメソッドAbstractThreadedSyncAdapterから実装の を返す必要がありonBindます。
  • これには、SyncAdapter XML ファイルでContentProviderとして参照される (単なるスタブ実装である可能性がある) が必要です。contentAuthority
  • これには、アカウント設定ページの [データと同期] ヘッダーの下に ContentProvider が表示されるという欠点があります。
于 2011-03-21T20:35:43.170 に答える