/**
* ContactListScreen.java
*
* Copyright � 1998-2011 Research In Motion Limited
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Note: For the sake of simplicity, this sample application may not leverage
* resource bundles and resource strings. However, it is STRONGLY recommended
* that application developers make use of the localization features available
* within the BlackBerry development platform to ensure a seamless application
* experience across a variety of languages and geographies. For more information
* on localizing your application, please refer to the BlackBerry Java Development
* Environment Development Guide associated with this release.
*/
package com.rim.samples.device.contactlinkingdemo;
import javax.microedition.pim.Contact;
import javax.microedition.pim.PIM;
import javax.microedition.pim.PIMException;
import javax.microedition.pim.PIMItem;
import net.rim.blackberry.api.invoke.AddressBookArguments;
import net.rim.blackberry.api.invoke.Invoke;
import net.rim.blackberry.api.pdap.BlackBerryContact;
import net.rim.blackberry.api.pdap.BlackBerryContactList;
import net.rim.blackberry.api.pdap.contactlinking.LinkableContact;
import net.rim.blackberry.api.pdap.contactlinking.LinkedContactUtilities;
import net.rim.device.api.command.Command;
import net.rim.device.api.command.CommandHandler;
import net.rim.device.api.command.ReadOnlyCommandMetadata;
import net.rim.device.api.system.Display;
import net.rim.device.api.ui.Color;
import net.rim.device.api.ui.DrawStyle;
import net.rim.device.api.ui.Field;
import net.rim.device.api.ui.Manager;
import net.rim.device.api.ui.MenuItem;
import net.rim.device.api.ui.XYRect;
import net.rim.device.api.ui.component.Dialog;
import net.rim.device.api.ui.component.LabelField;
import net.rim.device.api.ui.component.Menu;
import net.rim.device.api.ui.component.table.AbstractTableModel;
import net.rim.device.api.ui.component.table.DataTemplate;
import net.rim.device.api.ui.component.table.TableController;
import net.rim.device.api.ui.component.table.TableModelAdapter;
import net.rim.device.api.ui.component.table.TableView;
import net.rim.device.api.ui.component.table.TemplateColumnProperties;
import net.rim.device.api.ui.component.table.TemplateRowProperties;
import net.rim.device.api.ui.container.MainScreen;
import net.rim.device.api.ui.decor.BackgroundFactory;
import net.rim.device.api.util.StringProvider;
import net.rim.device.api.util.StringUtilities;
/**
* A screen displaying a list of contacts
*/
public final class ContactListScreen extends MainScreen {
private static SampleContact[] _contacts;
private static final int SELECT_CONTACT = 0;
private static final int CREATE_NEW = 1;
private MenuItem _viewEmailMenuItem;
private MenuItem _viewPhoneMenuItem;
private MenuItem _linkToBbContact;
private MenuItem _altLinkToBbContact;
private AbstractTableModel _model;
private TableView _view;
/**
* Creates a new ContactListScreen object
*/
public ContactListScreen() {
super(Manager.NO_VERTICAL_SCROLL);
// Initialize UI
setTitle("Contact Linking Demo");
_viewEmailMenuItem = new ViewEmailMenuItem();
_viewPhoneMenuItem = new ViewPhoneMenuItem();
_linkToBbContact = new LinkToContactMenuItem();
// Initialize the contact list with all contact information
initializeContacts();
// Create an adapter for displaying contact data in table
_model = new ContactTableModelAdapter();
_view = new TableView(_model);
final TableController controller = new TableController(_model, _view);
controller.setFocusPolicy(TableController.ROW_FOCUS);
_view.setController(controller);
// Set the highlight style for the view
_view.setDataTemplateFocus(BackgroundFactory
.createLinearGradientBackground(Color.LIGHTBLUE,
Color.LIGHTBLUE, Color.BLUE, Color.BLUE));
// Create a data template that will format the model data as an array of
// LabelFields
final DataTemplate dataTemplate = new DataTemplate(_view, 1, 1) {
public Field[] getDataFields(final int modelRowIndex) {
final Field[] fields =
{ new LabelField(((SampleContact) _model
.getRow(modelRowIndex)).toString(),
DrawStyle.ELLIPSIS | Field.NON_FOCUSABLE) };
return fields;
}
};
// Define the regions of the data template and column/row size
dataTemplate.createRegion(new XYRect(0, 0, 1, 1));
dataTemplate.setColumnProperties(0, new TemplateColumnProperties(
Display.getWidth()));
dataTemplate.setRowProperties(0, new TemplateRowProperties(24));
_view.setDataTemplate(dataTemplate);
dataTemplate.useFixedHeight(true);
// Add the contact list to the screen
add(_view);
}
/**
* Returns the contact currently highlighted in table
*
* @return The currently selected contact
*/
private SampleContact getSelectedContact() {
return (SampleContact) _model.getRow(_view.getRowNumberWithFocus());
}
/**
* Initializes the contacts
*/
private static void initializeContacts() {
int i = 0;
// Instantiate a new SampleContact array
_contacts = new SampleContact[7];
// Instantiate a new SampleContact object
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Clyde Warren");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-1234");
_contacts[i].setString(LinkableContact.EMAIL, "cwarren@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Scott Wyatt");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-7348");
_contacts[i].setString(LinkableContact.EMAIL, "swyatt@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Kevin Wilhelm");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-1123");
_contacts[i].setString(LinkableContact.EMAIL, "kwilhelm@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Karen Whittle");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-3456");
_contacts[i].setString(LinkableContact.EMAIL, "kwhittle@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Tanya Wahl");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-7785");
_contacts[i].setString(LinkableContact.EMAIL, "twahl@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Trevor Van Daele");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-7676");
_contacts[i].setString(LinkableContact.EMAIL, "tvandaele@rim.com");
i++;
_contacts[i] = new SampleContact(Integer.toString(i));
_contacts[i].setString(LinkableContact.NAME, "Heather Tiegs");
_contacts[i].setString(LinkableContact.MOBILE_PHONE, "555-5586");
_contacts[i].setString(LinkableContact.EMAIL, "htiegs@rim.com");
}
/**
* Gets the contact for a given login ID
*
* @param id
* The login id of the contact we're interested in
* @return The contact with the given login ID
*/
public static SampleContact getUserForID(final String id) {
if (_contacts == null) {
initializeContacts();
}
final int numUsers = _contacts.length;
for (int i = 0; i < numUsers; i++) {
if (_contacts[i].getContactID().equals(id)) {
return _contacts[i];
}
}
return null;
}
/**
* Unlinks a contact. This typically happens when the contact is selected to
* be linked to another SampleContact.
*
* @param linkableContact
* The contact to be unlinked
*/
private void unlinkContact(final LinkableContact linkableContact) {
final BlackBerryContact contact =
LinkedContactUtilities.getLinkedContact(linkableContact);
if (contact != null) {
LinkedContactUtilities.unlinkContact(contact, linkableContact
.getApplicationID());
}
}
/**
* Links a LinkableContact object to a BlackBerryContact
*
* @param linkableContact
* The LinkableContact object to be linked
*/
private static void linkContact(final LinkableContact linkableContact) {
// Check if there is a linking candidate
BlackBerryContact bbContact =
LinkedContactUtilities.getContactLinkCandidate(linkableContact);
// No linking candidate returned
if (bbContact == null) {
final String[] choices = { "Select Contact", "Create New" };
final int answer =
Dialog.ask(
linkableContact.getString(LinkableContact.NAME)
+ " is currently not "
+ "associated with a contact. Please select an option.",
choices, CREATE_NEW);
// Manually select contact from address book
if (answer == SELECT_CONTACT) {
BlackBerryContactList contacts = null;
try {
contacts =
(BlackBerryContactList) PIM.getInstance()
.openPIMList(PIM.CONTACT_LIST,
PIM.READ_WRITE);
} catch (final PIMException e) {
ContactLinkingDemo
.errorDialog("Couldn't open contacts list. PIM.openPIMList() threw "
+ e.toString());
return;
}
final Object choice = contacts.choose();
if (choice instanceof BlackBerryContact) {
bbContact = (BlackBerryContact) choice;
}
if (bbContact != null) {
// Check if contact from address book has been linked to
// another LinkableContact.
if (LinkedContactUtilities.isContactLinked(bbContact,
linkableContact.getApplicationID())) {
final int selection =
Dialog.ask(
Dialog.D_YES_NO,
"This contact is already linked. Are you sure you want "
+ "to link to a different contact? ",
Dialog.NO);
if (selection == Dialog.YES) {
// Undo the previous linking
bbContact =
LinkedContactUtilities.unlinkContact(
bbContact, linkableContact
.getApplicationID());
} else {
bbContact = null;
}
}
if (bbContact != null) {
// Link the BlackBerryContact to the LinkableContact
bbContact =
LinkedContactUtilities.linkContact(bbContact,
linkableContact);
}
}
} else if (answer == CREATE_NEW) {
// Create a new contact from phone for the current linking
bbContact = createContactFor(linkableContact);
}
} else // Found link candidate
{
// Get display name
final String displayName = getDisplayName(bbContact);
// Create prompt message
final StringBuffer msg =
new StringBuffer(
"Linking candidate found. Link to contact ");
if (displayName != null) {
msg.append(displayName);
}
msg.append('?');
// Prompt to link contact
final int answer =
Dialog.ask(Dialog.D_YES_NO, msg.toString(), Dialog.NO);
if (answer == Dialog.YES) {
bbContact =
LinkedContactUtilities.linkContact(bbContact,
linkableContact);
} else {
bbContact = null;
}
}
if (bbContact != null) {
Dialog.inform("Contact has been linked successfully");
}
}
/**
* Create a new address card for a contact and link that contact to the
* application.
*
* @param userData
* The LinkableContact object to be created in the contacts list
* @return A reference to a new BlackBerryContact, or null if the operation
* was not successful
*/
private static BlackBerryContact createContactFor(
final LinkableContact linkableContact) {
// Obtain list of contacts
BlackBerryContactList contacts;
try {
contacts =
(BlackBerryContactList) PIM.getInstance().openPIMList(
PIM.CONTACT_LIST, PIM.READ_WRITE);
} catch (final PIMException e) {
ContactLinkingDemo
.errorDialog("Could not open contacts list. PIM#openPIMList() threw "
+ e.toString());
return null;
}
// Create a new BlackBerryContact
BlackBerryContact contact =
(BlackBerryContact) contacts.createContact();
// Set the mobile phone number for the new BlackBerryContact
final String mobileNumber =
linkableContact.getString(LinkableContact.MOBILE_PHONE);
if (mobileNumber != null) {
contact.addString(Contact.TEL, Contact.ATTR_MOBILE, mobileNumber);
}
// Set the email address for the new BlackBerryContact
final String emailAddress =
linkableContact.getString(LinkableContact.EMAIL);
if (emailAddress != null) {
contact.addString(Contact.EMAIL, Contact.ATTR_PREFERRED,
linkableContact.getString(LinkableContact.EMAIL));
}
// Set the name for the new BlackBerryContact
final String[] names =
StringUtilities.stringToWords(linkableContact
.getString(LinkableContact.NAME));
final String[] nameArray =
new String[contacts.stringArraySize(Contact.NAME)];
nameArray[Contact.NAME_FAMILY] = names[1];
nameArray[Contact.NAME_GIVEN] = names[0];
contact.addStringArray(Contact.NAME, PIMItem.ATTR_NONE, nameArray);
// Invoke the Adress Book application
final AddressBookArguments abArg =
new AddressBookArguments(AddressBookArguments.ARG_NEW, contact);
Invoke.invokeApplication(Invoke.APP_TYPE_ADDRESSBOOK, abArg);
try {
// Commit changes to the contact model
contact.commit();
// Link the linkable contact with the new BlackBerry contact
contact =
LinkedContactUtilities
.linkContact(contact, linkableContact);
} catch (final PIMException e) {
Dialog.inform("BlackBerryContact.commit() threw exception: "
+ e.toString());
}
return contact;
}
/**
* @see MainScreen#makeMenu(Menu, int)
*/
protected void makeMenu(final Menu menu, final int instance) {
menu.add(_viewEmailMenuItem);
menu.add(_viewPhoneMenuItem);
final LinkableContact selected = getSelectedContact();
if (LinkedContactUtilities.getLinkedContact(selected) != null) {
menu.add(new UnlinkContactMenuItem());
} else {
menu.add(_linkToBbContact);
}
super.makeMenu(menu, instance);
}
/**
* Adapter for displaying contact information in table format
*/
private static class ContactTableModelAdapter extends TableModelAdapter {
/**
* @see net.rim.device.api.ui.component.table.TableModelAdapter#getNumberOfRows()
*/
public int getNumberOfRows() {
return _contacts.length;
}
/**
* @see net.rim.device.api.ui.component.table.TableModelAdapter#getNumberOfColumns()
*/
public int getNumberOfColumns() {
return 1;
}
/**
* @see net.rim.device.api.ui.component.table.TableModelAdapter#doGetRow(int)
*/
public Object doGetRow(final int rowIndex) {
return _contacts[rowIndex];
}
};
/**
* MenuItem class to display a contact's email address
*/
private class ViewEmailMenuItem extends MenuItem {
public ViewEmailMenuItem() {
super(new StringProvider("View Email"), 0x230020, 0);
this.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
Dialog.inform(getSelectedContact().getString(
LinkableContact.EMAIL));
}
}));
}
}
/**
* MenuItem class to display a contact's phone number
*/
private class ViewPhoneMenuItem extends MenuItem {
public ViewPhoneMenuItem() {
super(new StringProvider("View Phone"), 0x230020, 0);
this.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
Dialog.inform(getSelectedContact().getString(
LinkableContact.MOBILE_PHONE));
}
}));
}
}
/**
* MenuItem to link a LinkableContact to a BlackBerryContact
*/
private class LinkToContactMenuItem extends MenuItem {
public LinkToContactMenuItem() {
super(new StringProvider("Link To BlackBerry Contact"), 0x230030, 0);
this.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
linkContact(getSelectedContact());
}
}));
}
}
/**
* Returns the name to be displayed for a given Contact
*
* @param contact
* The Contact for which to extract the display name
* @return The name to be displayed
*/
public static String getDisplayName(final Contact contact) {
if (contact == null) {
return null;
}
String displayName = null;
// See if there is a meaningful name set for the contact
if (contact.countValues(Contact.NAME) > 0) {
final String[] name = contact.getStringArray(Contact.NAME, 0);
final String firstName = name[Contact.NAME_GIVEN];
final String lastName = name[Contact.NAME_FAMILY];
if (firstName != null && lastName != null) {
displayName = firstName + " " + lastName;
} else if (firstName != null) {
displayName = firstName;
} else if (lastName != null) {
displayName = lastName;
}
if (displayName != null) {
final String namePrefix = name[Contact.NAME_PREFIX];
if (namePrefix != null) {
displayName = namePrefix + " " + displayName;
}
return displayName;
}
}
// If no meaningful name is set, use the company name
if (contact.countValues(Contact.ORG) > 0) {
final String companyName = contact.getString(Contact.ORG, 0);
if (companyName != null) {
return companyName;
}
}
return displayName;
}
/**
* MenuItem to unlink a LinkableContact
*/
private class UnlinkContactMenuItem extends MenuItem {
public UnlinkContactMenuItem() {
super(new StringProvider("Unlink Contact"), 0x230060, 0);
this.setCommand(new Command(new CommandHandler() {
/**
* @see net.rim.device.api.command.CommandHandler#execute(ReadOnlyCommandMetadata,
* Object)
*/
public void execute(final ReadOnlyCommandMetadata metadata,
final Object context) {
unlinkContact(getSelectedContact());
}
}));
}
}
}