Review and reply to annotations on Android

With annotation replies, users are able to have written discussions directly inside a document. As of Nutrient Android SDK 4.5, Nutrient provides convenient APIs for accessing replies in a document, as well as user interface (UI) components for viewing and editing replies.

Annotations may also have author-specific states associated with them. This allows users to review a proposed change to, for example, say whether they agree or disagree with the change.

Nutrient has built-in support to let users view, search, and add replies and reviews. There’s also a model-level API for programmatic access so that you can build custom features. Nutrient implements annotation replies and state conforming to the PDF specification and is fully compatible with the same features in Adobe Acrobat Reader.

Terminology

This is the terminology we use:

  • Reply — An annotation with an in-reply-to annotation set.

  • Text reply — A reply where the author-specific state is unspecified.

  • State reply or state annotation — A reply where the author-specific state is specified.

  • Review — A state reply where the author-specific state is in the review state model (category).

  • Comments — The list containing an annotation and all of its text replies. This means the first comment displays the contents of the parent annotation. This is mostly a user-facing term.

Licensing

Replies is a separate component in your Nutrient license. Without this component, your app won’t be able to view, search, or add annotation replies. Contact our Sales team to add this component to your license.

Third-party compatibility

Replies were introduced in the PDF 1.6 specification and are fully compatible with Adobe Acrobat. Other PDF viewers might not be able to show all replies or may simply fail to display status information.

Screenshot of comments in Adobe Acrobat

Annotation Replies aren’t supported in Instant JSON.

User interface

Users can tap an annotation and then tap the comments toolbar button. This will present the note editor, which shows all the comments on the annotation, along with any reviews on those comments. Users can both add and edit the comments and add reviews.

Just like with other annotations, users can edit comments even if they didn’t create them.

If there are replies to replies, Nutrient will flatten the nested conversation into a single list sorted by date.

Disabling the replies and reviews UI

If your license includes annotation replies but you want to disable letting the user view and add replies and reviews, you can define a PdfConfiguration with the annotationReplyFeatureEnabled(false) method in the builder:

val configuration = PdfConfiguration.Builder().annotationReplyFeatureEnabled(false).build()
PdfConfiguration configuration = new PdfConfiguration.Builder().annotationReplyFeatureEnabled(false).build();

Then pass it when starting your PdfFragment or PdfActivity.

Model API

Replies to an annotation are themselves annotations. An annotation is a reply if it’s pointing to a parent by means of the Annotation#getInReplyTo() property. In the PDF, this is modeled with the IRT entry in the annotation dictionary. There’s no direct connection in the reverse direction, i.e. between an annotation and its replies. Instead, all the annotations on the same page must be searched. However, if you use the UI provided by Nutrient, this is all taken care of.

The author-specific state associated with an annotation isn’t specified in the annotation itself, but rather in a separate text annotation that refers to the original annotation by means of Annotation#getInReplyTo(). Each time a user changes the state, a new note annotation is created and appended to the linked list of state changes. To find the complete set of states associated with an annotation, it’s necessary to repeatedly search all the annotations on the same page to follow the reverse of Annotation#getInReplyTo(). Again, this is already handled in Nutrient’s UI.

Since replies are annotations, they’re included when querying the annotations on a page. You can check if an annotation is a reply using Annotation#isReply(). Doing this doesn’t require you to have the Replies component in your license.

If the license component is enabled, you can both read and set the annotation a reply replies to using Annotation#getInReplyTo() and Annotation#setInReplyTo(Annotation annotation).