mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-11 20:15:03 -05:00
7028a4c167
- Removed the contact names cache (memory leak) - Changed Contacts.searchByAddress() to Contacts.getNameForAddress(). Cursor is now immediately closed. - Only try to resolve contact names when "Global settings" -> "Show contact name" is checked - Never resolve contact names if number of recipients exceeds a threshold
220 lines
6.0 KiB
Java
220 lines
6.0 KiB
Java
package com.fsck.k9.helper;
|
|
|
|
import android.app.Activity;
|
|
import android.content.Context;
|
|
import android.content.Intent;
|
|
import android.database.Cursor;
|
|
import android.net.Uri;
|
|
import android.provider.Contacts;
|
|
import com.fsck.k9.mail.Address;
|
|
|
|
/**
|
|
* Access the contacts on the device using the old API (introduced in SDK 1).
|
|
*
|
|
* @see android.provider.Contacts
|
|
*/
|
|
@SuppressWarnings("deprecation")
|
|
public class ContactsSdk3_4 extends com.fsck.k9.helper.Contacts
|
|
{
|
|
/**
|
|
* The order in which the search results are returned by
|
|
* {@link #searchContacts(CharSequence)}.
|
|
*/
|
|
private static final String SORT_ORDER =
|
|
Contacts.People.TIMES_CONTACTED + " DESC, " +
|
|
Contacts.People.NAME;
|
|
|
|
/**
|
|
* Array of columns to load from the database.
|
|
*
|
|
* Important: The _ID field is needed by
|
|
* {@link com.fsck.k9.EmailAddressAdapter} or more specificly by
|
|
* {@link android.widget.ResourceCursorAdapter}.
|
|
*/
|
|
private static final String PROJECTION[] =
|
|
{
|
|
Contacts.People.ContactMethods._ID,
|
|
Contacts.People.ContactMethods.NAME,
|
|
Contacts.People.ContactMethods.DATA
|
|
};
|
|
|
|
/**
|
|
* Index of the name field in the projection. This must match the order in
|
|
* {@link #PROJECTION}.
|
|
*/
|
|
private static final int NAME_INDEX = 1;
|
|
|
|
/**
|
|
* Index of the email address field in the projection. This must match the
|
|
* order in {@link #PROJECTION}.
|
|
*/
|
|
private static final int EMAIL_INDEX = 2;
|
|
|
|
|
|
public ContactsSdk3_4(final Context context)
|
|
{
|
|
super(context);
|
|
}
|
|
|
|
@Override
|
|
public void createContact(final Activity activity, final Address email)
|
|
{
|
|
final Uri contactUri = Uri.fromParts("mailto", email.getAddress(), null);
|
|
|
|
final Intent contactIntent = new Intent(Contacts.Intents.SHOW_OR_CREATE_CONTACT);
|
|
contactIntent.setData(contactUri);
|
|
|
|
// Pass along full E-mail string for possible create dialog
|
|
contactIntent.putExtra(Contacts.Intents.EXTRA_CREATE_DESCRIPTION,
|
|
email.toString());
|
|
|
|
// Only provide personal name hint if we have one
|
|
final String senderPersonal = email.getPersonal();
|
|
if (senderPersonal != null)
|
|
{
|
|
contactIntent.putExtra(Contacts.Intents.Insert.NAME, senderPersonal);
|
|
}
|
|
|
|
activity.startActivity(contactIntent);
|
|
}
|
|
|
|
@Override
|
|
public String getOwnerName()
|
|
{
|
|
String name = null;
|
|
final Cursor c = mContentResolver.query(
|
|
Uri.withAppendedPath(Contacts.People.CONTENT_URI, "owner"),
|
|
PROJECTION,
|
|
null,
|
|
null,
|
|
null);
|
|
|
|
if (c != null)
|
|
{
|
|
if (c.getCount() > 0)
|
|
{
|
|
c.moveToFirst();
|
|
name = c.getString(NAME_INDEX);
|
|
}
|
|
c.close();
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public boolean isInContacts(final String emailAddress)
|
|
{
|
|
boolean result = false;
|
|
|
|
final String where = Contacts.ContactMethods.DATA + "=?";
|
|
final String[] args = new String[] {emailAddress};
|
|
|
|
final Cursor c = mContentResolver.query(
|
|
Contacts.ContactMethods.CONTENT_EMAIL_URI,
|
|
PROJECTION,
|
|
where,
|
|
args,
|
|
null);
|
|
|
|
if (c != null)
|
|
{
|
|
if (c.getCount() > 0)
|
|
{
|
|
result = true;
|
|
}
|
|
c.close();
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
@Override
|
|
public Cursor searchContacts(final CharSequence constraint)
|
|
{
|
|
final String where;
|
|
final String[] args;
|
|
if (constraint == null)
|
|
{
|
|
where = null;
|
|
args = null;
|
|
}
|
|
else
|
|
{
|
|
where = "(" +
|
|
Contacts.People.NAME + " LIKE ?" +
|
|
") OR (" +
|
|
Contacts.ContactMethods.DATA + " LIKE ?" +
|
|
")";
|
|
final String filter = constraint.toString() + "%";
|
|
args = new String[] {filter, filter};
|
|
}
|
|
|
|
final Cursor c = mContentResolver.query(
|
|
Contacts.ContactMethods.CONTENT_EMAIL_URI,
|
|
PROJECTION,
|
|
where,
|
|
args,
|
|
SORT_ORDER);
|
|
|
|
if (c != null)
|
|
{
|
|
/*
|
|
* To prevent expensive execution in the UI thread:
|
|
* Cursors get lazily executed, so if you don't call anything on
|
|
* the cursor before returning it from the background thread you'll
|
|
* have a complied program for the cursor, but it won't have been
|
|
* executed to generate the data yet. Often the execution is more
|
|
* expensive than the compilation...
|
|
*/
|
|
c.getCount();
|
|
}
|
|
|
|
return c;
|
|
}
|
|
|
|
@Override
|
|
public String getNameForAddress(String address)
|
|
{
|
|
if (address == null)
|
|
{
|
|
return null;
|
|
}
|
|
|
|
final String where = Contacts.ContactMethods.DATA + " = ?";
|
|
final String[] args = new String[] {address};
|
|
|
|
final Cursor c = mContentResolver.query(
|
|
Contacts.ContactMethods.CONTENT_EMAIL_URI,
|
|
PROJECTION,
|
|
where,
|
|
args,
|
|
SORT_ORDER);
|
|
|
|
String name = null;
|
|
if (c != null)
|
|
{
|
|
if (c.getCount() > 0)
|
|
{
|
|
c.moveToFirst();
|
|
name = getName(c);
|
|
}
|
|
c.close();
|
|
}
|
|
|
|
return name;
|
|
}
|
|
|
|
@Override
|
|
public String getName(Cursor c)
|
|
{
|
|
return c.getString(NAME_INDEX);
|
|
}
|
|
|
|
@Override
|
|
public String getEmail(Cursor c)
|
|
{
|
|
return c.getString(EMAIL_INDEX);
|
|
}
|
|
}
|