java.lang.IllegalArgumentException: Invalid lookup id

参看官方文档:http://developer.android.com/guide/topics/providers/contacts-provider.html#Access 的Retrieval and modification with intents 部分

本文讨论的是编辑指定的联系人,否则你应该使用Intent.ACTION_INSERT_OR_EDIT

涉及到的Action是:Intent.ACTION_EIDT
涉及到的Provider契约类常量是:
Contacts.CONTENT_LOOKUP_URI  指定相关联系人的URI
Contacts.CONTENT_ITEM_TYPE  指定联系人的MIME类型

重点是如何构建一个指定联系人的Contacts.CONTENT_LOOKUP_URI

官网对Contacts.CONTENT_LOOKUP_URI的说明是:

A content:// style URI for this table that should be used to create shortcuts or otherwise create long-term links to contacts. This URI should always be followed by a "/" and the contact's LOOKUP_KEY. It can optionally also have a "/" and last known contact ID appended after that. This "complete" format is an important optimization and is highly recommended.

As long as the contact's row ID remains the same, this URI is equivalent to CONTENT_URI. If the contact's row ID changes as a result of a sync or aggregation, this URI will look up the contact using indirect information (sync IDs or constituent raw contacts).

Lookup key should be appended unencoded - it is stored in the encoded form, ready for use in a URI.

以上大致意思是,可以通过如下两种方式构建:

第一种:

?
1
2
3
Uri content_lookup_uri = UriContentUris.withAppendedId(Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,lookupKey), contactId);
// contactId为可选参数,可用直接写成如下形式
Uri content_lookup_uri = Uri.withAppendedPath(Contacts.CONTENT_LOOKUP_URI,lookupKey);

第二种:

?
1
2
3
4
5
6
Uri content_lookup_uri = UriContentUris.withAppendedId(Contacts.CONTENT_URI,contactId);
/*
注意:这里用的是Contacts.CONTENT_URI不是Contacts.CONTENT_LOOKUP_URI,否则会出现异常:
ContactLoader﹕ Error loading the contact: content://com.android.contacts/contacts/lookup/159
     java.lang.IllegalArgumentException: Invalid lookup id: 159
*/

首先是如何获得联系人的LOOKUP_KEY和ID,通常情况下,当你使用Intent.ACTION_EDIT方式时,说明你已经拿到了一个CONTENT_LOOKUP_URI,为了对以上代码跟好的说明和方便起见我们通过如下代码块打开联系人应用,从中挑选一个联系人加以说明:

?
1
2
3
4
5
6
7
8
9
10
public static final int REQUEST_CODE = 1 ;
//...........
Intent pick_Contact = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(pick_Contact, REQUEST_CODE);
 
@Override
     protected void onActivityResult( int requestCode, int resultCode, Intent data) {
         Uri content_lookup_uri = data.getData(); // 这里拿到的content_lookup_uri 就是采用第一种方式构建的
         super .onActivityResult(requestCode, resultCode, data);
     }

通过以上步骤就拿到了content_lookup_uri,通过下面代码块来对指定联系人进行编辑

?
1
2
3
4
5
6
7
8
9
10
11
12
Intent editIntent = new Intent(Intent.ACTION_EDIT);
/*
注意:当既要给Intent设置Data属性又要设置Type属性时,必须使用setDataAndType()方法
否则会得到异常:
(Error loading the contact: null java.lang.IllegalArgumentException: uri must not null)
例如,使用setData()然后再使用setType(),后者方法会清除前者设置的属性。或者在new Intent对象时,使用的构造方法是:
Intent(String action, Uri uri)或者
Intent(String action, Uri uri,Context packageContext, Class cls)然后使用setType()设置的属性
以上请参见源码注释或文档
*/
editIntent.setDataAndType(content_lookup_uri2,ContactsContract.Contacts.CONTENT_ITEM_TYPE);
startActivity(editIntent);

当然多数时候我们直接使用Intent.ACTION_INSERT_OR_EDIT来编辑联系人 本文只是讨论在使用Intent.ACTION_EDIT时的注意事项


原文:http://my.oschina.net/artshell/blog/324871

你可能感兴趣的:(android开发)