12

So I've been reading up on how the auto-generated background color for contacts is created. Apparently it's based on a hashCode() of a key in the contact. I've seen it said that the email is used as the key, but that makes no sense, since not all my contacts have emails associated with them, and the ones that don't aren't all the same color.

Ultimately, I want to be able to get the EXACT color used in the contact's card. That way the icon I have in my app has the same background color as will be used when you click on it and open the contact card using the ACTION_VIEW.

So, just wondering what I need to use as a key to generate the same color that is generated by the android contacts app, for each individual contact? Thanks.

PS. Here's the hex codes that I have right now for the color palate. If someone could chime in on the accuracy of this as well, I would really appreciate it. Thanks.

<array name="letter_tile_colors">
        <item>#f16364</item>
        <item>#f58559</item>
        <item>#f9a43e</item>
        <item>#e4c62e</item>
        <item>#67bf74</item>
        <item>#59a2be</item>
        <item>#2093cd</item>
        <item>#ad62a7</item>
    </array>

Edit: Some folks have been saying it's similar to another answer, Android lollipop contact color

The problem with that answer is it's incomplete. It explains how to generate colors in the same way, but I'm not just trying to do random color generation. I'm looking to get the EXACT color that the default contacts app uses for that contact.

Community
  • 1
  • 1
craigmiller160
  • 5,751
  • 9
  • 41
  • 75

2 Answers2

7

From Google ContactsCommon source code:

The identifier is a unique and deterministic string that can be used to identify this contact. This is usually the contact's lookup key, but other contact details can be used as well, especially for non-local or temporary contacts that might not have a lookup key. This is used to determine the color of the tile. From ContactPhotoManager.

The identifier is used LetterTileDrawable class to select the tile color (identifier comes from contact request).

/**
 * Returns a deterministic color based on the provided contact identifier string.
 */
private int pickColor(final String identifier) {
    if (TextUtils.isEmpty(identifier) || mContactType == TYPE_VOICEMAIL) {
        return sDefaultColor;
    }
    // String.hashCode() implementation is not supposed to change across java versions, so
    // this should guarantee the same email address always maps to the same color.
    // The email should already have been normalized by the ContactRequest.
    final int color = Math.abs(identifier.hashCode()) % sColors.length();
    return sColors.getColor(color, sDefaultColor);
}

Palettes are defined in colors.xml file:

<!-- Background colors for LetterTileDrawables. This set of colors is a subset of
    https://spec.googleplex.com/quantumpalette#extended which passes Google Accessibility
    Requirements for the color in question on white with >= 3.0 contrast. We used
    http://leaverou.github.io/contrast-ratio/#white-on-%23db4437 to double-check the contrast.
    These colors are also used by MaterialColorMapUtils to generate primary activity colors.
-->
<array name="letter_tile_colors">
    <item>#DB4437</item>
    <item>#E91E63</item>
    <item>#9C27B0</item>
    <item>#673AB7</item>
    <item>#3F51B5</item>
    <item>#4285F4</item>
    <item>#039BE5</item>
    <item>#0097A7</item>
    <item>#009688</item>
    <item>#0F9D58</item>
    <item>#689F38</item>
    <item>#EF6C00</item>
    <item>#FF5722</item>
    <item>#757575</item>
</array>
<!-- Darker versions of letter_tile_colors, two shades darker. These colors are used
    for settings secondary activity colors. -->
<array name="letter_tile_colors_dark">
    <item>#C53929</item>
    <item>#C2185B</item>
    <item>#7B1FA2</item>
    <item>#512DA8</item>
    <item>#303F9F</item>
    <item>#3367D6</item>
    <item>#0277BD</item>
    <item>#006064</item>
    <item>#00796B</item>
    <item>#0B8043</item>
    <item>#33691E</item>
    <item>#E65100</item>
    <item>#E64A19</item>
    <item>#424242</item>
</array>
<!-- The default color used for tinting photos when no color can be extracted via Palette,
        this is Blue Grey 500 -->
<color name="quickcontact_default_photo_tint_color">#607D8B</color>
<!-- The default secondary color when no color can be extracted via Palette,
        this is Blue Grey 700 -->
<color name="quickcontact_default_photo_tint_color_dark">#455A64</color>
<color name="letter_tile_default_color">#cccccc</color>
<color name="letter_tile_font_color">#ffffff</color>
Gustavo Morales
  • 2,614
  • 9
  • 29
  • 37
-1

Hope this might help you

 private static final int NUM_OF_TILE_COLORS = 8;
 private final TypedArray mColors;

    //initialize inside oncreate of your activity
    mColors = res.obtainTypedArray(R.array.letter_tile_colors);//array of colors you have

    //call in wherver you want, key is the name of the contact
    private int pickColor(String key) {
    // String.hashCode() is not supposed to change across java versions, so
    // this should guarantee the same key always maps to the same color
    final int color = Math.abs(key.hashCode()) % NUM_OF_TILE_COLORS;
    try {
        return mColors.getColor(color, Color.BLACK);
    } finally {
        mColors.recycle();
    }
}
SaravInfern
  • 3,338
  • 1
  • 20
  • 44
  • 1
    Unfortunately it doesnt. That part I have figured out. It's the key value that's the problem. What key does Google use for its contacts values? – craigmiller160 Jul 10 '16 at 13:46