I am new to Android programming and I'm working on an Activity in an app that will plot the location of contacts from a specific email account on to a map. The following is what I in a class that the Activity will use to get the Contact info I want to use when plotting the location. I have tested this and it works. But as I researched the possible ways to pull this off (and how to program with Android in general). I have found that best practice is to optimize your code. I have two questions I want to ask.
First, is there a more optimized way of getting the name, full address, and geopoints of a contact from a specific email account (like an exchange email)?
my class file:
import java.util.ArrayList;
import java.util.List;
import com.google.android.maps.GeoPoint;
import android.database.Cursor;
import android.location.Address;
import android.location.Geocoder;
import android.provider.ContactsContract;
import android.content.ContentResolver;
import android.content.Context;
public class Contacts {
ArrayList<String> nameList = new ArrayList<String>();
ArrayList<String> locList = new ArrayList<String>();
ArrayList<GeoPoint> geoList = new ArrayList<GeoPoint>();
Context context = null;
Geocoder gc;
private String getContactName(String id){
String name = null;
ContentResolver nmCr = context.getContentResolver();
String selection = ContactsContract.Contacts._ID + " = ?";
String[] selectionArgs = new String[]{id};
String[] projection = new String[]{
ContactsContract.Contacts.DISPLAY_NAME
};
Cursor nmCur = nmCr.query(ContactsContract.Contacts.CONTENT_URI,
projection, selection, selectionArgs, null);
if (nmCur.getCount() > 0)
{
while (nmCur.moveToNext())
{
//if the account is under com.android.exchange and not com.google
// Pick out the ID, and the Display name of the
// contact from the current row of the cursor
name = nmCur.getString(nmCur.getColumnIndex(
ContactsContract.Contacts.DISPLAY_NAME));
}
}
nmCur.close();
return name;
}
public String getContactLocations(String id){
String addr = null;
ContentResolver addrCr = context.getContentResolver();
String selection = ContactsContract.CommonDataKinds.StructuredPostal.CONTACT_ID + " = ?";
String[] selectionArgs = new String[]{id};
String[] projection = new String[]{
ContactsContract.CommonDataKinds.StructuredPostal.STREET,
ContactsContract.CommonDataKinds.StructuredPostal.CITY,
ContactsContract.CommonDataKinds.StructuredPostal.REGION,
ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE
};
Cursor addrCur = addrCr.query(ContactsContract.CommonDataKinds.StructuredPostal.CONTENT_URI,
projection, selection, selectionArgs, null);
if (addrCur.getCount() > 0)
{
while(addrCur.moveToNext()) {
addr = addrCur.getString(
addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.STREET));
addr += " " + addrCur.getString(
addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.CITY));
addr += " " + addrCur.getString(
addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.REGION));
addr += " " + addrCur.getString(
addrCur.getColumnIndex(ContactsContract.CommonDataKinds.StructuredPostal.POSTCODE));
}
}
addrCur.close();
return addr;
}
public GeoPoint getContactGeo(String addr){
GeoPoint p = null;
gc = new Geocoder(context); //create new geocoder instance
try {
List<Address> foundAdresses = gc.getFromLocationName(addr, 5); //Search addresses
for (int i = 0; i < foundAdresses.size(); ++i) {
//Save results as Longitude and Latitude
Address x = foundAdresses.get(i);
p = new GeoPoint((int)(x.getLatitude() * 1E6),(int)(x.getLongitude() * 1E6));
}
}
catch (Exception e) {
e.printStackTrace();
}
return p;
}
public void getContactNames( Context context, String email){
this.context = context;
ContentResolver cr = context.getContentResolver();
String[] projection = new String[]{
ContactsContract.RawContacts.CONTACT_ID
};
String selection = ContactsContract.RawContacts.ACCOUNT_NAME + " = ? AND " + ContactsContract.RawContacts.ACCOUNT_TYPE + " = ?";
String[] selectionArgs = new String[]{
email,
"com.android.exchange"
};
Cursor cur = cr.query(ContactsContract.RawContacts.CONTENT_URI,
projection, selection, selectionArgs, null);
if (cur.getCount() > 0)
{
while (cur.moveToNext())
{
String id = cur.getString(cur.getColumnIndex(ContactsContract.RawContacts.CONTACT_ID));
nameList.add(
getContactName(id)
);
String addr = getContactLocations(id);
locList.add(addr);
geoList.add(getContactGeo(addr));
}
}
cur.close();
}
}
Second, right now, to use the data coming back from this file, I am calling this class's ArrayList
s after executing c.getContactNames(this, email);
in my Activity.
Looks like this:
c.getContactNames(this, sale.smtpEmail);
MapArray = MapView.getOverlays();
for (int i = 0; i < c.nameList.size(); i++) {
OverlayItem overlayitem = null;
drawable = new BitmapDrawable(mar.marker(i, this));
itemizedOverlay = new MapsItemizedOverlay(drawable, this);
if(c.locList.get(i) != null){
overlayitem = new OverlayItem(c.geoList.get(i), c.nameList.get(i), c.locList.get(i));
itemizedOverlay.addOverlay(overlayitem);
MapArray.add(itemizedOverlay);
}
}
Which I am doing so I create unnecessary objects. Is this best practice?