1package com.android.contacts.quickcontact; 2 3 4import android.content.Context; 5import android.content.Intent; 6import android.provider.ContactsContract.CommonDataKinds.GroupMembership; 7 8import com.android.contacts.ContactSaveService; 9import com.android.contacts.group.GroupMetaData; 10import com.android.contacts.model.AccountTypeManager; 11import com.android.contacts.model.Contact; 12import com.android.contacts.model.RawContact; 13import com.android.contacts.model.RawContactDelta; 14import com.android.contacts.model.RawContactDeltaList; 15import com.android.contacts.model.RawContactModifier; 16import com.android.contacts.model.ValuesDelta; 17import com.android.contacts.model.account.AccountType; 18import com.android.contacts.model.dataitem.DataItem; 19import com.android.contacts.model.dataitem.DataKind; 20import com.android.contacts.model.dataitem.GroupMembershipDataItem; 21 22import com.google.common.collect.Iterables; 23 24import java.util.List; 25 26/** 27 * Utility class to support adding invisible contacts. Ie, contacts that don't belong to the 28 * default group. 29 */ 30public class InvisibleContactUtil { 31 32 public static boolean isInvisibleAndAddable(Contact contactData, Context context) { 33 // Only local contacts 34 if (contactData == null || contactData.isDirectoryEntry()) return false; 35 36 // User profile cannot be added to contacts 37 if (contactData.isUserProfile()) return false; 38 39 // Only if exactly one raw contact 40 if (contactData.getRawContacts().size() != 1) return false; 41 42 // test if the default group is assigned 43 final List<GroupMetaData> groups = contactData.getGroupMetaData(); 44 45 // For accounts without group support, groups is null 46 if (groups == null) return false; 47 48 // remember the default group id. no default group? bail out early 49 final long defaultGroupId = getDefaultGroupId(groups); 50 if (defaultGroupId == -1) return false; 51 52 final RawContact rawContact = (RawContact) contactData.getRawContacts().get(0); 53 final AccountType type = rawContact.getAccountType(context); 54 // Offline or non-writeable account? Nothing to fix 55 if (type == null || !type.areContactsWritable()) return false; 56 57 // Check whether the contact is in the default group 58 boolean isInDefaultGroup = false; 59 for (DataItem dataItem : Iterables.filter( 60 rawContact.getDataItems(), GroupMembershipDataItem.class)) { 61 GroupMembershipDataItem groupMembership = (GroupMembershipDataItem) dataItem; 62 final Long groupId = groupMembership.getGroupRowId(); 63 if (groupId != null && groupId == defaultGroupId) { 64 isInDefaultGroup = true; 65 break; 66 } 67 } 68 69 return !isInDefaultGroup; 70 } 71 72 public static void addToDefaultGroup(Contact contactData, Context context) { 73 final RawContactDeltaList contactDeltaList = contactData.createRawContactDeltaList(); 74 if (markAddToDefaultGroup(contactData, contactDeltaList, context)) { 75 // Fire off the intent. we don't need a callback, as the database listener 76 // should update the ui 77 final Intent intent = ContactSaveService.createSaveContactIntent( 78 context, 79 contactDeltaList, "", 0, false, QuickContactActivity.class, 80 Intent.ACTION_VIEW, null, /* joinContactIdExtraKey =*/ null, 81 /* joinContactId =*/ null); 82 ContactSaveService.startService(context, intent); 83 } 84 } 85 86 public static boolean markAddToDefaultGroup(Contact contactData, 87 RawContactDeltaList rawContactDeltaList, Context context) { 88 final long defaultGroupId = getDefaultGroupId(contactData.getGroupMetaData()); 89 // there should always be a default group (otherwise the button would be invisible), 90 // but let's be safe here 91 if (defaultGroupId == -1) return false; 92 93 // add the group membership to the current state 94 final RawContactDelta rawContactEntityDelta = rawContactDeltaList.get(0); 95 96 final AccountTypeManager accountTypes = AccountTypeManager.getInstance( 97 context); 98 final AccountType type = rawContactEntityDelta.getAccountType(accountTypes); 99 final DataKind groupMembershipKind = type.getKindForMimetype( 100 GroupMembership.CONTENT_ITEM_TYPE); 101 final ValuesDelta entry = RawContactModifier.insertChild(rawContactEntityDelta, 102 groupMembershipKind); 103 if (entry == null) return false; 104 entry.setGroupRowId(defaultGroupId); 105 return true; 106 } 107 108 /** return default group id or -1 if no group or several groups are marked as default */ 109 private static long getDefaultGroupId(List<GroupMetaData> groups) { 110 long defaultGroupId = -1; 111 for (GroupMetaData group : groups) { 112 if (group.defaultGroup) { 113 // two default groups? return neither 114 if (defaultGroupId != -1) return -1; 115 defaultGroupId = group.groupId; 116 } 117 } 118 return defaultGroupId; 119 } 120} 121