diff options
| -rw-r--r-- | core/api/module-lib-current.txt | 4 | ||||
| -rw-r--r-- | core/java/android/provider/ContactsContract.java | 73 |
2 files changed, 77 insertions, 0 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index b574d0441258..172818d12b9e 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -311,6 +311,10 @@ package android.os.storage { package android.provider { + public static final class ContactsContract.RawContactsEntity implements android.provider.BaseColumns android.provider.ContactsContract.DataColumns android.provider.ContactsContract.RawContactsColumns { + method @NonNull @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) public static java.util.Map<java.lang.String,java.util.List<android.content.ContentValues>> queryRawContactEntity(@NonNull android.content.Context, long); + } + public final class DeviceConfig { field public static final String NAMESPACE_ALARM_MANAGER = "alarm_manager"; field public static final String NAMESPACE_APP_STANDBY = "app_standby"; diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java index 0f0f123ca162..a0f86159d50b 100644 --- a/core/java/android/provider/ContactsContract.java +++ b/core/java/android/provider/ContactsContract.java @@ -37,6 +37,7 @@ import android.content.Context; import android.content.ContextWrapper; import android.content.CursorEntityIterator; import android.content.Entity; +import android.content.Entity.NamedContentValues; import android.content.EntityIterator; import android.content.Intent; import android.content.IntentFilter; @@ -55,6 +56,7 @@ import android.os.RemoteException; import android.telecom.PhoneAccountHandle; import android.text.TextUtils; import android.util.DisplayMetrics; +import android.util.Log; import android.util.Pair; import android.view.View; @@ -64,7 +66,9 @@ import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Objects; import java.util.Set; @@ -5135,6 +5139,8 @@ public final class ContactsContract { */ public final static class RawContactsEntity implements BaseColumns, DataColumns, RawContactsColumns { + private static final String TAG = "ContactsContract.RawContactsEntity"; + /** * This utility class cannot be instantiated */ @@ -5187,6 +5193,73 @@ public final class ContactsContract { * <P>Type: INTEGER</P> */ public static final String DATA_ID = "data_id"; + + /** + * Query raw contacts entity by a contact ID, which can potentially be a corp profile + * contact ID + * + * @param context A context to get the ContentResolver from + * @param contactId Contact ID, which can potentialy be a corp profile contact ID. + * + * @return A map from a mimetype to a List of the entity content values. + * {@hide} + */ + @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.INTERACT_ACROSS_USERS) + public static @NonNull Map<String, List<ContentValues>> queryRawContactEntity( + @NonNull Context context, long contactId) { + Uri uri = RawContactsEntity.CONTENT_URI; + long realContactId = contactId; + + if (Contacts.isEnterpriseContactId(contactId)) { + uri = RawContactsEntity.CORP_CONTENT_URI; + realContactId = contactId - Contacts.ENTERPRISE_CONTACT_ID_BASE; + } + final Map<String, List<ContentValues>> contentValuesListMap = + new HashMap<String, List<ContentValues>>(); + // The resolver may return the entity iterator with no data. It is possible. + // e.g. If all the data in the contact of the given contact id are not exportable ones, + // they are hidden from the view of this method, though contact id itself exists. + EntityIterator entityIterator = null; + try { + final String selection = Data.CONTACT_ID + "=?"; + final String[] selectionArgs = new String[] {String.valueOf(realContactId)}; + + entityIterator = RawContacts.newEntityIterator(context.getContentResolver().query( + uri, null, selection, selectionArgs, null)); + + if (entityIterator == null) { + Log.e(TAG, "EntityIterator is null"); + return contentValuesListMap; + } + + if (!entityIterator.hasNext()) { + Log.w(TAG, "Data does not exist. contactId: " + realContactId); + return contentValuesListMap; + } + + while (entityIterator.hasNext()) { + Entity entity = entityIterator.next(); + for (NamedContentValues namedContentValues : entity.getSubValues()) { + ContentValues contentValues = namedContentValues.values; + String key = contentValues.getAsString(Data.MIMETYPE); + if (key != null) { + List<ContentValues> contentValuesList = contentValuesListMap.get(key); + if (contentValuesList == null) { + contentValuesList = new ArrayList<ContentValues>(); + contentValuesListMap.put(key, contentValuesList); + } + contentValuesList.add(contentValues); + } + } + } + } finally { + if (entityIterator != null) { + entityIterator.close(); + } + } + return contentValuesListMap; + } } /** |