Merge change 26949 into eclair
* changes:
Fixed the font size in the dialer (increased the size).
diff --git a/res/values/strings.xml b/res/values/strings.xml
index f4e3465..d0c77b2 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -480,34 +480,38 @@
<!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled -->
- <string name="noContactsHelpText">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ <string name="noContactsHelpText">"You don't have any contacts to display.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
\n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
\n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
</string>
<!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled -->
- <string name="noContactsHelpTextWithSync">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
- \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which contact groups are visible\n</li>
+ <string name="noContactsHelpTextWithSync">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
+ \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which groups of contacts are visible\n</li>
\n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
\n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
</string>
<!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is disabled, and there is no sim card (cdma)-->
- <string name="noContactsNoSimHelpText">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ <string name="noContactsNoSimHelpText">"You don't have any contacts to display.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
\n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
\n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
</string>
<!-- Displayed full screen when the user has no contacts and they are displaying the My Contacts group, and contact syncing is enabled, and there is no sim card (cdma) -->
- <string name="noContactsNoSimHelpTextWithSync">"You don't have any contacts.\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
- \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which contact groups are visible\n</li>
+ <string name="noContactsNoSimHelpTextWithSync">"You don't have any contacts to display. (If you just added an account, it can take a few minutes to sync contacts.)\n\nTo add contacts, press <font fgcolor="#ffffffff"><b>Menu</b></font> and touch:\n
+ \n<li><font fgcolor="#ffffffff"><b>Accounts</b></font> to add or configure an account with contacts you can sync to the phone\n</li>
+ \n<li><font fgcolor="#ffffffff"><b>Display groups</b></font> to change which groups of contacts are visible\n</li>
\n<li><font fgcolor="#ffffffff"><b>New contact</b></font> to create a new contact from scratch\n</li>
\n<li><font fgcolor="#ffffffff"><b>Import/Export</b></font>\n</li>"
</string>
<!-- Displayed full screen when the user has no favorites and they are displaying the favorites tab -->
<string name="noFavoritesHelpText">"You don't have any favorites.\n\nTo add a contact to your list of favorites:\n
- <li>Touch the Contacts tab\n</li>
+ <li>Touch the <b>Contacts</b> tab\n</li>
\n<li>Touch the contact you want to add to your favorites\n</li>
\n<li>Touch the star next to the contact\'s name\n</li>"
</string>
diff --git a/src/com/android/contacts/ContactsListActivity.java b/src/com/android/contacts/ContactsListActivity.java
index d5f6857..5d5a944 100644
--- a/src/com/android/contacts/ContactsListActivity.java
+++ b/src/com/android/contacts/ContactsListActivity.java
@@ -17,13 +17,11 @@
package com.android.contacts;
import com.android.contacts.model.ContactsSource;
+import com.android.contacts.model.GoogleSource;
import com.android.contacts.model.Sources;
-import com.android.contacts.model.ContactsSource.DataKind;
-import com.android.contacts.model.ContactsSource.EditType;
import com.android.contacts.ui.DisplayGroupsActivity;
import com.android.contacts.ui.DisplayGroupsActivity.Prefs;
import com.android.contacts.util.Constants;
-import com.google.android.collect.Lists;
import android.accounts.Account;
import android.app.Activity;
@@ -64,7 +62,6 @@
import android.provider.Contacts.People;
import android.provider.Contacts.PeopleColumns;
import android.provider.Contacts.Phones;
-import android.provider.ContactsContract.CommonDataKinds;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.ContactsContract.Intents;
@@ -80,7 +77,6 @@
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.Log;
-import android.util.SparseArray;
import android.view.ContextMenu;
import android.view.ContextThemeWrapper;
import android.view.Gravity;
@@ -305,6 +301,15 @@
static final String KEY_PICKER_MODE = "picker_mode";
+ /*
+ * TODO: Will be commented in the really near future. Similar commented out codes will be done.
+ * These are for make vCard exporter code understard two additional options:
+ * "export contacts in the phone only" and
+ * "export all contacts without caring Account information".
+ * static final Account sExportPhoneLocalAccount;
+ * static final Account sExportAllAccount;
+ */
+
private ContactItemListAdapter mAdapter;
int mMode = MODE_DEFAULT;
@@ -353,10 +358,12 @@
// Uri matcher for contact id
private static final int CONTACTS_ID = 1001;
- private static final UriMatcher CONTACTS_ID_MATCHER;
+ private static final UriMatcher sContactsIdMatcher;
static {
- CONTACTS_ID_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
- CONTACTS_ID_MATCHER.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
+ sContactsIdMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+ sContactsIdMatcher.addURI(ContactsContract.AUTHORITY, "contacts/#", CONTACTS_ID);
+ /*sExportPhoneLocalAccount = new Account("Phone-local Account", "phone-local");
+ sExportAllAccount = new Account("All account", "all");*/
}
private class DeleteClickListener implements DialogInterface.OnClickListener {
@@ -497,7 +504,7 @@
} else if (Intents.SEARCH_SUGGESTION_CLICKED.equals(action)) {
Uri data = intent.getData();
Uri telUri = null;
- if (CONTACTS_ID_MATCHER.match(data) == CONTACTS_ID) {
+ if (sContactsIdMatcher.match(data) == CONTACTS_ID) {
long contactId = Long.valueOf(data.getLastPathSegment());
final Cursor cursor = queryPhoneNumbers(contactId);
if (cursor != null) {
@@ -827,7 +834,8 @@
return createImportExportDialog();
}
case R.string.import_from_sim:
- case R.string.import_from_sdcard: {
+ case R.string.import_from_sdcard:
+ case R.string.export_to_sdcard: {
return createSelectAccountDialog(id);
}
case R.string.fail_reason_too_many_vcard: {
@@ -866,8 +874,7 @@
public AccountSelectedListener(List<Account> accountList, int resId) {
if (accountList == null || accountList.size() == 0) {
- // TODO: Add all the contacts into phone-local account.
- Log.e(TAG, "The size of Account list is 0");
+ Log.e(TAG, "The size of Account list is 0.");
}
mAccountList = accountList;
mResId = resId;
@@ -884,6 +891,8 @@
doImportFromSdCard(mAccountList.get(which));
break;
}
+ /*case R.string.export_to_sdcard: {
+ }*/
}
}
@@ -893,10 +902,18 @@
}
private Dialog createSelectAccountDialog(int resId) {
- // A lot of codes are copied from EditContactActivity.
- // TODO: Can we share the logic?
+ final boolean isExport = (resId == R.string.export_to_sdcard);
+ final boolean displayWritableOnly = !isExport;
+
final Sources sources = Sources.getInstance(this);
- final List<Account> accountList = sources.getAccounts(true);
+ final List<Account> accountList = sources.getAccounts(displayWritableOnly);
+
+ /*if (isExport) {
+ accountList.add(sExportPhoneLocalAccount);
+ accountList.add(sExportAllAccount);
+ }*/
+
+ // Assume accountList.size() > 1
// Wrap our context to inflate list items using correct theme
final Context dialogContext = new ContextThemeWrapper(
@@ -987,13 +1004,18 @@
switch (resId) {
case R.string.import_from_sim:
case R.string.import_from_sdcard: {
- showDialog(resId);
+ handleImportExportRequest(resId);
break;
}
case R.string.export_to_sdcard: {
+ // TODO: use handleImportExportRequest()
doExportToSdCard();
break;
}
+ default: {
+ Log.e(TAG, "Unexpected resource: " +
+ getResources().getResourceEntryName(resId));
+ }
}
}
};
@@ -1005,19 +1027,73 @@
return builder.create();
}
+ private void handleImportExportRequest(int resId) {
+ /*final boolean isExport = (resId == R.string.export_to_sdcard);
+ if (isExport) {
+ // We're sure there are at least two Account ("phone-local" and "all").
+ // Go to account selection every time.
+ showDialog(R.string.export_to_sdcard);
+ return;
+ }*/
+
+ // As for import, there's three possibilities
+ // - more than one accounts -> ask the user
+ // - just one account -> use the account without asking the user
+ // - no account -> use phone-local storage without asking the user
+
+ final Sources sources = Sources.getInstance(this);
+ final List<Account> accountList = sources.getAccounts(true);
+ final int size = accountList.size();
+ Account account;
+ if (size > 1) {
+ showDialog(resId);
+ return;
+ } else if (size == 1) {
+ account = accountList.get(0);
+ } else {
+ account = null;
+ }
+ switch (resId) {
+ case R.string.import_from_sim: {
+ doImportFromSim(account);
+ break;
+ }
+ case R.string.import_from_sdcard: {
+ doImportFromSdCard(account);
+ break;
+ }
+ /*case R.string.export_to_sdcard: {
+ doExportToSdCard(account);
+ break;
+ }*/
+ }
+ }
+
private void doImportFromSim(Account account) {
+ if (account != null) {
+ GoogleSource.createMyContactsIfNotExist(account, this);
+ }
+
Intent importIntent = new Intent(Intent.ACTION_VIEW);
importIntent.setType("vnd.android.cursor.item/sim-contact");
- importIntent.putExtra("account_name", account.name);
- importIntent.putExtra("account_type", account.type);
+ if (account != null) {
+ importIntent.putExtra("account_name", account.name);
+ importIntent.putExtra("account_type", account.type);
+ }
importIntent.setClassName("com.android.phone", "com.android.phone.SimContacts");
startActivity(importIntent);
}
private void doImportFromSdCard(Account account) {
+ if (account != null) {
+ GoogleSource.createMyContactsIfNotExist(account, this);
+ }
+
Intent importIntent = new Intent(this, ImportVCardActivity.class);
- importIntent.putExtra("account_name", account.name);
- importIntent.putExtra("account_type", account.type);
+ if (account != null) {
+ importIntent.putExtra("account_name", account.name);
+ importIntent.putExtra("account_type", account.type);
+ }
startActivity(importIntent);
}
@@ -2248,7 +2324,9 @@
cache.dataView = (TextView) view.findViewById(R.id.data);
cache.presenceView = (ImageView) view.findViewById(R.id.presence);
cache.photoView = (FasttrackBadgeWidget) view.findViewById(R.id.photo);
- cache.photoView.setExcludeMimes(new String[] {Contacts.CONTENT_ITEM_TYPE});
+ if (cache.photoView != null) {
+ cache.photoView.setExcludeMimes(new String[] {Contacts.CONTENT_ITEM_TYPE});
+ }
cache.nonFastTrackPhotoView = (ImageView) view.findViewById(R.id.noFastTrackphoto);
view.setTag(cache);
diff --git a/src/com/android/contacts/model/GoogleSource.java b/src/com/android/contacts/model/GoogleSource.java
index 46d0623..9968ace 100644
--- a/src/com/android/contacts/model/GoogleSource.java
+++ b/src/com/android/contacts/model/GoogleSource.java
@@ -20,6 +20,7 @@
import com.android.contacts.model.EntityDelta.ValuesDelta;
import com.google.android.collect.Lists;
+import android.accounts.Account;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
@@ -153,10 +154,19 @@
}
// TODO: this should come from resource in the future
+ // Note that frameworks/base/core/java/android/pim/vcard/ContactStruct.java also wants
+ // this String.
private static final String GOOGLE_MY_CONTACTS_GROUP = "System Group: My Contacts";
public static final void attemptMyContactsMembership(EntityDelta state, Context context) {
- attemptMyContactsMembership(state, context, true);
+ final ValuesDelta stateValues = state.getValues();
+ final String accountName = stateValues.getAsString(RawContacts.ACCOUNT_NAME);
+ final String accountType = stateValues.getAsString(RawContacts.ACCOUNT_TYPE);
+ attemptMyContactsMembership(state, accountName, accountType, context, true);
+ }
+
+ public static final void createMyContactsIfNotExist(Account account, Context context) {
+ attemptMyContactsMembership(null, account.name, account.type, context, true);
}
/**
@@ -165,12 +175,10 @@
* to prevent excess recursion, we provide a flag to make sure we only do the recursion loop
* once
*/
- private static final void attemptMyContactsMembership(EntityDelta state, Context context,
- boolean allowRecur) {
+ private static final void attemptMyContactsMembership(EntityDelta state,
+ final String accountName, final String accountType, Context context,
+ boolean allowRecur) {
final ContentResolver resolver = context.getContentResolver();
- final ValuesDelta stateValues = state.getValues();
- final String accountName = stateValues.getAsString(RawContacts.ACCOUNT_NAME);
- final String accountType = stateValues.getAsString(RawContacts.ACCOUNT_TYPE);
Cursor cursor = resolver.query(Groups.CONTENT_URI,
new String[] {Groups.TITLE, Groups.SOURCE_ID, Groups.SHOULD_SYNC},
@@ -192,6 +200,10 @@
}
}
+ if (myContactsExists && state == null) {
+ return;
+ }
+
try {
final ContentValues values = new ContentValues();
values.put(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
@@ -227,7 +239,8 @@
} catch (OperationApplicationException e) {
// the group was created after the query but before we tried to create it
if (allowRecur) {
- attemptMyContactsMembership(state, context, false);
+ attemptMyContactsMembership(
+ state, accountName, accountType, context, false);
}
return;
}
@@ -239,7 +252,9 @@
// TODO: alert user that their contact will be dropped?
}
}
- state.addEntry(ValuesDelta.fromAfter(values));
+ if (state != null) {
+ state.addEntry(ValuesDelta.fromAfter(values));
+ }
} finally {
cursor.close();
}
diff --git a/src/com/android/contacts/ui/DisplayGroupsActivity.java b/src/com/android/contacts/ui/DisplayGroupsActivity.java
index ab6f651..69f0007 100644
--- a/src/com/android/contacts/ui/DisplayGroupsActivity.java
+++ b/src/com/android/contacts/ui/DisplayGroupsActivity.java
@@ -17,6 +17,7 @@
package com.android.contacts.ui;
import com.android.contacts.R;
+import com.android.contacts.model.GoogleSource;
import com.android.contacts.model.ContactsSource;
import com.android.contacts.model.Sources;
import com.android.contacts.util.EmptyService;
@@ -305,14 +306,18 @@
final int childPosition = ExpandableListView.getPackedPositionChild(info.packedPosition);
final Cursor groupCursor = mAdapter.getGroup(groupPosition);
+ final String accountName = groupCursor.getString(SettingsQuery.ACCOUNT_NAME);
+ final String accountType = groupCursor.getString(SettingsQuery.ACCOUNT_TYPE);
+
// TODO: read sync mode through <sync-adapter> definition
- final int syncMode = SYNC_MODE_EVERYTHING;
+ int syncMode = SYNC_MODE_UNSUPPORTED;
+ if (accountType.equals(GoogleSource.ACCOUNT_TYPE)) {
+ syncMode = SYNC_MODE_EVERYTHING;
+ }
// Ignore when selective syncing unsupported
if (syncMode == SYNC_MODE_UNSUPPORTED) return;
- final String accountName = groupCursor.getString(SettingsQuery.ACCOUNT_NAME);
- final String accountType = groupCursor.getString(SettingsQuery.ACCOUNT_TYPE);
final Account account = new Account(accountName, accountType);
final boolean shouldSyncUngrouped = groupCursor.getInt(SettingsQuery.SHOULD_SYNC) != 0;