среда, 15 июня 2011 г.

Using the Contact Picker. Getting phone and send sms

How to get email or phone from contacts and use it in your app?
This tutorial will start out simple, but then we’ll get in to some of the technical details of using Contacts with the ContactsContract class, which was introduced in API Level 5.

Step 1: Launching the Contact Picker

import android.provider.ContactsContract.Contacts;  
import android.provider.ContactsContract.CommonDataKinds.Phone;  

private static final int CONTACT_PICKER_RESULT = 1001;  
  
public void doLaunchContactPicker(View view) {  
    Intent contactPickerIntent = new Intent(Intent.ACTION_PICK,  
            Contacts.CONTENT_URI);  
    startActivityForResult(contactPickerIntent, CONTACT_PICKER_RESULT);  
}

Once launched, the contacts picker in your application will look something like this:


Step 2: Handling the Results

Now you are ready to handle the results of the picker. Once the user taps on one of the contacts in the picker, focus will return to the calling Activity (your application’s Activity). You can grab the result from the contacts picker by implementing the onActivityResult() method of your Activity. Here you can check that the result matches your requestCode and that the result was good. Your onActivityResult() method implementation should be structured like this:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {  
    if (resultCode == RESULT_OK) {  
        switch (requestCode) {  
        case CONTACT_PICKER_RESULT:  
            // handle contact results  
            break;  
        }  
  
    } else {  
        // gracefully handle failure  
        Log.w(DEBUG_TAG, "Warning: activity result not ok");  
    }  
} 

You’ll get a result other than RESULT_OK if the user cancels the operation or if something else goes wrong.

Step 3: Reading the Result Data

The final parameter to onActivityResult is an Intent called “data.” This parameter contains the results data we are looking for. Different Intents will return different types of results. One option for inspecting the results is to display everything found in the Extras bundle in addition to the data Uri. Here’s a code snippet that will show all of the Extras, should any exist:

Bundle extras = data.getExtras();  
Set keys = extras.keySet();  
Iterator iterate = keys.iterator();  
while (iterate.hasNext()) {  
    String key = iterate.next();  
    Log.v(DEBUG_TAG, key + "[" + extras.get(key) + "]");  
}  
Uri result = data.getData();  
Log.v(DEBUG_TAG, "Got a result: "  + result.toString());

We’re not really interested in the Extras bundle for the contacts picker because it doesn’t contain the information we need. We just want the Uri which will lead us to the important contact details.

Step 4: Understanding the Result

In the onActivityResult() callback, we are supplied the Uri to the specific contact that the user chose from the contact picker. Using this Uri directly would allow us to get the basic Contact data, but no details. However, we are interested in determining the phone number of the contact. So, an easy way to deal with this is to just grab the contact id from the Uri, which is the number at the end of the path:
The full Uri looks something like:

content://com.android.contacts/contacts/lookup/0r7-2C46324E483C324A3A484634/235

In this case, the resulting id would simply be 235.
We can retrieve the contact identifier using the getLastPathSegment() method, as follows:

// get the contact id from the Uri  
String id = result.getLastPathSegment();

Step 5: Querying the Contacts Database for Phone

Now that you have the identifier for the chosen contact, you have all the information you need to query the Contacts content provider directly for that contact’s phone number. Android content providers are a powerful way of sharing data amongst applications. The interface to them is similar to that of a database and many are database backed, using SQLite, but they need not be.
One way you can query the contacts content provider for the appropriate contact details is by using the default ContentResolver with one of the ContactsContract.CommonDataKinds subclasses. For phone, you can use the ContactsContract.CommonDataKinds.Phone class as follows:
// query for everything phone  
cursor = getContentResolver().query(  
        Phone.CONTENT_URI, null,  
        Phone.CONTACT_ID + "=?",  
        new String[]{id}, null); 
Some other useful ContactsContract.CommonDataKinds subclasses include Email, Photo, Website, Nickname, Organization, and StructuredPostal.

Step 6: Viewing the Query Results

