Android 如何让我的syncadapter帐户出现在Google联系人应用程序中?

Android 如何让我的syncadapter帐户出现在Google联系人应用程序中?,android,android-contacts,Android,Android Contacts,我正试图让android应用程序的自定义联系人出现在playstore的Google(最新)联系人应用程序中,但无法让我的用户帐户出现在联系人应用程序快速帐户切换列表的工具架抽屉中。我需要做什么才能使我的帐户显示在此列表中 我已实施以下措施: 我的Android清单包含以下条目: <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/a

我正试图让android应用程序的自定义联系人出现在playstore的Google(最新)联系人应用程序中,但无法让我的用户帐户出现在联系人应用程序快速帐户切换列表的工具架抽屉中。我需要做什么才能使我的帐户显示在此列表中

我已实施以下措施:

我的Android清单包含以下条目:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.test.contactsynctest">

    <uses-permission android:name="android.permission.GET_ACCOUNTS"></uses-permission>
    <uses-permission android:name="android.permission.MANAGE_ACCOUNTS"></uses-permission>
    <uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_CONTACTS"></uses-permission>
    <uses-permission android:name="android.permission.CONTROL_KEYBOARD"></uses-permission>
    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS"></uses-permission>
    <uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS"></uses-permission>


    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity
            android:name="com.test.contactsynctest.ContactSyncActivity"
            android:label="@string/app_name"
            android:theme="@style/AppTheme.NoActionBar">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service
            android:name="com.test.contactsynctest.TestSyncService"
            android:exported="true">
            <intent-filter>
                <action android:name="android.content.SyncAdapter"/>
            </intent-filter>
            <meta-data
                android:name="android.content.SyncAdapter"
                android:resource="@xml/syncadapter_contacts"/>
        </service>
        <service
            android:name="com.test.contactsynctest.AuthenticatorService"
            android:exported="true">
            <intent-filter>
                <action android:name="android.accounts.AccountAuthenticator"/>
            </intent-filter>
            <meta-data
                android:name="android.accounts.AccountAuthenticator"
                android:resource="@xml/authenticator"/>
        </service>
    </application>

</manifest>
认证服务

package com.test.contactsynctest;

import android.accounts.AccountManager;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class AuthenticatorService extends Service {

    private static AccountAuthenticator auth = null;

    public AuthenticatorService() {
        super();
    }

    @Override
    public IBinder onBind(Intent intent) {

        if (intent.getAction().equals(AccountManager.ACTION_AUTHENTICATOR_INTENT)) {
            if (auth == null) {
                auth = new AccountAuthenticator(this);
            }
            return auth.getIBinder();
        }
        return null;
    }
}
接触同步活动

package com.test.contactsynctest;

import android.Manifest;
import android.accounts.AccountManager;
import android.content.ContentProviderOperation;
import android.content.OperationApplicationException;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Calendar;

public class ContactSyncActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_contacts_export);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                writeContact("Sally" + Calendar.getInstance().getTime().toString(), "123-456-789");
                Toast.makeText(ContactSyncActivity.this, "Contact created", Toast.LENGTH_LONG).show();
            }
        });

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_CONTACTS)
                != PackageManager.PERMISSION_GRANTED) {

                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_CONTACTS}, 2);
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_contacts_export, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            AccountManager.get(this).addAccount(AccountAuthenticator.ACCOUNT_TYPE, null, null, null, null, null, null);
            Toast.makeText(ContactSyncActivity.this, "Account registered", Toast.LENGTH_LONG).show();
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    private void writeContact(String displayName, String number) {
        ArrayList contentProviderOperations = new ArrayList();
        //insert raw contact using RawContacts.CONTENT_URI
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
                .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, AccountAuthenticator.ACCOUNT_TYPE).withValue(ContactsContract.RawContacts.ACCOUNT_NAME, AccountAuthenticator.USERID).build());
        //insert contact display name using Data.CONTENT_URI
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Contacts.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, displayName).build());
        //insert mobile number using Data.CONTENT_URI
        contentProviderOperations.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
                .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0).withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
                .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, number).withValue(ContactsContract.CommonDataKinds.Phone.TYPE, ContactsContract.CommonDataKinds.Phone.TYPE_MOBILE).build());
        try {
            getApplicationContext().getContentResolver().
                    applyBatch(ContactsContract.AUTHORITY, contentProviderOperations);
        } catch (RemoteException e) {
            e.printStackTrace();
        } catch (OperationApplicationException e) {
            e.printStackTrace();
        }
    }
}
TestSyncService

