/* * Copyright (C) 2013-2015 RoboVM AB * * 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. * * Portions of this code is based on Apple Inc's QuickContacts sample (v1.3) * which is copyright (C) 2010-2014 Apple Inc. */ package org.robovm.samples.quickcontacts.ui; import java.io.File; import java.util.Arrays; import java.util.List; import org.robovm.apple.addressbook.ABAddressBook; import org.robovm.apple.addressbook.ABPerson; import org.robovm.apple.addressbook.ABPersonEmailAddress; import org.robovm.apple.addressbook.ABPersonProperty; import org.robovm.apple.addressbook.ABProperty; import org.robovm.apple.addressbook.ABPropertyLabel; import org.robovm.apple.addressbookui.ABNewPersonViewController; import org.robovm.apple.addressbookui.ABNewPersonViewControllerDelegate; import org.robovm.apple.addressbookui.ABPeoplePickerNavigationController; import org.robovm.apple.addressbookui.ABPeoplePickerNavigationControllerDelegateAdapter; import org.robovm.apple.addressbookui.ABPersonViewController; import org.robovm.apple.addressbookui.ABPersonViewControllerDelegate; import org.robovm.apple.addressbookui.ABUnknownPersonViewController; import org.robovm.apple.addressbookui.ABUnknownPersonViewControllerDelegate; import org.robovm.apple.dispatch.DispatchQueue; import org.robovm.apple.foundation.NSArray; import org.robovm.apple.foundation.NSBundle; import org.robovm.apple.foundation.NSDictionary; import org.robovm.apple.foundation.NSError; import org.robovm.apple.foundation.NSErrorException; import org.robovm.apple.foundation.NSIndexPath; import org.robovm.apple.foundation.NSMutableArray; import org.robovm.apple.foundation.NSString; import org.robovm.apple.uikit.NSTextAlignment; import org.robovm.apple.uikit.UIAlertView; import org.robovm.apple.uikit.UINavigationController; import org.robovm.apple.uikit.UITableView; import org.robovm.apple.uikit.UITableViewCell; import org.robovm.apple.uikit.UITableViewCellAccessoryType; import org.robovm.apple.uikit.UITableViewCellStyle; import org.robovm.apple.uikit.UITableViewController; import org.robovm.objc.annotation.CustomClass; @CustomClass("QuickContactsViewController") public class QuickContactsViewController extends UITableViewController implements ABPersonViewControllerDelegate, ABNewPersonViewControllerDelegate, ABUnknownPersonViewControllerDelegate { private static final double EDIT_UNKNOW_CONTACT_ROW_HEIGHT = 81; private ABAddressBook addressBook; private NSArray<NSDictionary<NSString, NSString>> menuArray; @Override public void viewDidLoad() { super.viewDidLoad(); menuArray = new NSMutableArray<>(0); try { addressBook = ABAddressBook.create(null); checkAddressBookAccess(); } catch (NSErrorException e) { UIAlertView alert = new UIAlertView("Error", "Your device doesn't support access to contacts.", null, "Cancel"); alert.show(); } } /** * Check the authorization status of our application for Address Book */ private void checkAddressBookAccess() { switch (ABAddressBook.getAuthorizationStatus()) { case Authorized: // Update our UI if the user has granted access to their Contacts accessGrantedForAddressBook(); break; case NotDetermined: // Prompt the user for access to Contacts if there is no definitive // answer requestAddressBookAccess(); break; case Denied: case Restricted: // Display a message if the user has denied or restricted access to // Contacts UIAlertView alert = new UIAlertView("Privacy Warning", "Permission was not granted for Contacts.", null, "OK"); alert.show(); break; default: break; } } /** * Prompt the user for access to their Address Book data */ private void requestAddressBookAccess() { addressBook.requestAccess(new ABAddressBook.RequestAccessCompletionHandler() { @Override public void requestAccess(boolean granted, NSError error) { if (granted) { DispatchQueue.getMainQueue().async(new Runnable() { @Override public void run() { accessGrantedForAddressBook(); } }); } else { checkAddressBookAccess(); } } }); } /** * This method is called when the user has granted access to their address * book data. */ private void accessGrantedForAddressBook() { // Load data from the plist file String plistPath = NSBundle.getMainBundle().findResourcePath("Menu", "plist"); menuArray = (NSArray<NSDictionary<NSString, NSString>>) NSArray.read(new File(plistPath)); getTableView().reloadData(); } @Override public long getNumberOfSections(UITableView tableView) { return menuArray.size(); } @Override public long getNumberOfRowsInSection(UITableView tableView, long section) { return 1; } @Override public UITableViewCell getCellForRow(UITableView tableView, NSIndexPath indexPath) { final String cellIdentifier = "CellID"; UITableViewCell cell; // Make the Display Picker and Create New Contact rows look like buttons if (indexPath.getSection() < 2) { cell = new UITableViewCell(UITableViewCellStyle.Default, cellIdentifier); cell.getTextLabel().setTextAlignment(NSTextAlignment.Center); } else { cell = new UITableViewCell(UITableViewCellStyle.Subtitle, cellIdentifier); cell.setAccessoryType(UITableViewCellAccessoryType.DisclosureIndicator); cell.getDetailTextLabel().setNumberOfLines(0); // Display descriptions for the Edit Unknown Contact and Display and // Edit Contact rows cell.getDetailTextLabel().setText( menuArray.get(indexPath.getSection()).getString("description")); } cell.getTextLabel().setText( menuArray.get(indexPath.getSection()).getString("title")); return cell; } @Override public void didSelectRow(UITableView tableView, NSIndexPath indexPath) { switch (indexPath.getSection()) { case 0: showPeoplePickerController(); break; case 1: showNewPersonViewController(); break; case 2: showPersonViewController(); break; case 3: showUnknownPersonViewController(); break; default: showPeoplePickerController(); break; } } @Override public double getHeightForRow(UITableView tableView, NSIndexPath indexPath) { // Change the height if Edit Unknown Contact is the row selected return indexPath.getSection() == 3 ? EDIT_UNKNOW_CONTACT_ROW_HEIGHT : tableView.getRowHeight(); } /** * Called when users tap "Display Picker" in the application. Displays a * list of contacts and allows users to select a contact from that list. The * application only shows the phone, email, and birthdate information of the * selected contact. */ private void showPeoplePickerController() { ABPeoplePickerNavigationController picker = new ABPeoplePickerNavigationController(); picker.setPeoplePickerDelegate(new ABPeoplePickerNavigationControllerDelegateAdapter() { /** * Displays the information of a selected person. * * @param peoplePicker * @param person * @return */ @Override public boolean shouldContinueAfterSelectingPerson(ABPeoplePickerNavigationController peoplePicker, ABPerson person) { return true; } /** * Does not allow users to perform default actions such as dialing a * phone number, when they select a person property. * * @param peoplePicker * @param person * @param property * @param identifier * @return */ @Override public boolean shouldContinueAfterSelectingPerson(ABPeoplePickerNavigationController peoplePicker, ABPerson person, ABProperty property, int identifier) { return false; } /** * Dismisses the people picker and shows the application when users * tap Cancel. * * @param peoplePicker */ @Override public void didCancel(ABPeoplePickerNavigationController peoplePicker) { dismissViewController(true, null); } }); // Display only a person's phone, email, and birthdate List<ABPersonProperty> displayedItems = Arrays.asList(ABPersonProperty.Phone, ABPersonProperty.Email, ABPersonProperty.Birthday); picker.setDisplayedProperties(displayedItems); // Show the picker presentViewController(picker, true, null); } /** * Called when users tap "Display and Edit Contact" in the application. * Searches for a contact named "Appleseed" in in the address book. Displays * and allows editing of all information associated with that contact if the * search is successful. Shows an alert, otherwise. */ private void showPersonViewController() { // Search for the person named "Appleseed" in the address book List<ABPerson> people = addressBook.getPeople("Appleseed"); // Display "Appleseed" information if found in the address book if (people != null && people.size() > 0) { ABPerson person = people.get(0); ABPersonViewController picker = new ABPersonViewController(); picker.setPersonViewDelegate(this); picker.setDisplayedPerson(person); // Allow users to edit the person’s information picker.setAllowsEditing(true); getNavigationController().pushViewController(picker, true); } else { // Show an alert if "Appleseed" is not in Contacts UIAlertView alert = new UIAlertView("Error", "Could not find Appleseed in the Contacts application", null, "Cancel"); alert.show(); } } /** * Called when users tap "Create New Contact" in the application. Allows * users to create a new contact. */ private void showNewPersonViewController() { ABNewPersonViewController picker = new ABNewPersonViewController(); picker.setNewPersonViewDelegate(this); UINavigationController navigation = new UINavigationController(picker); presentViewController(navigation, true, null); } /** * Called when users tap "Edit Unknown Contact" in the application. */ private void showUnknownPersonViewController() { ABPerson person = ABPerson.create(); try { person.addEmailAddress(new ABPersonEmailAddress("[email protected]", ABPropertyLabel.Other)); ABUnknownPersonViewController picker = new ABUnknownPersonViewController(); picker.setUnknownPersonViewDelegate(this); picker.setDisplayedPerson(person); picker.setAllowsAddingToAddressBook(true); picker.setAllowsActions(true); picker.setAlternateName("John Appleseed"); picker.setTitle("John Appleseed"); picker.setMessage("Company, Inc"); getNavigationController().pushViewController(picker, true); } catch (NSErrorException e) { UIAlertView alert = new UIAlertView("Error", "Could not create unknown user", null, "Cancel"); alert.show(); } } /** * Dismisses the picker when users are done creating a contact or adding the * displayed person properties to an existing contact. */ @Override public void didResolveToPerson(ABUnknownPersonViewController unknownCardViewController, ABPerson person) { getNavigationController().popViewController(true); } /** * Does not allow users to perform default actions such as emailing a * contact, when they select a contact property. */ @Override public boolean shouldPerformDefaultAction(ABUnknownPersonViewController personViewController, ABPerson person, ABProperty property, int identifier) { return false; } /** * Dismisses the new-person view controller. */ @Override public void didComplete(ABNewPersonViewController newPersonView, ABPerson person) { dismissViewController(true, null); } /** * Does not allow users to perform default actions such as dialing a phone * number, when they select a contact property. */ @Override public boolean shouldPerformDefaultAction(ABPersonViewController personViewController, ABPerson person, ABProperty property, int identifier) { return false; } }