Certainly, you could read the class documentation for the ContactsContract.CommonDataKinds.Phone class and determine what kind of results to expect. However, this is not always the case so let’s inspect the results of this call. This is a very handy trick if you are working with a content provider that has less-than-adequate documentation, or is not behaving as expected.
This snippet of code will show you, via LogCat output, every column and value that is returned from the query to the content provider:

cursor.moveToFirst();  
String columns[] = cursor.getColumnNames();  
for (String column : columns) {  
    int index = cursor.getColumnIndex(column);  
    Log.v(DEBUG_TAG, "Column: " + column + " == [" + cursor.getString(index) + "]");

Now you can see that, indeed, they really did mean for the phone to come back via a column called DATA1, aliased to Phone.DATA. The Android Contacts system is very flexible, and this sort of generic column name shows where some of that flexibility comes from. The phone type, such as Home or Work, is found in Phone.TYPE.

Step 7: Retrieving the Phone

We have all of the data we need to actually get the phone number. When using database Cursors, we have to make sure they are internally referencing a data row we’re interested in, so we start with a call to the moveToFirst() method and make sure it was successful. For this tutorial, we won’t worry about multiple phone numbers. Instead, we’ll just use the first result:

if (cursor.moveToFirst()) {  
    int phoneIdx = cursor.getColumnIndex(Phone.DATA);  
    phone = cursor.getString(phoneIdx);  
    Log.v(DEBUG_TAG, "Got phone: " + phone);  
}

It’s important to remember that a contact may have many numbers. If you wanted to give the user the option of choosing from multiple phone numbers, you could display your own phone chooser to pick amongst these after the user has chosen a specific contact.

Step 8: Send SMS

Here’s a code snippet that will show Activity that allow you send sms with filled textbox and address:

Intent smsIntent = new Intent(Intent.ACTION_VIEW);
      smsIntent.setType("vnd.android-dir/mms-sms");
      smsIntent.putExtra("address", phoneNumber);
      smsIntent.putExtra("sms_body","Hello!");
      startActivity(smsIntent);

Step 9: Putting it All Together

We skipped over two important items in this tutorial that are worth mentioning now.
First, we didn’t include any error checking; we did this for clarity, but in production code, this is an essential piece of the solution. An easy way to implement some checking would be to to wrap just about everything in a try-catch block.
Second, you need to remember that Cursor objects require management within your Activity lifecycle. Always remember to release Cursor objects when you are done using them.
Here’s the complete implementation of the onActivityResult() method to put these points in perspective:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
         if (resultCode == RESULT_OK) {
             switch (requestCode) {
             case CONTACT_PICKER_RESULT:
              Uri result = data.getData();
              if(Constants.Debug) Log.v(DEBUG_TAG, "Got a result: " + result.toString()); 
              // get the contact id from the Uri  
              String id = result.getLastPathSegment();
              // query for everything phone  
              cursor = getContentResolver().query(  
                      Phone.CONTENT_URI, null,  
                      Phone.CONTACT_ID + "=?",  
                      new String[]{id}, null); 
              startManagingCursor(cursor);
              cursor.moveToFirst();  
              String columns[] = cursor.getColumnNames();  
              String phoneNumber = null;
              if (cursor.moveToFirst()) {  
                  int phoneIdx = cursor.getColumnIndex(Phone.DATA);  
                  phoneNumber = cursor.getString(phoneIdx);
                  if(Constants.Debug) Log.v(DEBUG_TAG, "Got phone: " + phoneNumber);
              }  
              if (!TextUtils.isEmpty(phoneNumber)){
               Intent smsIntent = new Intent(Intent.ACTION_VIEW);
      smsIntent.setType("vnd.android-dir/mms-sms");
      smsIntent.putExtra("address", phoneNumber);
      smsIntent.putExtra("sms_body","Hello!");
      startActivity(smsIntent);
              }
                 break;
             }

         } else {
             // gracefully handle failure
          if(Constants.Debug) Log.v(DEBUG_TAG, "Warning: activity result not ok");             
         }
 }

Комментариев нет:

Отправить комментарий