package com.test.contactsynctest;

import android.accounts.Account;
import android.app.Service;
import android.content.AbstractThreadedSyncAdapter;
import android.content.ContentProviderClient;
import android.content.Context;
import android.content.Intent;
import android.content.SyncResult;
import android.os.Bundle;
import android.os.IBinder;

public class TestSyncService extends Service {

    private static SyncAdapterImpl syncAdapter = null;

    @Override
    public IBinder onBind(Intent intent) {
        if (syncAdapter == null) {
            syncAdapter = new SyncAdapterImpl(this);
        }
        return syncAdapter.getSyncAdapterBinder();
    }

    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {

        public SyncAdapterImpl(Context context) {
            super(context, true);
        }

        @Override
        public void onPerformSync(Account account, Bundle extra, String authority, ContentProviderClient provider, SyncResult result) {
            // nothing needed here for this test
        }

    }
}
在我的xml目录中,我有以下文件

帐户验证器

syncadapter\u contacts.xml

<?xml version="1.0" encoding="utf-8"?>
<sync-adapter xmlns:android="http://schemas.android.com/apk/res/android"
              android:accountType="com.test.contactsynctest"
              android:contentAuthority="com.android.contacts"
              android:supportsUploading="true"
    />

account_preferences.xml

<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen>

</PreferenceScreen>


我测试了一些其他应用程序,发现Android 7和Android 8之间的行为不一致——例如,Android 7.x上的yahoo应用程序没有出现在左边抽屉的快速帐户切换列表中,而Android 8.0上运行的yahoo应用程序和Contacts应用程序的完全相同版本在列表中显示了yahoo帐户。所有gmail帐户都会在联系人应用程序帐户切换程序中随时显示,但其他帐户会有所不同。

你能在联系人应用程序中发布你想显示的帐户列表的屏幕截图吗?我似乎没有发布图像的能力,但如果你查看playstore列表,然后查看他们的照片,其中有一个标题为“按帐户查看您的联系人“这就是我希望看到我的帐户出现的地方。我希望只有谷歌帐户出现在帐户切换程序中,就像所有谷歌应用程序一样,谷歌实现的侧栏通常让你在不同的谷歌帐户之间切换,我从来没有在那里看到过任何其他帐户。我见过其他几个帐户,包括Yahoo mail,因此它绝对不限于Google帐户。你能发布一个显示Yahoo电子邮件的侧边栏截图吗?你可以使用雅虎电子邮件创建一个谷歌帐户,也许这就是你看到的?你可以在联系人应用程序中发布你想显示的帐户列表的屏幕截图吗?我似乎没有能力发布图像,但如果你查看playstore列表,然后查看他们的照片,其中有一个标题为“按帐户查看你的联系人”这就是我希望看到我的账户出现的地方。我希望只有谷歌账户出现在账户切换程序中,就像所有谷歌应用一样,谷歌实现的侧栏通常让你在不同的谷歌账户之间切换,我从来没有在那里看到过任何其他帐户。我见过其他几个帐户,包括Yahoo mail,因此它绝对不限于Google帐户。你能发布一个显示Yahoo电子邮件的侧边栏截图吗?你可以用雅虎的电子邮件创建一个谷歌账户,也许这就是你看到的?
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen>

</PreferenceScreen>