首页 > 解决方案 > 我的应用程序创建的联系人没有编辑选项导出到电话簿中的本机联系人

问题描述

我正在开发一个应用程序,它允许您在应用程序中创建联系人,您可以使用联系人提供程序将其导出到本机联系人数据库,并且我正在使用我的应用程序将我的联系人同步到服务器。

我正在使用 SyncAdapter 来实现 2 路联系人同步。我已经创建了一个帐户AccountNameAccountType使用AuthenticatorService

public class AuthenticationService extends Service {

    private Authenticator mAuthenticator;

    public AuthenticationService() {
        mAuthenticator = new Authenticator(this);
    }


    public class Authenticator extends AbstractAccountAuthenticator {
        // Simple constructor
        public Authenticator(Context context) {
            super(context);
        }
        @Override
        public Bundle editProperties(AccountAuthenticatorResponse response, String accountType) {
            return null;
        }

        @Override
        public Bundle addAccount(AccountAuthenticatorResponse response, String accountType, String authTokenType, String[] requiredFeatures, Bundle options) throws NetworkErrorException {
            return null;
        }

        @Override
        public Bundle confirmCredentials(AccountAuthenticatorResponse response, Account account, Bundle options) throws NetworkErrorException {
            return null;
        }

        @Override
        public Bundle getAuthToken(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
            return null;
        }

        @Override
        public String getAuthTokenLabel(String authTokenType) {
            return null;
        }

        @Override
        public Bundle updateCredentials(AccountAuthenticatorResponse response, Account account, String authTokenType, Bundle options) throws NetworkErrorException {
            return null;
        }

        @Override
        public Bundle hasFeatures(AccountAuthenticatorResponse response, Account account, String[] features) throws NetworkErrorException {
            return null;
        }
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return mAuthenticator.getIBinder();
    }
}

下面是我的authenticator.xml

<?xml version="1.0" encoding="utf-8"?>
<account-authenticator
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:accountType="com.contacts.example"
    android:icon="@drawable/ico_reply_all_svg"
    android:smallIcon="@drawable/ic_launcher_background"
    android:label="@string/app_name"/>

下面是我的ContactSyncAdapterService

public class ContactSyncService extends Service {

    private static SyncAdapterImpl sSyncAdapter = null;
    private static final Object sSyncAdapterLock = new Object();
    private static Context mContext;
    private static ContentResolver cr;

    private static class SyncAdapterImpl extends AbstractThreadedSyncAdapter {


        public SyncAdapterImpl(Context context,ContentResolver c) {
            super(context, true);
            mContext = context;
            cr = c;
        }

        @Override
        public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
            Log.d("TEST", "onPerformSync Called");
            // run sync with server
        }
    }

    @Override
    public void onCreate() {
        super.onCreate();
        synchronized (sSyncAdapterLock) {
            if(sSyncAdapter == null) {
                sSyncAdapter = new SyncAdapterImpl(getApplicationContext(), getContentResolver());
            }
        }
    }

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

syncadapter.xml

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

下面是我如何使用我的accountNameaccountType

public void addContact() {

        ArrayList<ContentProviderOperation> ops =
                new ArrayList<ContentProviderOperation>();

        int rawContactInsertIndex = ops.size();
        ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
                .withValue(RawContacts.ACCOUNT_TYPE, "com.contacts.example")
                .withValue(RawContacts.ACCOUNT_NAME, "dummyaccount1")
                .withValue(RawContacts.RAW_CONTACT_IS_READ_ONLY, "0")
                .build());

        ops.add(ContentProviderOperation.newInsert(Data.CONTENT_URI)
                .withValueBackReference(Data.RAW_CONTACT_ID, rawContactInsertIndex)
                .withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE)
                .withValue(StructuredName.DISPLAY_NAME, "DoomsDay2")
                .withValue(Data.IS_READ_ONLY, 0")
                .build());
        try {
            getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

帐户创建代码如下:

public static Account CreateSyncAccount(Context context) {

        public static final String ACCOUNT_TYPE = "com.contacts.example";
        // The account name
        public static final String ACCOUNT_NAME = "dummyaccount1";
        // Create the account type and default account
        Account newAccount = new Account(
                ACCOUNT_NAME, ACCOUNT_TYPE);
        // Get an instance of the Android account manager
        AccountManager accountManager =
                (AccountManager) context.getSystemService(
                        ACCOUNT_SERVICE);
        /*
         * Add the account and account type, no password or user data
         * If successful, return the Account object, otherwise report an error.
         */
        if (accountManager.addAccountExplicitly(newAccount, null, null)) {
            /*
             * If you don't set android:syncable="true" in
             * in your <provider> element in the manifest,
             * then call context.setIsSyncable(account, AUTHORITY, 1)
             * here.
             */
        } else {
            /*
             * The account exists or some other error occurred. Log this, report it,
             * or handle it internally.
             */
        }
        return newAccount;
    }

以下是面临的问题:

  1. 导出的联系人在本机联系人应用程序中可见。但我无法使用本机联系人应用程序编辑这些联系人。根本没有编辑选项。它说它们是只读的。
  2. 我想在本机应用程序中编辑这些联系人并运行 syncadapter,以便我可以将这些修改后的联系人获取回我的应用程序,从而获取服务器。
  3. 是 OEM 特定的吗?我尝试了许多不同的设备,但行为是相同的。
  4. 这甚至可能吗?我们只能编辑设备使用添加帐户添加的那些帐户联系人(就像我们为谷歌联系人添加的那样)?

请帮我解决这个问题!!提前致谢。

标签: androidcontactsandroid-contactsandroid-syncadapter

解决方案


推荐阅读