1 /* 2 * Copyright (C) 2007 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 android.content; 18 19 import android.os.Parcel; 20 import android.os.Parcelable; 21 import android.util.Log; 22 23 import java.util.ArrayList; 24 import java.util.HashMap; 25 import java.util.Map; 26 import java.util.Set; 27 28 /** 29 * This class is used to store a set of values that the {@link ContentResolver} 30 * can process. 31 */ 32 public final class ContentValues implements Parcelable { 33 public static final String TAG = "ContentValues"; 34 35 /** Holds the actual values */ 36 private HashMap<String, Object> mValues; 37 38 /** 39 * Creates an empty set of values using the default initial size 40 */ 41 public ContentValues() { 42 // Choosing a default size of 8 based on analysis of typical 43 // consumption by applications. 44 mValues = new HashMap<String, Object>(8); 45 } 46 47 /** 48 * Creates an empty set of values using the given initial size 49 * 50 * @param size the initial size of the set of values 51 */ 52 public ContentValues(int size) { 53 mValues = new HashMap<String, Object>(size, 1.0f); 54 } 55 56 /** 57 * Creates a set of values copied from the given set 58 * 59 * @param from the values to copy 60 */ 61 public ContentValues(ContentValues from) { 62 mValues = new HashMap<String, Object>(from.mValues); 63 } 64 65 /** 66 * Creates a set of values copied from the given HashMap. This is used 67 * by the Parcel unmarshalling code. 68 * 69 * @param values the values to start with 70 * {@hide} 71 */ 72 private ContentValues(HashMap<String, Object> values) { 73 mValues = values; 74 } 75 76 @Override 77 public boolean equals(Object object) { 78 if (!(object instanceof ContentValues)) { 79 return false; 80 } 81 return mValues.equals(((ContentValues) object).mValues); 82 } 83 84 @Override 85 public int hashCode() { 86 return mValues.hashCode(); 87 } 88 89 /** 90 * Adds a value to the set. 91 * 92 * @param key the name of the value to put 93 * @param value the data for the value to put 94 */ 95 public void put(String key, String value) { 96 mValues.put(key, value); 97 } 98 99 /** 100 * Adds all values from the passed in ContentValues. 101 * 102 * @param other the ContentValues from which to copy 103 */ 104 public void putAll(ContentValues other) { 105 mValues.putAll(other.mValues); 106 } 107 108 /** 109 * Adds a value to the set. 110 * 111 * @param key the name of the value to put 112 * @param value the data for the value to put 113 */ 114 public void put(String key, Byte value) { 115 mValues.put(key, value); 116 } 117 118 /** 119 * Adds a value to the set. 120 * 121 * @param key the name of the value to put 122 * @param value the data for the value to put 123 */ 124 public void put(String key, Short value) { 125 mValues.put(key, value); 126 } 127 128 /** 129 * Adds a value to the set. 130 * 131 * @param key the name of the value to put 132 * @param value the data for the value to put 133 */ 134 public void put(String key, Integer value) { 135 mValues.put(key, value); 136 } 137 138 /** 139 * Adds a value to the set. 140 * 141 * @param key the name of the value to put 142 * @param value the data for the value to put 143 */ 144 public void put(String key, Long value) { 145 mValues.put(key, value); 146 } 147 148 /** 149 * Adds a value to the set. 150 * 151 * @param key the name of the value to put 152 * @param value the data for the value to put 153 */ 154 public void put(String key, Float value) { 155 mValues.put(key, value); 156 } 157 158 /** 159 * Adds a value to the set. 160 * 161 * @param key the name of the value to put 162 * @param value the data for the value to put 163 */ 164 public void put(String key, Double value) { 165 mValues.put(key, value); 166 } 167 168 /** 169 * Adds a value to the set. 170 * 171 * @param key the name of the value to put 172 * @param value the data for the value to put 173 */ 174 public void put(String key, Boolean value) { 175 mValues.put(key, value); 176 } 177 178 /** 179 * Adds a value to the set. 180 * 181 * @param key the name of the value to put 182 * @param value the data for the value to put 183 */ 184 public void put(String key, byte[] value) { 185 mValues.put(key, value); 186 } 187 188 /** 189 * Adds a null value to the set. 190 * 191 * @param key the name of the value to make null 192 */ 193 public void putNull(String key) { 194 mValues.put(key, null); 195 } 196 197 /** 198 * Returns the number of values. 199 * 200 * @return the number of values 201 */ 202 public int size() { 203 return mValues.size(); 204 } 205 206 /** 207 * Remove a single value. 208 * 209 * @param key the name of the value to remove 210 */ 211 public void remove(String key) { 212 mValues.remove(key); 213 } 214 215 /** 216 * Removes all values. 217 */ 218 public void clear() { 219 mValues.clear(); 220 } 221 222 /** 223 * Returns true if this object has the named value. 224 * 225 * @param key the value to check for 226 * @return {@code true} if the value is present, {@code false} otherwise 227 */ 228 public boolean containsKey(String key) { 229 return mValues.containsKey(key); 230 } 231 232 /** 233 * Gets a value. Valid value types are {@link String}, {@link Boolean}, 234 * {@link Number}, and {@code byte[]} implementations. 235 * 236 * @param key the value to get 237 * @return the data for the value, or {@code null} if the value is missing or if {@code null} 238 * was previously added with the given {@code key} 239 */ 240 public Object get(String key) { 241 return mValues.get(key); 242 } 243 244 /** 245 * Gets a value and converts it to a String. 246 * 247 * @param key the value to get 248 * @return the String for the value 249 */ 250 public String getAsString(String key) { 251 Object value = mValues.get(key); 252 return value != null ? value.toString() : null; 253 } 254 255 /** 256 * Gets a value and converts it to a Long. 257 * 258 * @param key the value to get 259 * @return the Long value, or {@code null} if the value is missing or cannot be converted 260 */ 261 public Long getAsLong(String key) { 262 Object value = mValues.get(key); 263 try { 264 return value != null ? ((Number) value).longValue() : null; 265 } catch (ClassCastException e) { 266 if (value instanceof CharSequence) { 267 try { 268 return Long.valueOf(value.toString()); 269 } catch (NumberFormatException e2) { 270 Log.e(TAG, "Cannot parse Long value for " + value + " at key " + key); 271 return null; 272 } 273 } else { 274 Log.e(TAG, "Cannot cast value for " + key + " to a Long: " + value, e); 275 return null; 276 } 277 } 278 } 279 280 /** 281 * Gets a value and converts it to an Integer. 282 * 283 * @param key the value to get 284 * @return the Integer value, or {@code null} if the value is missing or cannot be converted 285 */ 286 public Integer getAsInteger(String key) { 287 Object value = mValues.get(key); 288 try { 289 return value != null ? ((Number) value).intValue() : null; 290 } catch (ClassCastException e) { 291 if (value instanceof CharSequence) { 292 try { 293 return Integer.valueOf(value.toString()); 294 } catch (NumberFormatException e2) { 295 Log.e(TAG, "Cannot parse Integer value for " + value + " at key " + key); 296 return null; 297 } 298 } else { 299 Log.e(TAG, "Cannot cast value for " + key + " to a Integer: " + value, e); 300 return null; 301 } 302 } 303 } 304 305 /** 306 * Gets a value and converts it to a Short. 307 * 308 * @param key the value to get 309 * @return the Short value, or {@code null} if the value is missing or cannot be converted 310 */ 311 public Short getAsShort(String key) { 312 Object value = mValues.get(key); 313 try { 314 return value != null ? ((Number) value).shortValue() : null; 315 } catch (ClassCastException e) { 316 if (value instanceof CharSequence) { 317 try { 318 return Short.valueOf(value.toString()); 319 } catch (NumberFormatException e2) { 320 Log.e(TAG, "Cannot parse Short value for " + value + " at key " + key); 321 return null; 322 } 323 } else { 324 Log.e(TAG, "Cannot cast value for " + key + " to a Short: " + value, e); 325 return null; 326 } 327 } 328 } 329 330 /** 331 * Gets a value and converts it to a Byte. 332 * 333 * @param key the value to get 334 * @return the Byte value, or {@code null} if the value is missing or cannot be converted 335 */ 336 public Byte getAsByte(String key) { 337 Object value = mValues.get(key); 338 try { 339 return value != null ? ((Number) value).byteValue() : null; 340 } catch (ClassCastException e) { 341 if (value instanceof CharSequence) { 342 try { 343 return Byte.valueOf(value.toString()); 344 } catch (NumberFormatException e2) { 345 Log.e(TAG, "Cannot parse Byte value for " + value + " at key " + key); 346 return null; 347 } 348 } else { 349 Log.e(TAG, "Cannot cast value for " + key + " to a Byte: " + value, e); 350 return null; 351 } 352 } 353 } 354 355 /** 356 * Gets a value and converts it to a Double. 357 * 358 * @param key the value to get 359 * @return the Double value, or {@code null} if the value is missing or cannot be converted 360 */ 361 public Double getAsDouble(String key) { 362 Object value = mValues.get(key); 363 try { 364 return value != null ? ((Number) value).doubleValue() : null; 365 } catch (ClassCastException e) { 366 if (value instanceof CharSequence) { 367 try { 368 return Double.valueOf(value.toString()); 369 } catch (NumberFormatException e2) { 370 Log.e(TAG, "Cannot parse Double value for " + value + " at key " + key); 371 return null; 372 } 373 } else { 374 Log.e(TAG, "Cannot cast value for " + key + " to a Double: " + value, e); 375 return null; 376 } 377 } 378 } 379 380 /** 381 * Gets a value and converts it to a Float. 382 * 383 * @param key the value to get 384 * @return the Float value, or {@code null} if the value is missing or cannot be converted 385 */ 386 public Float getAsFloat(String key) { 387 Object value = mValues.get(key); 388 try { 389 return value != null ? ((Number) value).floatValue() : null; 390 } catch (ClassCastException e) { 391 if (value instanceof CharSequence) { 392 try { 393 return Float.valueOf(value.toString()); 394 } catch (NumberFormatException e2) { 395 Log.e(TAG, "Cannot parse Float value for " + value + " at key " + key); 396 return null; 397 } 398 } else { 399 Log.e(TAG, "Cannot cast value for " + key + " to a Float: " + value, e); 400 return null; 401 } 402 } 403 } 404 405 /** 406 * Gets a value and converts it to a Boolean. 407 * 408 * @param key the value to get 409 * @return the Boolean value, or {@code null} if the value is missing or cannot be converted 410 */ 411 public Boolean getAsBoolean(String key) { 412 Object value = mValues.get(key); 413 try { 414 return (Boolean) value; 415 } catch (ClassCastException e) { 416 if (value instanceof CharSequence) { 417 return Boolean.valueOf(value.toString()); 418 } else if (value instanceof Number) { 419 return ((Number) value).intValue() != 0; 420 } else { 421 Log.e(TAG, "Cannot cast value for " + key + " to a Boolean: " + value, e); 422 return null; 423 } 424 } 425 } 426 427 /** 428 * Gets a value that is a byte array. Note that this method will not convert 429 * any other types to byte arrays. 430 * 431 * @param key the value to get 432 * @return the {@code byte[]} value, or {@code null} is the value is missing or not a 433 * {@code byte[]} 434 */ 435 public byte[] getAsByteArray(String key) { 436 Object value = mValues.get(key); 437 if (value instanceof byte[]) { 438 return (byte[]) value; 439 } else { 440 return null; 441 } 442 } 443 444 /** 445 * Returns a set of all of the keys and values 446 * 447 * @return a set of all of the keys and values 448 */ 449 public Set<Map.Entry<String, Object>> valueSet() { 450 return mValues.entrySet(); 451 } 452 453 /** 454 * Returns a set of all of the keys 455 * 456 * @return a set of all of the keys 457 */ 458 public Set<String> keySet() { 459 return mValues.keySet(); 460 } 461 462 public static final Parcelable.Creator<ContentValues> CREATOR = 463 new Parcelable.Creator<ContentValues>() { 464 @SuppressWarnings({"deprecation", "unchecked"}) 465 public ContentValues createFromParcel(Parcel in) { 466 // TODO - what ClassLoader should be passed to readHashMap? 467 HashMap<String, Object> values = in.readHashMap(null); 468 return new ContentValues(values); 469 } 470 471 public ContentValues[] newArray(int size) { 472 return new ContentValues[size]; 473 } 474 }; 475 476 public int describeContents() { 477 return 0; 478 } 479 480 @SuppressWarnings("deprecation") 481 public void writeToParcel(Parcel parcel, int flags) { 482 parcel.writeMap(mValues); 483 } 484 485 /** 486 * Unsupported, here until we get proper bulk insert APIs. 487 * {@hide} 488 */ 489 @Deprecated 490 public void putStringArrayList(String key, ArrayList<String> value) { 491 mValues.put(key, value); 492 } 493 494 /** 495 * Unsupported, here until we get proper bulk insert APIs. 496 * {@hide} 497 */ 498 @SuppressWarnings("unchecked") 499 @Deprecated 500 public ArrayList<String> getStringArrayList(String key) { 501 return (ArrayList<String>) mValues.get(key); 502 } 503 504 /** 505 * Returns a string containing a concise, human-readable description of this object. 506 * @return a printable representation of this object. 507 */ 508 @Override 509 public String toString() { 510 StringBuilder sb = new StringBuilder(); 511 for (String name : mValues.keySet()) { 512 String value = getAsString(name); 513 if (sb.length() > 0) sb.append(" "); 514 sb.append(name + "=" + value); 515 } 516 return sb.toString(); 517 } 518 } 519