1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 package org.xwalk.core.extension.api.contacts;
7 import android.content.ContentProviderOperation;
8 import android.content.ContentProviderResult;
9 import android.content.ContentResolver;
10 import android.content.ContentUris;
11 import android.content.OperationApplicationException;
12 import android.database.Cursor;
13 import android.net.Uri;
14 import android.os.RemoteException;
15 import android.provider.ContactsContract;
16 import android.provider.ContactsContract.Data;
17 import android.provider.ContactsContract.Groups;
18 import android.provider.ContactsContract.RawContacts;
19 import android.util.Log;
21 import java.text.ParseException;
22 import java.text.SimpleDateFormat;
23 import java.util.ArrayList;
24 import java.util.HashSet;
28 public class ContactUtils {
29 private static final String TAG = "ContactUtils";
30 public ContentResolver mResolver;
31 public ContactUtils(ContentResolver resolver) {
35 public static <K, V> K getKeyFromValue(Map<K, V> map, V value) {
37 for (Map.Entry<K, V> entry : map.entrySet()) {
38 if (value != null && value.equals(entry.getValue())) {
47 * @param strings e.g. ["apple", "orange", "banana"]
48 * @return A list of question marks to be used in SQL clause, e.g. "?,?,?"
50 public static String makeQuestionMarkList(Set<String> strings) {
52 for (int i = 0; i < strings.size(); ++i) {
55 return ret.substring(0, ret.length()-1);
58 public boolean hasID(String id) {
59 if (id == null) return false;
62 c = mResolver.query(ContactsContract.Contacts.CONTENT_URI,
63 null, ContactsContract.Contacts._ID + " = ?",
64 new String[]{id}, null);
65 return (c.getCount() != 0);
66 } catch (SecurityException e) {
67 Log.e(TAG, "hasID: " + e.toString());
70 if (c != null) c.close();
74 public String getRawId(String id) {
77 c = mResolver.query(RawContacts.CONTENT_URI, new String[]{RawContacts._ID},
78 RawContacts.CONTACT_ID + "=?", new String[]{id}, null);
79 if (c.moveToFirst()) {
80 // Actually it is possible that for one contact id there are multiple rawIds.
81 return c.getString(0);
85 } catch (SecurityException e) {
86 Log.e(TAG, "getRawId: " + e.toString());
89 if (c != null) c.close();
93 public String getId(String rawId) {
96 c = mResolver.query(RawContacts.CONTENT_URI, new String[]{RawContacts.CONTACT_ID},
97 RawContacts._ID + "=?", new String[]{rawId}, null);
98 if (c.moveToFirst()) {
99 return c.getString(0);
103 } catch (SecurityException e) {
104 Log.e(TAG, "getId: " + e.toString());
107 if (c != null) c.close();
111 public Set<String> getCurrentRawIds() {
114 c = mResolver.query(RawContacts.CONTENT_URI,
115 new String[]{RawContacts._ID}, null, null, null);
116 Set<String> rawIds = new HashSet<String>();
117 while (c.moveToNext()) {
118 rawIds.add(c.getString(0));
121 } catch (SecurityException e) {
122 Log.e(TAG, "getCurrentRawIds: " + e.toString());
125 if (c != null) c.close();
129 public String[] getDefaultAccountNameAndType() {
130 ArrayList<ContentProviderOperation> ops = new ArrayList<ContentProviderOperation>();
131 ops.add(ContentProviderOperation.newInsert(RawContacts.CONTENT_URI)
132 .withValue(RawContacts.ACCOUNT_NAME, null)
133 .withValue(RawContacts.ACCOUNT_TYPE, null)
136 ContentProviderResult[] results = null;
138 results = mResolver.applyBatch(ContactsContract.AUTHORITY, ops);
139 } catch (Exception e) {
140 if (e instanceof RemoteException ||
141 e instanceof OperationApplicationException ||
142 e instanceof SecurityException) {
143 Log.e(TAG, "getDefaultAccountNameAndType - Failed to apply batch: " + e.toString());
146 throw new RuntimeException(e);
150 Uri rawContactUri = null;
151 long rawContactId = 0;
152 for (ContentProviderResult result : results) {
153 rawContactUri = result.uri;
154 rawContactId = ContentUris.parseId(rawContactUri);
158 String accountType = "";
159 String accountName = "";
161 c = mResolver.query(RawContacts.CONTENT_URI,
162 new String[] {RawContacts.ACCOUNT_TYPE, RawContacts.ACCOUNT_NAME},
163 RawContacts._ID + "=?",
164 new String[] {String.valueOf(rawContactId)}, null);
165 if (c.moveToFirst()) {
166 if (!c.isAfterLast()) {
167 accountType = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_TYPE));
168 accountName = c.getString(c.getColumnIndex(RawContacts.ACCOUNT_NAME));
171 } catch (SecurityException e) {
172 Log.e(TAG, "getDefaultAccountNameAndType: " + e.toString());
175 if (c != null) c.close();
178 mResolver.delete(rawContactUri, null, null);
180 return new String[] { accountName, accountType };
183 public String getGroupId(String groupTitle) {
184 final String selection = Groups.DELETED + "=? and " + Groups.GROUP_VISIBLE + "=?";
187 c = mResolver.query(Groups.CONTENT_URI, null, selection, new String[]{"0", "1"}, null);
189 for (int i = 0; i < c.getCount(); i++) {
190 final String title = c.getString(c.getColumnIndex(Groups.TITLE));
191 if (title.equals(groupTitle)) {
192 return c.getString(c.getColumnIndex(Groups._ID));
197 } catch (SecurityException e) {
198 Log.e(TAG, "getGroupId: " + e.toString());
201 if (c != null) c.close();
205 public String getGroupTitle(String groupId) {
206 final String selection = Groups.DELETED + "=? and " + Groups.GROUP_VISIBLE + "=?";
209 c = mResolver.query(Groups.CONTENT_URI, null, selection, new String[]{"0", "1"}, null);
211 for (int i = 0; i < c.getCount(); i++) {
212 final String id = c.getString(c.getColumnIndex(Groups._ID));
213 if (id.equals(groupId)) {
214 return c.getString(c.getColumnIndex(Groups.TITLE));
219 } catch (SecurityException e) {
220 Log.e(TAG, "getGroupTitle: " + e.toString());
223 if (c != null) c.close();
227 public String getEnsuredGroupId(String groupTitle) {
228 String groupId = getGroupId(groupTitle);
229 if (groupId == null) {
230 newGroup(groupTitle);
231 groupId = getGroupId(groupTitle);
232 if (groupId == null) return null;
237 public void newGroup(String groupTitle) {
238 final String accountNameType[] = getDefaultAccountNameAndType();
239 ArrayList<ContentProviderOperation> o = new ArrayList<ContentProviderOperation>();
240 o.add(ContentProviderOperation.newInsert(Groups.CONTENT_URI)
241 .withValue(Groups.TITLE, groupTitle)
242 .withValue(Groups.GROUP_VISIBLE, true)
243 .withValue(Groups.ACCOUNT_NAME, accountNameType[0])
244 .withValue(Groups.ACCOUNT_TYPE, accountNameType[1])
247 mResolver.applyBatch(ContactsContract.AUTHORITY, o);
248 } catch (Exception e) {
249 if (e instanceof RemoteException ||
250 e instanceof OperationApplicationException ||
251 e instanceof SecurityException) {
252 Log.e(TAG, "newGroup - Failed to create new contact group: " + e.toString());
254 throw new RuntimeException(e);
259 public void cleanByMimeType(String id, String mimeType) {
260 mResolver.delete(Data.CONTENT_URI,
261 String.format("%s = ? AND %s = ?", Data.CONTACT_ID, Data.MIMETYPE),
262 new String[] {id, mimeType});
266 * Get date only from a JSON date string
267 * @param string e.g. "1969-12-31T16:00:20.012-0800"
268 * @return string e.g. "1969-12-31"
270 public String dateTrim(String string) {
273 final SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd", java.util.Locale.getDefault());
274 date = df.format(df.parse(string));
275 } catch (ParseException e) {
276 Log.e(TAG, "dateFormat - parse failed: " + e.toString());