Yesterday, the android team released WikiNotes , a personal wiki(like voodoopad), to help developers new to the platform get the hang of the flow of a typical android application. It provides a nice example of using intents to trigger activities directly, and associating activities with intents for the viewing of URI referenced content from a content provider. It also shows how to implement a content provider that allows the resolution of a URI on a field that isn’t the data’s ID column as well as perform searches via URI.
WikiNotes already provides support for automatically creating links for things like websites, phone numbers, and CamelCase formatted WikiNotes. Since android uses URIs to identify content on the phone, you can create links to any kind of content inside of WikiNotes.
I will provide a quick example of using the Linkify class to create a clickable link in a WikiNote that points to a contact in your address book.(hopefully, I am not stepping on anyone’s toes)
Before we start, since we will be accessing contacts on our phone we need to add the permission android.permission.READ_CONTACTS to our AndroidManifest.xml
Contacts are identified by the URI: content://contacts/people/#. I don’t think anyone would want to have to type out that whole thing on their handset keyboard so I will use the short hand “C:#” to identify a clickable contact in our WikiNote. This doesn’t make it any easier to identify who the contact actually is, but the contact provider currently only allows you to reference them by id number, plus its just easier to use a number for now.
Linkify uses a pattern matcher to identify which part of the string of a TextView to make into a clickable link so our first step is to define a wiki contact regex Pattern. If you open up WikiNotes you will see the declaration and definition for WIKI_WORD_MATCHER. Just under that we will add code for our wiki contact pattern.
private static final Pattern WIKI_WORD_MATCHER;
private static final Pattern WIKI_CONTACT_MATCHER;
static {
// Compile the regular expression pattern that will be used to
// match WikiWords in the body of the note
WIKI_WORD_MATCHER = Pattern.compile("\\b[A-Z]+[a-z0-9]+[A-Z][A-Za-z0-9]+\\b");
//match shorthand C:# for a wiki contact
WIKI_CONTACT_MATCHER =Pattern.compile("\\b[C]+[:]+[1-90-9]+\\b");
The next step is to Linkify the TextView so that when it is clicked it resolves to the full contact URI. Inside of the ShowWikiNotes() we want to add the following below the second Linkify.addLinks()
//add custom linkify match for contacts
Linkify.addLinks(noteView, WIKI_CONTACT_MATCHER,
android.provider.Contacts.People.CONTENT_URI.toString()+"/", null, new TransformFilter(){
public String transformUrl(Matcher matcher, String url) {
String ret = url.substring(2); //parse out the number
return ret;
}
});
This uses the method:
addLinks(TextView text, Pattern p, String scheme, MatchFilter matchFilter, TransformFilter transformFilter)
Where the first two parameter are obvious. Scheme is the uri to prepend to the matched text. MatchFilter which lets you further filter the matched text, and TransformFilter which takes the matched text and lets you change it before it is added to the scheme. In this case the string that is passed to the filter is “C:#” and we want to parse out the number part of the string.
Once you have done this you should be able to type C:1 into your WikiNote, confirm it and it will display a clickable link that will take you to the Contact viewing activity.
Woops… Well this is an interesting error in that it shows a little of how intent filters work. When the link is clicked in the TextView an intent with the View action and Browesable category is launched with it’s data set to the contact URI. The issue is that the ContactViewer activity does not have the the android.intent.category.BROWSABLE intent filter so when the intent is triggered the system can’t find an activity that matches it. Now if it did have that filter it would have displayed the following (hopefully):
As the number of content providers grows we can link to many different kinds of content in the wiki and have android automate the viewing of the content by calling the appropriate view activities. You can have links to music, videos, and images, but interestingly with a little modification you could launch all kinds of applications and intent actions from wiki links. You now have a wiki user interface where your users can easily design their own wiki-based navigation for their phone and it’s content.

