Skip to content
Mike Angstadt edited this page May 22, 2022 · 7 revisions

Parts of my ADR property value are getting lost. What's wrong?

Comma characters have special meaning inside of a vCard. If they are not escaped properly, then ez-vcard splits the value by comma and ignores everything but the first value.

In the example below, ez-vcard thinks the street address is "123 Main St" because the comma character is not escaped with a backslash.

ADR:;;123 Main St, Apt 22;Springfield;MA;01109;USA

In ez-vcard versions 0.9.9 and above, calling the Address.getStreetAddressFull() method will return the entire street address field, treating the comma as a normal character. Or, you can call the Address.getStreetAddresses() method to get the entire list of split values.

In versions 0.9.8 and below, you'll need to register a custom ADR scribe in order to treat comma characters as normal characters (shown below).

VCardReader reader = new VCardReader(...);
reader.getScribeIndex().register(new AddressScribe() {
  @Override
  protected Address _parseText(String value, VCardDataType dataType, VCardVersion version, VCardParameters parameters, List<String> warnings) {
    String components[] = value.split(";");
    int i = 0;

    Address property = new Address();
    property.setPoBox(next(components, i++));
    property.setExtendedAddress(next(components, i++));
    property.setStreetAddress(next(components, i++));
    property.setLocality(next(components, i++));
    property.setRegion(next(components, i++));
    property.setPostalCode(next(components, i++));
    property.setCountry(next(components, i++));
    return property;
  }

  private String next(String components[], int index) {
    if (index >= components.length) return null;
    String next = components[index];
    return (next.length() > 0) ? next : null;
  }
});

I want to create an hCard (HTML-encoded vCard), but want to customize the HTML that is generated. Why can't I specify my own HTML template with the HCardPage class?

hCards are tightly intertwined with the HTML code of a webpage. Due to this fact, it is difficult to develop a general purpose hCard "writer" that can be "plugged into" any given webpage. ez-vcard's HCardPage class, which is used to generate hCards, serves more as an example of what a vCard looks like when embedded in HTML.

The HCardPage class itself is not much more than a wrapper around some Freemarker templating code. If you're interested in learning how to embed an hCard in your own website, feel free to use this template file as a starting point for learning about the hCard format.

How do I get the names and values of all the properties in a VCard object? There's no getName() or getValue() method!

ez-vcard considers property names to be part of the "serialization" part of the framework. Therefore, they are not stored in the property class, but in a separate class that contains logic for serializing and deserializing the property. ez-vcard calls this class the scribe class.

Similarly, the way a property's value looks varies depending on the version and format a vCard is serialized to. Many property classes lack a getValue() method because the unmarshalled value of a property is not always a simple String. For example, the value of the ADR property is composed of multiple components, so ez-vcard separates out each component into its own String field.

To get the name and value of each property, you'll have to use of each property's scribe class. The example below demonstrates how to do this. It uses the ScribeIndex class to retrieve each property's scribe class, uses the scribe class to get the property's name and value, and then outputs the name and value to stdout.

Note that a vCard version must be specified in order to generate the property value. In this example, version 3.0 is used. Also note that this example does not output property parameters.

VCard vcard = ...
ScribeIndex index = new ScribeIndex();
WriteContext context = new WriteContext(VCardVersion.V3_0, null, true);
for (VCardProperty property : vcard) {
  VCardPropertyScribe scribe = index.getPropertyScribe(property);
  String name = scribe.getPropertyName();
  String value = scribe.writeText(property, context);
  System.out.println(name + " = " + value);
}

If you are interested in doing this for debugging reasons, note that all of ez-vcard's property classes implement Java's toString() method, so you can simply pass a VCard instance to System.out to see its contents.

Some of the characters in my vCard are not being read correctly by my email client.

Some email clients have trouble processing non-ASCII characters. One possible work-around is to encode the property's value in "quoted-printable" encoding, as demonstrated below:

VCard vcard = new VCard();
FormattedName fn = vcard.setFormattedName("André Müller");
fn.getParameters().setEncoding(Encoding.QUOTED_PRINTABLE);
fn.getParameters().setCharset("ISO-8859-1");
vcard.write(System.out);

Outputs:

BEGIN:VCARD
VERSION:3.0
PRODID:ez-vcard 0.9.11
FN;ENCODING=QUOTED-PRINTABLE;CHARSET=ISO-8859-1:Andr=E9 M=FCller
END:VCARD

I am getting a NPE on startup when using ez-vcard with my Android app

Several Android developers who use ez-vcard in their apps have reported getting a NullPointerException on startup. The exception is thrown from the static initializer of the Ezvcard class when it tries to read a .properties file from the classpath.

This properties file was removed in version 0.11.3, so upgrading should resolve the issue.

If you are unable to upgrade to version 0.11.3 or later, many people were able to solve the problem by adjusting their Proguard rules. See this issue for more information.