2

アカウントの種類は「mypackage.account」で、コンテンツ権限は「mypackage」です。のService実装を提供する がありAbstractAccountAuthenticatoraddAccountメソッドは次のように実装されます。

    /**
     * The user has requested to add a new account to the system. We return an intent that will launch our login
     * screen if the user has not logged in yet, otherwise our activity will just pass the user's credentials on to
     * the account manager.
     */
    @Override
    public Bundle addAccount(AccountAuthenticatorResponse response, String account_type, String auth_token_type,
                             String[] required_features, Bundle options) throws NetworkErrorException {
        final Intent intent = new Intent(_context, ConnectAccountActivity.class);
        intent.putExtra(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE, response);
        final Bundle reply = new Bundle();
        reply.putParcelable(AccountManager.KEY_INTENT, intent);

        return reply;
    }

私は提供しますauthenticator.xml

<account-authenticator xmlns:android="http://schemas.android.com/apk/res/android"
                   android:accountType="mypackage.account"
                   android:icon="@drawable/ic_launcher"
                   android:smallIcon="@drawable/ic_launcher"
                   android:label="@string/app_name"
                   android:accountPreferences="@xml/account_preferences" />

Serviceこれを次のAndroidManifest.xmlように定義します。

<!-- Account authentication service that provides the methods for authenticating KeepandShare accounts to the
     AccountManager framework -->
<service android:exported="true" android:name=".authenticator.AccountAuthenticatorService" android:process=":auth" tools:ignore="ExportedService">
    <intent-filter>
        <action android:name="android.accounts.AccountAuthenticator"/>
    </intent-filter>
    <meta-data android:name="android.accounts.AccountAuthenticator" android:resource="@xml/authenticator"/>
</service>

これでセットアップは完了です。新しいアカウントを追加するアクションを使用して、デバイスに自分のアカウント タイプのアカウントのリストを表示する画面が必要な場合は、次のようなアカウントの追加アクションがあります。

final Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[]{ "mypackage" });
startActivity(intent);

この時点で、「mypackage.account」と「anotherpackage.account」をオプションとして表示するアカウント タイプ ピッカーが表示されます。(「anotherpackage.account」は私が取り組んでいる別のアプリで定義されています)これは意図した動作のようには見えません。両方のアプリで定義されている権限が異なることを約 20 回確認しましたが、違います。誰かが私に欠けているものを見せてもらえますか?

4

3 に答える 3

2

Androidのデカップリングが再び私を噛むようになりました。どちらのアプリにも次のようなものが必要だったsync_adapter.xmlようです。

<!-- The attributes in this XML file provide configuration information for the SyncAdapter. -->
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
          android:contentAuthority="mypackage"
          android:accountType="mypackage.account"
          android:supportsUploading="true"
          android:userVisible="true"
          android:allowParallelSyncs="false"
          android:isAlwaysSyncable="true"/>

そしてそれを:の同期サービスに接続しAndroidManifest.xmlます

<!-- Data sync service that provides the SyncAdapter to the SyncManager framework. The SyncAdapter is used to
     maintain that the set of data on the device is a subset of the data on the server -->
<service android:exported="true" android:name=".data.sync.SyncService" tools:ignore="ExportedService">
    <intent-filter>
        <action android:name="android.content.SyncAdapter"/>
    </intent-filter>
    <meta-data android:name="android.content.SyncAdapter" android:resource="@xml/sync_adapter"/>
</service>

完全を期すために、myServiceは次のように実装されています。

/**
 * Service that provides sync functionality to the SyncManager through the {@link SyncAdapter}.
 */
public class SyncService extends Service {

    @Override
    public void onCreate() {
        synchronized (_sync_adapter_lock) {
            if (_sync_adapter == null)
                _sync_adapter = new SyncAdapter(getApplicationContext(), false);
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return _sync_adapter.getSyncAdapterBinder();
    }

    private static final Object _sync_adapter_lock = new Object();
    private static SyncAdapter _sync_adapter = null;
}

SyncAdapter

/**
 * Sync adapter for KeepandShare data.
 */
public class SyncAdapter extends AbstractThreadedSyncAdapter {

    public SyncAdapter(Context context, boolean should_auto_initialize) {
        super(context, should_auto_initialize);

        //noinspection ConstantConditions,PointlessBooleanExpression
        if (!BuildConfig.DEBUG) {
            Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
                @Override
                public void uncaughtException(Thread thread, Throwable throwable) {
                    Log.e("Uncaught sync exception, suppressing UI in release build.", throwable);
                }
            });
        }
    }

    @Override
    public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider,
                              SyncResult sync_result) {
        // TODO: implement sync
    }
}

実際にはデータを同期していませんが(アプリは現在どのサーバーにもリンクされていません)、Androidフレームワークは、の設定を使用して、SyncAdapterアカウント認証システムがアカウントの追加リクエストに応答するかどうかを判断しているようです。

于 2012-11-07T19:26:17.227 に答える
1

それにもかかわらず、質問が古くて閉じていることは知っています...

ドキュメントSettings.ACTION_ADD_ACCOUNT:

追加できるアカウントの種類は、1 つ以上の同期可能なコンテンツ プロバイダーの権限を持つEXTRA_AUTHORITIESエクストラをインテントに追加することで制限できます。そのコンテンツ プロバイダーと同期できるアカウント タイプのみがユーザーに提供されます。

空の同期アダプターを実装する必要があったのはそのためだと思います。ドキュメントを参照すると、Settings.EXTRA_ACCOUNT_TYPES代わりに使用するときにこれは必要ないはずです(あなたのように2つのプロジェクトで試したことはありませんでしたが、現在開発中のプロジェクトでは魅力的に機能し、同期アダプターはまったく必要ありません):

intent.putExtra(Settings.EXTRA_ACCOUNT_TYPES, new String[] { "mypackage.account" });
于 2015-08-05T12:08:29.283 に答える
0

インテントを呼び出す代わりに...

final Intent intent = new Intent(Settings.ACTION_ADD_ACCOUNT);
intent.putExtra(Settings.EXTRA_AUTHORITIES, new String[]{ "mypackage" });
startActivity(intent);

以下を使用して、指定されたアカウント タイプの認証プロセスに直接進むことができます。これはあなたが持っている必要はありませんSyncAdapter

AccountManager accountManager = AccountManager.get(this);
accountManager.addAccount(AccountAuthenticator.ACCOUNT_TYPE, AccountAuthenticator.AUTHTOKEN_TYPE_FULL_ACCESS, null, null, this, new AccountManagerCallback<Bundle>() {
        @Override
        public void run(AccountManagerFuture<Bundle> future) {

        }
}, new Handler());
于 2013-10-19T23:49:20.643 に答える