• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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      */
ContentValues()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      */
ContentValues(int size)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      */
ContentValues(ContentValues from)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      */
ContentValues(HashMap<String, Object> values)72     private ContentValues(HashMap<String, Object> values) {
73         mValues = values;
74     }
75 
76     @Override
equals(Object object)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
hashCode()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      */
put(String key, String value)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      */
putAll(ContentValues other)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      */
put(String key, Byte value)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      */
put(String key, Short value)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      */
put(String key, Integer value)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      */
put(String key, Long value)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      */
put(String key, Float value)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      */
put(String key, Double value)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      */
put(String key, Boolean value)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      */
put(String key, byte[] value)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      */
putNull(String key)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      */
size()202     public int size() {
203         return mValues.size();
204     }
205 
206     /**
207      * Indicates whether this collection is empty.
208      *
209      * @return true iff size == 0
210      * {@hide}
211      * TODO: consider exposing this new method publicly
212      */
isEmpty()213     public boolean isEmpty() {
214         return mValues.isEmpty();
215     }
216 
217     /**
218      * Remove a single value.
219      *
220      * @param key the name of the value to remove
221      */
remove(String key)222     public void remove(String key) {
223         mValues.remove(key);
224     }
225 
226     /**
227      * Removes all values.
228      */
clear()229     public void clear() {
230         mValues.clear();
231     }
232 
233     /**
234      * Returns true if this object has the named value.
235      *
236      * @param key the value to check for
237      * @return {@code true} if the value is present, {@code false} otherwise
238      */
containsKey(String key)239     public boolean containsKey(String key) {
240         return mValues.containsKey(key);
241     }
242 
243     /**
244      * Gets a value. Valid value types are {@link String}, {@link Boolean},
245      * {@link Number}, and {@code byte[]} implementations.
246      *
247      * @param key the value to get
248      * @return the data for the value, or {@code null} if the value is missing or if {@code null}
249      *         was previously added with the given {@code key}
250      */
get(String key)251     public Object get(String key) {
252         return mValues.get(key);
253     }
254 
255     /**
256      * Gets a value and converts it to a String.
257      *
258      * @param key the value to get
259      * @return the String for the value
260      */
getAsString(String key)261     public String getAsString(String key) {
262         Object value = mValues.get(key);
263         return value != null ? value.toString() : null;
264     }
265 
266     /**
267      * Gets a value and converts it to a Long.
268      *
269      * @param key the value to get
270      * @return the Long value, or {@code null} if the value is missing or cannot be converted
271      */
getAsLong(String key)272     public Long getAsLong(String key) {
273         Object value = mValues.get(key);
274         try {
275             return value != null ? ((Number) value).longValue() : null;
276         } catch (ClassCastException e) {
277             if (value instanceof CharSequence) {
278                 try {
279                     return Long.valueOf(value.toString());
280                 } catch (NumberFormatException e2) {
281                     Log.e(TAG, "Cannot parse Long value for " + value + " at key " + key);
282                     return null;
283                 }
284             } else {
285                 Log.e(TAG, "Cannot cast value for " + key + " to a Long: " + value, e);
286                 return null;
287             }
288         }
289     }
290 
291     /**
292      * Gets a value and converts it to an Integer.
293      *
294      * @param key the value to get
295      * @return the Integer value, or {@code null} if the value is missing or cannot be converted
296      */
getAsInteger(String key)297     public Integer getAsInteger(String key) {
298         Object value = mValues.get(key);
299         try {
300             return value != null ? ((Number) value).intValue() : null;
301         } catch (ClassCastException e) {
302             if (value instanceof CharSequence) {
303                 try {
304                     return Integer.valueOf(value.toString());
305                 } catch (NumberFormatException e2) {
306                     Log.e(TAG, "Cannot parse Integer value for " + value + " at key " + key);
307                     return null;
308                 }
309             } else {
310                 Log.e(TAG, "Cannot cast value for " + key + " to a Integer: " + value, e);
311                 return null;
312             }
313         }
314     }
315 
316     /**
317      * Gets a value and converts it to a Short.
318      *
319      * @param key the value to get
320      * @return the Short value, or {@code null} if the value is missing or cannot be converted
321      */
getAsShort(String key)322     public Short getAsShort(String key) {
323         Object value = mValues.get(key);
324         try {
325             return value != null ? ((Number) value).shortValue() : null;
326         } catch (ClassCastException e) {
327             if (value instanceof CharSequence) {
328                 try {
329                     return Short.valueOf(value.toString());
330                 } catch (NumberFormatException e2) {
331                     Log.e(TAG, "Cannot parse Short value for " + value + " at key " + key);
332                     return null;
333                 }
334             } else {
335                 Log.e(TAG, "Cannot cast value for " + key + " to a Short: " + value, e);
336                 return null;
337             }
338         }
339     }
340 
341     /**
342      * Gets a value and converts it to a Byte.
343      *
344      * @param key the value to get
345      * @return the Byte value, or {@code null} if the value is missing or cannot be converted
346      */
getAsByte(String key)347     public Byte getAsByte(String key) {
348         Object value = mValues.get(key);
349         try {
350             return value != null ? ((Number) value).byteValue() : null;
351         } catch (ClassCastException e) {
352             if (value instanceof CharSequence) {
353                 try {
354                     return Byte.valueOf(value.toString());
355                 } catch (NumberFormatException e2) {
356                     Log.e(TAG, "Cannot parse Byte value for " + value + " at key " + key);
357                     return null;
358                 }
359             } else {
360                 Log.e(TAG, "Cannot cast value for " + key + " to a Byte: " + value, e);
361                 return null;
362             }
363         }
364     }
365 
366     /**
367      * Gets a value and converts it to a Double.
368      *
369      * @param key the value to get
370      * @return the Double value, or {@code null} if the value is missing or cannot be converted
371      */
getAsDouble(String key)372     public Double getAsDouble(String key) {
373         Object value = mValues.get(key);
374         try {
375             return value != null ? ((Number) value).doubleValue() : null;
376         } catch (ClassCastException e) {
377             if (value instanceof CharSequence) {
378                 try {
379                     return Double.valueOf(value.toString());
380                 } catch (NumberFormatException e2) {
381                     Log.e(TAG, "Cannot parse Double value for " + value + " at key " + key);
382                     return null;
383                 }
384             } else {
385                 Log.e(TAG, "Cannot cast value for " + key + " to a Double: " + value, e);
386                 return null;
387             }
388         }
389     }
390 
391     /**
392      * Gets a value and converts it to a Float.
393      *
394      * @param key the value to get
395      * @return the Float value, or {@code null} if the value is missing or cannot be converted
396      */
getAsFloat(String key)397     public Float getAsFloat(String key) {
398         Object value = mValues.get(key);
399         try {
400             return value != null ? ((Number) value).floatValue() : null;
401         } catch (ClassCastException e) {
402             if (value instanceof CharSequence) {
403                 try {
404                     return Float.valueOf(value.toString());
405                 } catch (NumberFormatException e2) {
406                     Log.e(TAG, "Cannot parse Float value for " + value + " at key " + key);
407                     return null;
408                 }
409             } else {
410                 Log.e(TAG, "Cannot cast value for " + key + " to a Float: " + value, e);
411                 return null;
412             }
413         }
414     }
415 
416     /**
417      * Gets a value and converts it to a Boolean.
418      *
419      * @param key the value to get
420      * @return the Boolean value, or {@code null} if the value is missing or cannot be converted
421      */
getAsBoolean(String key)422     public Boolean getAsBoolean(String key) {
423         Object value = mValues.get(key);
424         try {
425             return (Boolean) value;
426         } catch (ClassCastException e) {
427             if (value instanceof CharSequence) {
428                 // Note that we also check against 1 here because SQLite's internal representation
429                 // for booleans is an integer with a value of 0 or 1. Without this check, boolean
430                 // values obtained via DatabaseUtils#cursorRowToContentValues will always return
431                 // false.
432                 return Boolean.valueOf(value.toString()) || "1".equals(value);
433             } else if (value instanceof Number) {
434                 return ((Number) value).intValue() != 0;
435             } else {
436                 Log.e(TAG, "Cannot cast value for " + key + " to a Boolean: " + value, e);
437                 return null;
438             }
439         }
440     }
441 
442     /**
443      * Gets a value that is a byte array. Note that this method will not convert
444      * any other types to byte arrays.
445      *
446      * @param key the value to get
447      * @return the {@code byte[]} value, or {@code null} is the value is missing or not a
448      *         {@code byte[]}
449      */
getAsByteArray(String key)450     public byte[] getAsByteArray(String key) {
451         Object value = mValues.get(key);
452         if (value instanceof byte[]) {
453             return (byte[]) value;
454         } else {
455             return null;
456         }
457     }
458 
459     /**
460      * Returns a set of all of the keys and values
461      *
462      * @return a set of all of the keys and values
463      */
valueSet()464     public Set<Map.Entry<String, Object>> valueSet() {
465         return mValues.entrySet();
466     }
467 
468     /**
469      * Returns a set of all of the keys
470      *
471      * @return a set of all of the keys
472      */
keySet()473     public Set<String> keySet() {
474         return mValues.keySet();
475     }
476 
477     public static final Parcelable.Creator<ContentValues> CREATOR =
478             new Parcelable.Creator<ContentValues>() {
479         @SuppressWarnings({"deprecation", "unchecked"})
480         public ContentValues createFromParcel(Parcel in) {
481             // TODO - what ClassLoader should be passed to readHashMap?
482             HashMap<String, Object> values = in.readHashMap(null);
483             return new ContentValues(values);
484         }
485 
486         public ContentValues[] newArray(int size) {
487             return new ContentValues[size];
488         }
489     };
490 
describeContents()491     public int describeContents() {
492         return 0;
493     }
494 
495     @SuppressWarnings("deprecation")
writeToParcel(Parcel parcel, int flags)496     public void writeToParcel(Parcel parcel, int flags) {
497         parcel.writeMap(mValues);
498     }
499 
500     /**
501      * Unsupported, here until we get proper bulk insert APIs.
502      * {@hide}
503      */
504     @Deprecated
putStringArrayList(String key, ArrayList<String> value)505     public void putStringArrayList(String key, ArrayList<String> value) {
506         mValues.put(key, value);
507     }
508 
509     /**
510      * Unsupported, here until we get proper bulk insert APIs.
511      * {@hide}
512      */
513     @SuppressWarnings("unchecked")
514     @Deprecated
getStringArrayList(String key)515     public ArrayList<String> getStringArrayList(String key) {
516         return (ArrayList<String>) mValues.get(key);
517     }
518 
519     /**
520      * Returns a string containing a concise, human-readable description of this object.
521      * @return a printable representation of this object.
522      */
523     @Override
toString()524     public String toString() {
525         StringBuilder sb = new StringBuilder();
526         for (String name : mValues.keySet()) {
527             String value = getAsString(name);
528             if (sb.length() > 0) sb.append(" ");
529             sb.append(name + "=" + value);
530         }
531         return sb.toString();
532     }
533 }
534