• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017 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 package com.android.networkrecommendation.config;
17 
18 import android.annotation.SuppressLint;
19 import android.content.Context;
20 import android.content.SharedPreferences;
21 import android.content.SharedPreferences.Editor;
22 import android.os.Build;
23 
24 import java.util.Collection;
25 import java.util.Locale;
26 import java.util.Map;
27 import java.util.Set;
28 
29 /**
30  * Utility class for retrieving and storing key/value pairs in a SharedPreferences file.
31  *
32  * Typical usage:
33  *
34  * In your application's onCreate();
35  * PreferenceFile.init(this);
36  *
37  * In common preferences declaration area:
38  * private static final PreferenceFile sFile = new PreferenceFile("my_prefs");
39  * public static final SharedPreference<String> pageUrl = sFile.value("page_url", "http://blah");
40  *
41  * At usage time:
42  * String pageUrl = Preferences.pageUrl.get();
43  * Preferences.pageUrl.put("http://www.newurl.com/");
44  */
45 public class PreferenceFile {
46     private static final String TAG = "PreferenceFile";
47 
48     private static Context sContext;
49 
init(Context context)50     public static void init(Context context) {
51         sContext = context;
52     }
53 
54     private final String mName;
55     private final int mMode;
56 
57     @SuppressWarnings("deprecation")
PreferenceFile(String name)58     public PreferenceFile(String name) {
59         this(name, Context.MODE_PRIVATE);
60     }
61 
62     /**
63      * @deprecated any mode other than MODE_PRIVATE is a bad idea. If you need multi-process
64      * support, see if {@link MultiProcessPreferenceFile} is suitable.
65      */
66     @Deprecated
PreferenceFile(String name, int mode)67     public PreferenceFile(String name, int mode) {
68         mName = name;
69         mMode = mode;
70     }
71 
72     /**
73      * Returns a text dump of all preferences in this file; for debugging.
74      */
dump()75     public String dump() {
76         SharedPreferences sp = open();
77         Map<String, ?> allPrefs = sp.getAll();
78         String format = "%" + longestString(allPrefs.keySet()) + "s = %s\n";
79         StringBuilder s = new StringBuilder();
80         for (String key : allPrefs.keySet()) {
81             s.append(String.format(Locale.US, format, key, allPrefs.get(key)));
82         }
83         return s.toString();
84     }
85 
86     /** Return a SharedPreferences for this file. */
open()87     public SharedPreferences open() {
88         return sContext.getSharedPreferences(mName, mMode);
89     }
90 
remove(SharedPreference<?>.... preferences)91     public void remove(SharedPreference<?>... preferences) {
92         SharedPreferences.Editor editor = open().edit();
93         for (SharedPreference<?> preference : preferences) {
94             editor.remove(preference.getKey());
95         }
96         commit(editor);
97     }
98 
99     /** Synchronously clear all SharedPreferences in this file. */
clear()100     public void clear() {
101         open().edit().clear().commit();
102     }
103 
104 
105     /**
106      * If on API >= 9, use the asynchronous
107      * {@link Editor#apply()} method. Otherwise, use the
108      * synchronous {@link Editor#commit()} method. <br />
109      * <br />
110      * If commit() is used, the result will be returned. If apply() is used, it
111      * will always return true.
112      *
113      * @param editor The editor to save
114      * @return the result of commit() on API &lt; 9 and true on API >= 9.
115      */
116     @SuppressLint("NewApi")
commit(Editor editor)117     public static boolean commit(Editor editor) {
118         if (Build.VERSION.SDK_INT < Build.VERSION_CODES.GINGERBREAD) {
119             return editor.commit();
120         }
121         editor.apply();
122         return true;
123     }
124 
125     /** Define a new Long value shared pref key. */
longValue(final String key, final Long defaultValue)126     public SharedPreference<Long> longValue(final String key, final Long defaultValue) {
127         return new SharedPreference<Long>(this, key) {
128             @Override
129             protected Long read(SharedPreferences sp) {
130                 if (sp.contains(key)) {
131                     return sp.getLong(key, 0L);
132                 }
133                 return defaultValue;
134             }
135 
136             @Override
137             protected void write(Editor editor, Long value) {
138                 if (value == null) {
139                     throw new IllegalArgumentException("null cannot be written for Long");
140                 }
141                 editor.putLong(key, value);
142             }
143         };
144     }
145 
146     /** Define a new String value shared pref key. */
147     public SharedPreference<String> stringValue(final String key, final String defaultValue) {
148         return new SharedPreference<String>(this, key) {
149             @Override
150             protected String read(SharedPreferences sp) {
151                 if (sp.contains(key)) {
152                     return sp.getString(key, null);
153                 }
154                 return defaultValue;
155             }
156 
157             @Override
158             protected void write(Editor editor, String value) {
159                 if (value == null) {
160                     throw new IllegalArgumentException("null cannot be written for String");
161                 }
162                 editor.putString(key, value);
163             }
164         };
165     }
166 
167     /** Define a new Boolean value shared pref key. */
168     public SharedPreference<Boolean> booleanValue(final String key, final Boolean defaultValue) {
169         return new SharedPreference<Boolean>(this, key) {
170             @Override
171             protected Boolean read(SharedPreferences sp) {
172                 if (sp.contains(key)) {
173                     return sp.getBoolean(key, false);
174                 }
175                 return defaultValue;
176             }
177 
178             @Override
179             protected void write(Editor editor, Boolean value) {
180                 if (value == null) {
181                     throw new IllegalArgumentException("null cannot be written for Boolean");
182                 }
183                 editor.putBoolean(key, value);
184             }
185         };
186     }
187 
188     /** Define a new Integer value shared pref key. */
189     public SharedPreference<Integer> intValue(final String key, final Integer defaultValue) {
190         return new SharedPreference<Integer>(this, key) {
191             @Override
192             protected Integer read(SharedPreferences sp) {
193                 if (sp.contains(key)) {
194                     return sp.getInt(key, 0);
195                 }
196                 return defaultValue;
197             }
198 
199             @Override
200             protected void write(Editor editor, Integer value) {
201                 if (value == null) {
202                     throw new IllegalArgumentException("null cannot be written for Integer");
203                 }
204                 editor.putInt(key, value);
205             }
206         };
207     }
208 
209     /** Define a new Set<String> value shared pref key. */
210     public SharedPreference<Set<String>> stringSetValue(final String key,
211             final Set<String> defaultValue) {
212         return new SharedPreference<Set<String>>(this, key) {
213             @Override
214             protected Set<String> read(SharedPreferences sp) {
215                 if (sp.contains(key)) {
216                     return sp.getStringSet(key, null);
217                 }
218                 return defaultValue;
219             }
220 
221             @Override
222             protected void write(Editor editor, Set<String> value) {
223                 if (value == null) {
224                     throw new IllegalArgumentException("null cannot be written for Set<String>");
225                 }
226                 editor.putStringSet(key, value);
227             }
228         };
229     }
230 
231     /**
232      * A class representing a key/value pair in a given {@link PreferenceFile}.
233      */
234     public static abstract class SharedPreference<T> {
235         PreferenceFile mFile;
236         final String mKey;
237 
238         protected SharedPreference(PreferenceFile file, String key) {
239             mFile = file;
240             mKey = key;
241         }
242 
243         /** Read the value stored for this pref, or the default value if none is stored. */
244         public final T get() {
245             return read(mFile.open());
246         }
247 
248         /** Get the representation in string of the value for this pref. */
249         public String getValueString() {
250             T value = get();
251             if (value == null) {
252                 return null;
253             }
254             return value.toString();
255         }
256 
257         /** Return this pref's key. */
258         public final String getKey() {
259             return mKey;
260         }
261 
262         /** Return true if this key is defined in its file. */
263         public final boolean exists() {
264             return mFile.open().contains(mKey);
265         }
266 
267         /** Write a new value for this pref to its file. */
268         public final void put(T value) {
269             SharedPreferences sp = mFile.open();
270             Editor editor = sp.edit();
271             write(editor, value);
272             commit(editor);
273         }
274 
275         /** Removes this pref from its file. */
276         public final void remove() {
277             commit(mFile.open().edit().remove(mKey));
278         }
279 
280         /** Override the PreferenceFile used by this preference (for testing). */
281         public final void override(PreferenceFile file) {
282             mFile = file;
283         }
284 
285         protected abstract T read(SharedPreferences sp);
286         protected abstract void write(Editor editor, T value);
287     }
288 
289     /**
290      * Returns the length of the longest string in the provided Collection.
291      */
292     private static int longestString(Collection<String> strings) {
293         int longest = 0;
294         for (String s : strings) {
295             longest = Math.max(longest, s.length());
296         }
297         return longest;
298     }
299 }
300