1 /* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.contacts.model; 18 19 import android.content.ContentValues; 20 import android.content.Context; 21 import android.content.Entity; 22 import android.net.Uri; 23 import android.provider.ContactsContract.Contacts; 24 import android.provider.ContactsContract.Data; 25 import android.provider.ContactsContract.RawContacts; 26 27 import com.android.contacts.model.account.AccountType; 28 import com.android.contacts.model.account.AccountWithDataSet; 29 import com.android.contacts.model.dataitem.DataItem; 30 31 import java.util.ArrayList; 32 import java.util.List; 33 34 /** 35 * RawContact represents a single raw contact in the raw contacts database. 36 * It has specialized getters/setters for raw contact 37 * items, and also contains a collection of DataItem objects. A RawContact contains the information 38 * from a single account. 39 * 40 * This allows RawContact objects to be thought of as a class with raw contact 41 * fields (like account type, name, data set, sync state, etc.) and a list of 42 * DataItem objects that represent contact information elements (like phone 43 * numbers, email, address, etc.). 44 */ 45 public class RawContact { 46 47 private final Context mContext; 48 private AccountTypeManager mAccountTypeManager; 49 private final ContentValues mValues; 50 private final ArrayList<NamedDataItem> mDataItems; 51 52 public static class NamedDataItem { 53 public final Uri uri; 54 public final DataItem dataItem; 55 NamedDataItem(Uri uri, DataItem dataItem)56 public NamedDataItem(Uri uri, DataItem dataItem) { 57 this.uri = uri; 58 this.dataItem = dataItem; 59 } 60 } 61 createFrom(Entity entity)62 public static RawContact createFrom(Entity entity) { 63 final ContentValues values = entity.getEntityValues(); 64 final ArrayList<Entity.NamedContentValues> subValues = entity.getSubValues(); 65 66 RawContact rawContact = new RawContact(null, values); 67 for (Entity.NamedContentValues subValue : subValues) { 68 rawContact.addNamedDataItemValues(subValue.uri, subValue.values); 69 } 70 return rawContact; 71 } 72 73 /** 74 * A RawContact object can be created with or without a context. 75 * 76 * The context is used for the buildString() member function in DataItem objects, 77 * specifically for retrieving an instance of AccountTypeManager. It is okay to 78 * pass in null for the context in which case, you will not be able to call buildString(), 79 * getDataKind(), or getAccountType() from a DataItem object. 80 */ RawContact(Context context)81 public RawContact(Context context) { 82 this(context, new ContentValues()); 83 } 84 RawContact(Context context, ContentValues values)85 public RawContact(Context context, ContentValues values) { 86 mContext = context; 87 mValues = values; 88 mDataItems = new ArrayList<NamedDataItem>(); 89 } 90 getAccountTypeManager()91 public AccountTypeManager getAccountTypeManager() { 92 if (mAccountTypeManager == null) { 93 mAccountTypeManager = AccountTypeManager.getInstance(mContext); 94 } 95 return mAccountTypeManager; 96 } 97 getContext()98 public Context getContext() { 99 return mContext; 100 } 101 getValues()102 public ContentValues getValues() { 103 return mValues; 104 } 105 106 /** 107 * Returns the id of the raw contact. 108 */ getId()109 public Long getId() { 110 return getValues().getAsLong(RawContacts._ID); 111 } 112 113 /** 114 * Returns the account name of the raw contact. 115 */ getAccountName()116 public String getAccountName() { 117 return getValues().getAsString(RawContacts.ACCOUNT_NAME); 118 } 119 120 /** 121 * Returns the account type of the raw contact. 122 */ getAccountTypeString()123 public String getAccountTypeString() { 124 return getValues().getAsString(RawContacts.ACCOUNT_TYPE); 125 } 126 127 /** 128 * Returns the data set of the raw contact. 129 */ getDataSet()130 public String getDataSet() { 131 return getValues().getAsString(RawContacts.DATA_SET); 132 } 133 134 /** 135 * Returns the account type and data set of the raw contact. 136 */ getAccountTypeAndDataSetString()137 public String getAccountTypeAndDataSetString() { 138 return getValues().getAsString(RawContacts.ACCOUNT_TYPE_AND_DATA_SET); 139 } 140 isDirty()141 public boolean isDirty() { 142 return getValues().getAsBoolean(RawContacts.DIRTY); 143 } 144 getVersion()145 public long getVersion() { 146 return getValues().getAsLong(RawContacts.DIRTY); 147 } 148 getSourceId()149 public String getSourceId() { 150 return getValues().getAsString(RawContacts.SOURCE_ID); 151 } 152 getSync1()153 public String getSync1() { 154 return getValues().getAsString(RawContacts.SYNC1); 155 } 156 getSync2()157 public String getSync2() { 158 return getValues().getAsString(RawContacts.SYNC2); 159 } 160 getSync3()161 public String getSync3() { 162 return getValues().getAsString(RawContacts.SYNC3); 163 } 164 getSync4()165 public String getSync4() { 166 return getValues().getAsString(RawContacts.SYNC4); 167 } 168 isDeleted()169 public boolean isDeleted() { 170 return getValues().getAsBoolean(RawContacts.DELETED); 171 } 172 isNameVerified()173 public boolean isNameVerified() { 174 return getValues().getAsBoolean(RawContacts.NAME_VERIFIED); 175 } 176 getContactId()177 public long getContactId() { 178 return getValues().getAsLong(Contacts.Entity.CONTACT_ID); 179 } 180 isStarred()181 public boolean isStarred() { 182 return getValues().getAsBoolean(Contacts.STARRED); 183 } 184 getAccountType()185 public AccountType getAccountType() { 186 return getAccountTypeManager().getAccountType(getAccountTypeString(), getDataSet()); 187 } 188 189 /** 190 * Sets the account name, account type, and data set strings. 191 * Valid combinations for account-name, account-type, data-set 192 * 1) null, null, null (local account) 193 * 2) non-null, non-null, null (valid account without data-set) 194 * 3) non-null, non-null, non-null (valid account with data-set) 195 */ setAccount(String accountName, String accountType, String dataSet)196 private void setAccount(String accountName, String accountType, String dataSet) { 197 final ContentValues values = getValues(); 198 if (accountName == null) { 199 if (accountType == null && dataSet == null) { 200 // This is a local account 201 values.putNull(RawContacts.ACCOUNT_NAME); 202 values.putNull(RawContacts.ACCOUNT_TYPE); 203 values.putNull(RawContacts.DATA_SET); 204 return; 205 } 206 } else { 207 if (accountType != null) { 208 // This is a valid account, either with or without a dataSet. 209 values.put(RawContacts.ACCOUNT_NAME, accountName); 210 values.put(RawContacts.ACCOUNT_TYPE, accountType); 211 if (dataSet == null) { 212 values.putNull(RawContacts.DATA_SET); 213 } else { 214 values.put(RawContacts.DATA_SET, dataSet); 215 } 216 return; 217 } 218 } 219 throw new IllegalArgumentException( 220 "Not a valid combination of account name, type, and data set."); 221 } 222 setAccount(AccountWithDataSet accountWithDataSet)223 public void setAccount(AccountWithDataSet accountWithDataSet) { 224 setAccount(accountWithDataSet.name, accountWithDataSet.type, accountWithDataSet.dataSet); 225 } 226 setAccountToLocal()227 public void setAccountToLocal() { 228 setAccount(null, null, null); 229 } 230 231 /** 232 * Creates and inserts a DataItem object that wraps the content values, and returns it. 233 */ addDataItemValues(ContentValues values)234 public DataItem addDataItemValues(ContentValues values) { 235 final NamedDataItem namedItem = addNamedDataItemValues(Data.CONTENT_URI, values); 236 return namedItem.dataItem; 237 } 238 addNamedDataItemValues(Uri uri, ContentValues values)239 public NamedDataItem addNamedDataItemValues(Uri uri, ContentValues values) { 240 final NamedDataItem namedItem = new NamedDataItem(uri, DataItem.createFrom(this, values)); 241 mDataItems.add(namedItem); 242 return namedItem; 243 } 244 getDataItems()245 public List<DataItem> getDataItems() { 246 final ArrayList<DataItem> list = new ArrayList<DataItem>(); 247 for (NamedDataItem dataItem : mDataItems) { 248 if (Data.CONTENT_URI.equals(dataItem.uri)) { 249 list.add(dataItem.dataItem); 250 } 251 } 252 return list; 253 } 254 getNamedDataItems()255 public List<NamedDataItem> getNamedDataItems() { 256 return mDataItems; 257 } 258 toString()259 public String toString() { 260 final StringBuilder sb = new StringBuilder(); 261 sb.append("RawContact: ").append(mValues); 262 for (RawContact.NamedDataItem namedDataItem : mDataItems) { 263 sb.append("\n ").append(namedDataItem.uri); 264 sb.append("\n -> ").append(namedDataItem.dataItem.getContentValues()); 265 } 266 return sb.toString(); 267 } 268 } 269