2

I have the following piece of code in my Android application that looks up a contacts ID, I have just changed the target from 1.5 to 2.2 but with a min SDK of 3 (1.5) so that I can use the ContactsContract Uri in 2.2 and the People Uri in 1.5.

However the code leads to the following error when run on 1.5 devices:

07-27 15:02:53.382: WARN/dalvikvm(12656): VFY: unable to resolve static field 25 (CONTENT_URI) in Landroid/provider/ContactsContract$Contacts;

From google I have garnered that I need to use reflection in this case to allow the application run on both versions of Android?

I have seen example's of how to use reflection to use methods of multiple/different versions but how can I use it in mycase where I want to use the ContactsContract Uri?

Here is my code:


findViewById(R.id.contactimage).setOnClickListener(new OnClickListener() {
                public void onClick(View v) {

                    String sdk = android.os.Build.VERSION.SDK;
                    Uri contactUri;
                    Log.d("CDA", "Contact ID Button pressed = " + contactId);
                    if(sdk.equals("8")){
                        contactUri = ContentUris.withAppendedId
                        (ContactsContract.Contacts.CONTENT_URI, contactId);

                        Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
                        startActivity(intent);

                    }
                    else{
                    contactUri = ContentUris.withAppendedId
                    (People.CONTENT_URI, contactId);

                    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
                    startActivity(intent);
                    }

                    dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN,KeyEvent.FLAG_SOFT_KEYBOARD));
                    dispatchKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK));
                }
        });

EDIT:

Here is an example of how its done:

private static Uri CONTENT_URI=null;
private static String NAME_URI=null;
private static String ID_URI=null;
private static String NUMBER_URI = null;
private static Uri PHONE_LOOKUP = null;
static int sdk;
 static {
     sdk=new Integer(Build.VERSION.SDK).intValue();

     if (sdk>=5) {
     try {
     Class clazz=Class.forName("android.provider.ContactsContract$CommonDataKinds$Phone");
     Class clazz_phonelookup=Class.forName("android.provider.ContactsContract$PhoneLookup");

     NAME_URI=(String)clazz.getField("DISPLAY_NAME").get(clazz);
     ID_URI=(String)clazz.getField("_ID").get(clazz);

     NUMBER_URI=(String)clazz.getField("NUMBER").get(clazz);
     PHONE_LOOKUP =(Uri)clazz_phonelookup.getField("CONTENT_FILTER_URI").get(clazz);


     }
     catch (Throwable t) {
     Log.e("reflection", "Exception when determining CONTENT_URI", t);
     }
     }
     else {
     CONTENT_URI=Contacts.People.CONTENT_URI;

     NAME_URI=People.NAME;
     ID_URI=People._ID;

     NUMBER_URI=People.NUMBER;
     PHONE_LOOKUP = null;

     }
     }
Donal Rafferty
  • 19,707
  • 39
  • 114
  • 191
  • 1
    You'll have to wrap any of the SDK-version-specific code in a wrapper class, most likely. This is a duplicate of this SO question from 5 months ago, though: http://stackoverflow.com/questions/2312321/how-to-use-contacts-api-for-android-1-x-and-2-x-simultaneously – Yoni Samlan Jul 27 '10 at 14:28

1 Answers1

1

This demo from the documentation defines a parent class for two different SDK-specific classes that work for API levels 3/4 and API levels 5+.

This helped me understand the differences between Contacts and ContactsContract, and allows for usage of both implicitly by getting the OS API level in the wrapper class.

http://developer.android.com/resources/samples/BusinessCard/index.html

Hope this helps!

Codeman
  • 12,157
  • 10
  • 53
  • 91
  • If you find an answer correct, please upvote it as well as marking it correct. That said, glad I could help! I'd been struggling with the same thing recently. – Codeman Jun 30 '11 at 18:06