1 package com.android.contacts.quickcontact; 2 3 4 import android.content.Context; 5 import android.content.Intent; 6 import android.provider.ContactsContract.CommonDataKinds.GroupMembership; 7 8 import com.android.contacts.ContactSaveService; 9 import com.android.contacts.group.GroupMetaData; 10 import com.android.contacts.model.AccountTypeManager; 11 import com.android.contacts.model.Contact; 12 import com.android.contacts.model.RawContact; 13 import com.android.contacts.model.RawContactDelta; 14 import com.android.contacts.model.RawContactDeltaList; 15 import com.android.contacts.model.RawContactModifier; 16 import com.android.contacts.model.ValuesDelta; 17 import com.android.contacts.model.account.AccountType; 18 import com.android.contacts.model.dataitem.DataItem; 19 import com.android.contacts.model.dataitem.DataKind; 20 import com.android.contacts.model.dataitem.GroupMembershipDataItem; 21 22 import com.google.common.collect.Iterables; 23 24 import 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 */ 30 public class InvisibleContactUtil { 31 isInvisibleAndAddable(Contact contactData, Context context)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 addToDefaultGroup(Contact contactData, Context context)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 markAddToDefaultGroup(Contact contactData, RawContactDeltaList rawContactDeltaList, Context context)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 */ getDefaultGroupId(List<GroupMetaData> groups)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