在Android上重命名帐户(AccountManager)

在Android上重命名帐户(AccountManager),android,android-contacts,accountmanager,batch-rename,Android,Android Contacts,Accountmanager,Batch Rename,我正在更改已发布应用程序的名称 是否有一种快速而安全的方法来更改通过AccountManager.addaccountexplicit创建的帐户名,以便现有用户的现有信息保持不变 如果没有,我如何在保留所有数据的同时手动更改帐户名 我将发布一个关于我复制所有内容然后删除旧内容的幼稚方法的答案,但我相信有人会想出一个更好的方法(或者在我的方法中发现一些错误)。一个幼稚的方法,检查所有记录,一个接一个地复制它们,然后删除所有旧内容 我真的很担心这种方法在现实世界的用户身上可能会失败 private

我正在更改已发布应用程序的名称

是否有一种快速而安全的方法来更改通过
AccountManager.addaccountexplicit
创建的帐户名,以便现有用户的现有信息保持不变

如果没有,我如何在保留所有数据的同时手动更改帐户名


我将发布一个关于我复制所有内容然后删除旧内容的幼稚方法的答案,但我相信有人会想出一个更好的方法(或者在我的方法中发现一些错误)。

一个幼稚的方法,检查所有记录,一个接一个地复制它们,然后删除所有旧内容

我真的很担心这种方法在现实世界的用户身上可能会失败

private void naiveRename(ContentResolver resolver) {
    ArrayList<ContentProviderOperation> operationList = new ArrayList<ContentProviderOperation>();
    Cursor cur = resolver.query(RawContacts.CONTENT_URI, null, RawContacts.ACCOUNT_NAME + "='"
            + "OLD NAME" + "'", null, null);
    if (cur != null) {

        // copy all data
        while (cur.moveToNext()) {
            Uri curUri = RawContacts.CONTENT_URI.buildUpon()
                    .appendQueryParameter(ContactsContract.CALLER_IS_SYNCADAPTER, "true")
                    .build();
            ContentProviderOperation.Builder builder = ContentProviderOperation
                    .newInsert(curUri);

            for (int i = 0; i < cur.getColumnCount(); i++) {
                String colName = cur.getColumnName(i);

                if (RawContacts._ID.equals(colName) || RawContacts.VERSION.equals(colName)
                        || RawContacts.CONTACT_ID.equals(colName)) {
                    // Skip - read only
                } else if (RawContacts.ACCOUNT_NAME.equals(colName)) {
                    builder.withValue(RawContacts.ACCOUNT_NAME, "NEW NAME");
                } else {
                    builder.withValue(colName, cur.getString(i));
                }
            }
            operationList.add(builder.build());
        }

        // delete all old data
        ContentProviderOperation.Builder builder = ContentProviderOperation
                .newDelete(RawContacts.CONTENT_URI);
        builder.withSelection(RawContacts.ACCOUNT_NAME + "='" + "OLD NAME" + "'", null);

            try {
                resolver.applyBatch(ContactsContract.AUTHORITY, operationList);
            } catch (RemoteException e) {
                // PANIC!
            } catch (OperationApplicationException e) {
                // OMG! WHAT TO DO?!
            }
        } else {
            // LORDI!
        }
    }
private void解析程序(ContentResolver解析程序){
ArrayList operationList=新建ArrayList();
Cursor cur=resolver.query(RawContacts.CONTENT\u URI,null,RawContacts.ACCOUNT\u NAME+“=”)
+“旧名称”+“”,空,空);
如果(cur!=null){
//复制所有数据
while(cur.moveToNext()){
Uri curUri=RawContacts.CONTENT\u Uri.buildon()
.appendQueryParameter(contacts contract.CALLER\u是\u SYNCADAPTER,“true”)
.build();
ContentProviderOperation.Builder=ContentProviderOperation
.newInsert(curUri);
对于(int i=0;i
API v21在
AccountManager
中添加了一个方法,如果有帮助的话

从文档中:

这相当于删除现有帐户并添加新帐户 使用旧帐户的用户数据重命名帐户

这意味着为了向后兼容,您必须手动删除该帐户,然后执行与创建新帐户相同的过程(
AccountManager.addaccountexplicit()
AccountManager.setUserData()

编辑: 如果要在以后更新联系人以显示正确的帐户名,请尝试以下(未测试)代码:


这似乎不起作用。。。在Accounts&sync以及联系人数据中,我仍然将旧名称视为帐户。我将此标记为答案,因为这是我所做的,坏事情发生的可能性大于更改“accounts&sync”上的文本的好处,因此我们支持这样做。我猜这失败了,因为您正在重命名每个联系人中的
ACCOUNT\u NAME
字段,而不是帐户本身。联系人通常与
AccountManager
管理的帐户无关。请看我的答案。很好的新api,谢谢。这是否也会修改联系人表,使旧帐户下保存的所有联系人现在都保存在新帐户下?我不认为这是自动完成的,因为您基本上创建了一个新帐户,它没有引用旧帐户。联系人提供商不知道发生了什么。我在答案中添加了一些代码来手动更新这些值。请看这是否有效。好吧,这是一个非常老的问题,所以我无法检查代码,虽然它看起来很有希望,但我会将其标记为可接受的世代。根据我的经验,在重命名帐户之前,您需要使用@saschoar提供的代码更新数据库,否则联系人将被删除。
ContentValues contentValues = new ContentValues();
contentValues.put(ContactsContract.RawContacts.ACCOUNT_NAME, "new account name");
getContext().getContentResolver().update(ContactsContract.RawContacts.CONTENT_URI,
        contentValues,
        ContactsContract.RawContacts.ACCOUNT_TYPE + " = ? AND " + ContactsContract.RawContacts.ACCOUNT_NAME + " = ?",
        new String[]{"your account type", "old account name"});