BCards_FinalReport

advertisement
February, 2011
Business Card Application
On Android
Submitted by:
Koren Shoval
Eyal Segal
Advisor:
Nethanel Azuleus
Index
1.
INTRODUCTION ........................................................................................................................................................... 4
1.1.
ABOUT ANDROID .................................................................................................................................................... 4
1.2.
PROJECT GOALS ...................................................................................................................................................... 4
1.3.
WORKING ENVIRONMENT ...................................................................................................................................... 5
2.
SYSTEM OVERVIEW ..................................................................................................................................................... 6
2.1.
TECHNOLOGIES ....................................................................................................................................................... 8
2.1.1.
BLUETOOTH ........................................................................................................................................................ 8
2.1.2.
ENCRYPTION ....................................................................................................................................................... 9
3.
USE CASES ................................................................................................................................................................. 11
3.1.
UC01 - BUSINESS CARD EDITOR ............................................................................................................................. 11
3.1.1.
UC0101 - CREATE CARD ..................................................................................................................................... 11
3.1.2.
UC0102 - EDIT CARD .......................................................................................................................................... 12
3.1.3.
UC0103 - CREATE ITEM LAYOUT ........................................................................................................................ 12
3.1.4.
UC0104 - EDIT ITEM LAYOUT ............................................................................................................................. 13
3.1.5.
UC0105 - POSITION ITEM ON A CARD ............................................................................................................... 13
3.1.6.
UC0106 - MANAGE ALL ITEMS ........................................................................................................................... 14
3.1.7.
UC0107 - CREATE NEW THEME FROM A CARD .................................................................................................. 14
3.1.8.
UC0108 - APPLY A THEME ................................................................................................................................. 15
3.1.9.
UC0109 - SET BACKGROUND FROM ANDROID GALLERY .................................................................................... 15
3.2.
UC02 – TABS BROWSE ........................................................................................................................................... 16
3.2.1.
UC0201 - BROWSE FOR A CARD ........................................................................................................................ 16
3.2.2.
UC0202 - SEARCH FOR A CARD .......................................................................................................................... 16
3.2.3.
UC0203 - CREATE FOLDER ................................................................................................................................. 17
3.2.4.
UC0204 - RENAME FOLDER ............................................................................................................................... 17
3.2.5.
UC0205 - DELETE FOLDER .................................................................................................................................. 18
3.2.6.
UC0206 - USE A BUSINESS CARD (SMS, CALL, EMAIL, ETC.). .............................................................................. 18
3.2.7.
UC0207 - MOVE A CARD BETWEEN FOLDERS .................................................................................................... 19
3.3.
UC03 – GALLERY BROWSER ................................................................................................................................... 20
3.3.1.
UC0301 - BROWSE FOR A CARD ........................................................................................................................ 20
3.3.2.
UC0302 - SEARCH FOR A CARD .......................................................................................................................... 21
3.3.3.
UC0303 - CREATE FOLDER ................................................................................................................................. 22
3.3.4.
UC0304 - RENAME FOLDER ............................................................................................................................... 22
3.3.5.
UC0305 - DELETE FOLDER .................................................................................................................................. 23
3.3.6.
UC0306 - USE A BUSINESS CARD (SMS, CALL, EMAIL, ETC.) ............................................................................... 23
3.3.7.
UC0307 - MOVE A CARD BETWEEN FOLDERS .................................................................................................... 24
3.4.
UC04 – BLUETOOTH .............................................................................................................................................. 25
3.4.1.
UC0401 - SEND BUSINESS CARD VIA BLUETOOTH ............................................................................................. 25
3.4.2.
UC0402 - RECEIVE A BUSINESS CARD ................................................................................................................ 27
4.
DESIGN & IMPLEMENTATION .................................................................................................................................... 28
4.1.
BACKGROUND SERVICE ......................................................................................................................................... 30
4.2.
NOTIFICATIONS ..................................................................................................................................................... 32
4.3.
STORAGE SERVICE ................................................................................................................................................. 34
4.4.
BLUETOOTH & ENCRYPTION.................................................................................................................................. 35
4.4.1.
SEND - RECEIVE SEQUENCE ............................................................................................................................... 38
4.4.2.
ENCRYPTION SEQUENCE ................................................................................................................................... 39
4.5.
BUSINESS CARDS DATA STRUCTURES .................................................................................................................... 41
4.6.
BUSINESS CARD EDITOR ........................................................................................................................................ 43
4.7.
BUSINESS CARDS TABS STYLE BROWSER ............................................................................................................... 45
4.8.
BUSINESS CARDS GALLERY STYLE BROWSER ......................................................................................................... 47
5.
OPTIMIZATIONS ........................................................................................................................................................ 49
6.
REFERENCES .............................................................................................................................................................. 50
1. Introduction
1.1.
About Android
Android is an operating system, developed for mobile phones as open source code.
The OS initially developed by Android Inc., which later was bought by Google in 2005. The Android is based
on a modified version of Linux kernel, and provides a Java based libraries for application development.
Today, there is a large community of developers which extends the Android devices abilities.
Currently, there are over 200,000 applications available for Android.
Android supports many known standards, including graphical abilities (OpenGL ES), database analysis
(SQLite), data encryption and much more.
In this project we used Android API level 8 (Version 2.2)
1.2.
Project Goals
One of our main goals in this project was to learn how to use Android API in order to develop an application
for mobile phones. This includes understanding the way Android works in every aspect, and apply our
knowledge with the Android SDK. Part of this main goal is to understand how a graphical user interface
works in one device or how it fits into many different devices, and to build such a GUI.
Another important goal is to successfully transmit data from one device to another, using Bluetooth
protocol. The transmission consists of pairing two devices, connecting them and sending/receiving the data.
The last goal was to make sure that the data can be transferred safe, according to user choice, using
encryption protocol. This includes authentication process between two users who want to exchange data.
To implement all these goals, we selected an application that manages business cards collection and allows
transferring them between users with or without authentication.
1.3.
Working Environment
The OS we worked with is Windows Vista x86. Our development tools included the Eclipse IDE for Java, the
Android SDK and emulators, Eclipse Memory Analyzer and two HTC mobile devices.
For developing, building and debugging Android code, we used Eclipse IDE for Java and Android ADT for
eclipse. At first, in order to simulate Android mobile phones, we used Android emulators which gave us the
option to develop and debug on PC. Most of the development effort and testing was made on the HTC
devices, since the emulators do not support bluetooth at this point. After the application was ready, we
used Eclipse Memory Analyzer in order to examine our memory usage.
2. System Overview
This application is for managing business cards collection. It consists of your
own personal designed cards and received cards from your colleagues. You can
design a business card, use pictures from the gallery as background, add your
preferred details to the card and customize its layout, font and color.
Main screen
Editing a card
The application offers several themes that can be applied to your new card. You can also create a theme
from any card, and later apply it to other cards.
In this application, you can manage your cards in two different ways – the gallery
browser or the tabs browser, that provide different ways of cards presentation. In
both ways, you can manage your folders, create new ones, rename and delete
existing ones, and do the same with your cards.
Browsing by tabs
Cards as icons
As for your cards, if a card has the relevant details, you can use it to call the phone number on the card, send
SMS or Email, and send the card to your colleagues using Bluetooth. The data can be encrypted and
authenticated, according to your choice.
Another interesting option is to automatically generate cards for your contacts list. Each contact in the
phone would have its own card with the contact details.
A card can be sent via Bluetooth by selecting a card and a remove device to send it to. The transmission
takes place in the background and the user is able to view the progress through Android’s notification bar.
When the card arrives at the receiver, the card is displayed and can be accepted or declined.
Select a device
Receiving in progress…
Save Card?
2.1.
Technologies
2.1.1. Bluetooth
Bluetooth is a proprietary open wireless technology standard for exchanging data over short distances.
The Bluetooth specifications are developed and licensed by the Bluetooth Special Interest Group (SIG),
which consists of more than 13,000 companies all over the world.
There are many advantages of using Bluetooth as a data transfer method. Among them is low power
consumption, which is one of the most problematic issues in the mobile phones world, high data throughput
and high communication distance (depends on Bluetooth hardware).
Android API Level 8 (version 2.2) supports Bluetooth 2.1 .
Its throughput is about 1.4Mbit/sec and its maximum distance can reach 100 meters (class 1).
To enable Bluetooth usage, Android uses two main protocols:

SDP – service discovery protocol:
Used to allow devices to discover what services each other support, and what parameters to use to
connect to them. For example, when connecting a mobile phone to a Bluetooth headset, SDP will be
used to determine which Bluetooth profiles are supported by the headset (headset profile, hands free
profile, advanced audio distribution profile, etc.) and the protocol multiplexor settings needed to
connect to each of them. Each service is identified by a Universally Unique Identifier (UUID), with official
services (Bluetooth profiles) assigned a short form UUID (16 bits rather than the full 128)

RFCOMM – Radio frequency communication:
The RFCOMM protocol is a simple set of transport protocols, made on top of the L2CAP protocol,
providing emulated RS-232 serial ports (up to sixty simultaneous connections to a Bluetooth device at a
time). The protocol is based on the ETSI standard TS 07.10. RFCOMM is sometimes called serial port
emulation. The Bluetooth serial port profile is based on this protocol. RFCOMM provides a simple
reliable data stream to the user, similar to TCP. It is used directly by many telephony related profiles as a
carrier for AT commands, as well as being a transport layer for OBEX over Bluetooth. Many Bluetooth
applications use RFCOMM because of its widespread support and publicly available API on most
operating systems. Additionally, applications that used a serial port to communicate can be quickly
ported to use RFCOMM.
With the Bluetooth API, a user can scan for other Bluetooth devices, connect or pair with them, query for
paired Bluetooth devices, establish RFCOMM channels/sockets, connect to a specified socket on a remote
device or transfer data to and from it.
2.1.2. Encryption
The Java security APIs spans a wide range of areas. Cryptographic and public key infrastructure (PKI)
interfaces provide the underlying basis for developing secure applications. Interfaces for performing
authentication and access control enable applications to guard against unauthorized access to protected
resources.
The APIs allow for multiple interoperable implementations of algorithms and other security services.
Services are implemented in providers, which are plugged into the Java platform via a standard interface
that makes it easy for applications to obtain security services without having to know anything about their
implementations. This allows developers to focus on how to integrate security into their applications, rather
than on how to actually implement complex security mechanisms.
The Java platform includes a number of providers that implement a core set of security services. It also
allows for additional custom providers to be installed. This enables developers to extend the platform with
new security mechanisms.
The Java cryptography architecture is a framework for accessing and developing cryptographic functionality
for the Java platform. It includes APIs for a large variety of cryptographic services, including:

Message digest algorithms

Digital signature algorithms

Symmetric bulk encryption

Symmetric stream encryption

Asymmetric encryption

Password-based encryption (PBE)

Elliptic Curve Cryptography (ECC)

Key agreement algorithms

Key generators

Message Authentication Codes (MACs)

(Pseudo-)random number generators
The Java platform includes built-in providers for many of the most commonly used cryptographic algorithms,
including the RSA and DSA signature algorithms, the DES, AES, and ARCFOUR encryption algorithms, the
MD5 and SHA-1 message digest algorithms, and the Diffie-Hellman key agreement algorithm. These default
providers implement cryptographic algorithms in Java code.
EKE – Encrypted Key Exchange
Encrypted Key Exchange (also known as EKE) is a family of password-authenticated key agreement methods
described by Steven M. Bellovin and Michael Merritt. Although several of the forms of EKE in this paper
were later found to be flawed, the surviving, refined, and enhanced forms of EKE effectively make this the
first method to amplify a shared password into a shared key, where the shared key may subsequently be
used to provide a zero-knowledge password proof or other functions. In the most general form of EKE, at
least one party encrypts an ephemeral (one-time) public key using a password, and sends it to a second
party, who decrypts it and uses it to negotiate a shared key with the first party.
A second paper describes Augmented-EKE, and introduced the concept of augmented passwordauthenticated key agreement for client/server scenarios. Augmented methods have the added goal of
ensuring that password verification data stolen from a server cannot be used by an attacker to masquerade
as the client, unless the attacker first determines the password (e.g. by performing a brute force attack on
the stolen data).
A version of EKE based on Diffie-Hellman, known as DH-EKE, has survived attack and has led to improved
variations, such as the PAKfamily of methods in IEEE P1363.2.
3. Use Cases
In the following section we will describe the use cases for the application according to the project goals and
usage scenarios. These will later be used in the application design.
3.1.
UC01 - Business Card Editor
These use cases describe usage scenarios for the business card editor activity.
3.1.1. UC0101 - Create card
This use case describes creation of a new business card. It is triggered by starting the card editor from the
main screen.
-
Main scenario
1. User starts card editor (from main)
2. A card is generated using the default theme
3. A popup screen opens and lets user edit item values
4. User edits default items and clicks “save”
5. The popup closes showing the editor surface
6. The user clicks on menu option “save as” and saves the card
7. A save dialog opens and the user selects where to save the card and its filename
8. Users clicks “ok” and the card is saved
-
Exceptions
4. User clicks “cancel” or presses the back button in the popup screen and the changes are ignored.
8. User clicks “cancel” in save dialog
3.1.2. UC0102 - Edit card
This use case describes editing of an existing card. It is triggered from main screen.
-
Main scenario
1. User starts cards browser
2. User selects the wanted folder
3. User browse for the card to edit
4. User clicks on menu option “Edit”
5. The editor opens with the selected card
3.1.3. UC0103 - Create item layout
This use case describes creation of new business card item when creating or editing a card. It is triggered by
the user at the editor surface screen.
-
Main Scenario
1. User clicks on menu option “Add Item”
2. Layout dialog opens with the item’s information
3. User edits item’s text content
4. User updates item’s type, style and color
5. User clicks on “ok” button to save the changes
6. Editor gets back the updated item, save the changes to the card and updates the surface
-
Exceptions
6. User clicks “cancel” or presses the back button in the dialog screen and the changes are ignored.
3.1.4. UC0104 - Edit item layout
This use case describes how to edit a business card item that is already on the card’s surface.
It is triggered by the user at the editor surface.
-
Main Scenario
1. User clicks on surface where the item’s bounding box should be
2. The top item with a bounding box that contains the clicked position will be selected and several
options will show on the side of the item (delete, edit, move)
3. User clicks on the “edit” option
4. Layout dialog opens with the item’s information
5. User edits item’s text content
6. User updates item’s type, style and color
7. User clicks on “ok” button to save the changes
8. Editor gets back the updated item, save the changes to the card and updates the surface
-
Exceptions
7. User clicks “cancel” or presses the back button in the dialog screen and the changes are ignored.
3.1.5. UC0105 - Position item on a card
This use case describes how to move a business card item on the surface of the card. It is triggered by the
user and starts at the editor surface.
-
Main Scenario
1. User clicks on an item
2. Editor surface shows edit, remove and drag buttons and a frame around the item
3. The user presses on the surface inside the frame or on the drag button and drags the item on the
surface to its new position
4. The editor surface saves the changes to the card
-
Exceptions
2. User clicks outside of the item’s frame to cancel the item’s selection.
3.1.6. UC0106 - Manage all items
This use case describes how to edit all of the business card items at once. It is triggered by the user and
starts at the editor surface.
-
Main Scenario
1. User clicks on menu option “Items”
2. Items dialog opens with a list the card’s items
3. User edits each item’s value and selects “Save”
4. The editor surface saves the changes to the card
-
Exceptions
3. User clicks back or “Cancel” and the changes are discarded
3.1.7. UC0107 - Create new theme from a card
This use case describes creating a new theme based on an existing card. It is triggered from editor surface.
-
Main Scenario
1. User clicks menu option “save as theme”
2. A “save as…” dialog pops up
3. User enters the name of the new theme and presses “ok”.
4. The theme is saved to storage
-
Exceptions
4. User clicks on “Cancel. The theme is not created
3.1.8. UC0108 - Apply a theme
This use case describes how to apply a theme on a business card. It is triggered by the user and starts at the
editor surface.
-
Main Scenario
1. User clicks on menu option “Set Theme”
2. A themes gallery popup with the first theme applied to the card.
3. User swipes left or right to iterate between themes, each swipe alters the layout of the card
according to the current theme.
4. User clicks on “Select theme” and the theme is set on the card
5. Editor gets the result back from the themes gallery and set the updates business card on the surface.
-
Exceptions
4. User clicks the back button and the changes are ignored.
3.1.9. UC0109 - Set background from android gallery
This use case describes setup of card background, which is chosen from phone gallery. It is triggered from
editor surface.
-
Main Scenario
1. User clicks on menu option “Set background”
2. The phone gallery opens
3. User clicks on the wanted picture
4. The editor surface returns, and the selected picture is set as background
3.2.
UC02 – Tabs Browse
These use cases describe usage scenarios for the business card tabs browser activity.
3.2.1. UC0201 - Browse for a card
This use case describes how to locate a business card inside the tabs browser. It is triggered by the user and
starts at the main activity.
-
Main Scenario
1. User clicks on “browse” button at main.
2. Browse activity opens up to show the default search tab
3. User selects the folder with the card by clicking the folder’s tab
4. The tabs view updates the list of cards to display the cards in the current folder
5. User scrolls to the requested card and clicks on the card to select it
3.2.2. UC0202 - Search for a card
This use case describes how to locate a business card inside the tabs browser. It is triggered by the user and
starts at the browser’s default tab.
-
Main Scenario
1. User clicks on “Search” tab
2. Browse activity moves to the Search tab and shows all available cards
3. User clicks on the search text box and the keyboard appears
4. User writes a set of characters or words to find
5. Browse activity hides cards that do not contain the search text
6. User scrolls to the requested card and clicks on the card to select it
3.2.3. UC0203 - Create folder
This use case describes creation of a new folder. It is triggered from tabs browser screen.
-
Main Scenario
1. User clicks the “New…” tab or chooses menu option “Create folder”
2. An input dialog pops up
3. User inserts the new folder name and clicks “Ok” button
4. The folder is created and appears as a tab
-
Exceptions
3. User clicks the back button or “Cancel” button and the folder is not created.
3. User enters an existing name. The current tab is changed to the existing tab, and no new folder is
created
3. User enters a forbidden name (“New…”, “Contacts”, “Search”). No folder is created and the last
used tab is active again
3.2.4. UC0204 - Rename folder
This use case describes renaming of an existing folder. It is triggered from tabs browser screen.
-
Main Scenario
1. User selects the folder he want to rename
2. User clicks on menu option “Rename folder” while no card is selected
3. An input dialog pops up
4. User inserts the new folder name and clicks “Ok” button
5. The folder is renamed and appears as a tab with the new name
-
Exceptions
4. User clicks the back button or “Cancel” button and the folder is not renamed.
3.2.5. UC0205 - Delete folder
This use case describes how to remove a business card using the tabs browser. It is triggered by the user and
starts at tabs browse activity
-
Main Scenario
1. User selects a specific folder by clicking its tab
2. User chooses menu option “Delete folder”
3. A confirmation dialog pops up
4. User clicks “Ok” button and the folder is deleted
-
Exceptions
4. User clicks the back button or “Cancel” button and the folder is not deleted.
3.2.6. UC0206 - Use a business card (SMS, Call, Email, etc.).
This use case describes usage of a business card, in order to call existing phone number, send Email or SMS,
and send via bluetooth. It is triggered from tabs browser screen
-
Main Scenario
1. User selects a specific folder by clicking its tab
2. User searches the wanted card in the list
3. User selects the card
4. User clicks on menu button and chooses the wanted action from the enabled actions
3.2.7. UC0207 - Move a card between folders
This use case describes how to move a business card from one folder to another using the tabs browser. It is
triggered by the user and starts at tabs browse activity
-
Main Scenario
5. User selects the specific card
6. User chooses menu option “Move”
7. A folder selection dialog pops up
8. User selects the folder to move the card to and clicks “Ok”
9. The card is moved to the selected tab and the Browser sets that tab as the current view
-
Exceptions
5. User clicks the back button or “Cancel” button and the user returns to the current tab.
3.3.
UC03 – Gallery Browser
These use cases describe usage scenarios for the business card gallery browser activity.
3.3.1. UC0301 - Browse for a card
This use case describes browsing a card within the gallery browser. It is triggered from main screen.
-
Main Scenario
1. User clicks on “browse” button at main
2. Browse activity opens up to show the first folder in the gallery
3. User finds and clicks the folder with the card by swiping the folders
4. A list of cards in the selected folder is shown
5. User swipes on the cards in order to browse the wanted card
-
Branch
3b. User flips up the view
3b.1 Explorer view is opened with all of the folders as little icons
3b.2 User clicks on the wanted folder
3b.3 Continue to step 4
5b. User flips up the view
5b.1 Explorer view is opened with all of the cards as little icons
5b.2 User clicks on the wanted card
5b.3 The card is shown on full screen
3.3.2. UC0302 - Search for a card
This use case describes how to locate a business card inside the gallery browser. It is triggered by the user
and starts at the browser’s first screen.
-
Main Scenario
1. Browse activity opens up to show the first folder in the gallery
2. The user swipes down the screen and the search line appears
3. The user clicks on the search line and the keyboard appears
4. The user writes down the string sequence he wants to search for
5. All the cards with an item that contains such string will appear as list
-
Branch
2b. If the user wants to search inside specific folder
2b.1 User swipes to a specific folder and clicks it
2b.2 The user swipes down the screen and the search line appears
2b.3 Continue to step 3
2b.1b. User flips up the view
1b.1 Explorer view is opened with all of the folders as little icons
1b.2 User clicks on the wanted folder he wants to search in
1b.3 Continue to step 2b.2
3.3.3. UC0303 - Create folder
This use case describes creation of a new folder. It is triggered from gallery browser screen.
-
Main Scenario
1. User clicks on menu option “Create folder" within the folders view
2. An input dialog pops up
3. User inserts the new folder name and clicks “Ok” button
4. The folder is created
-
Exceptions
3. User clicks the back button or “Cancel” button and the folder is not created
3. User enters an existing name. No new folder is created
3. User enters a forbidden name (“New…”, “Contacts”, “Search”). No folder is created
3.3.4. UC0304 - Rename folder
This use case describes renaming of an existing folder. It is triggered from gallery browser screen.
-
Main Scenario
1. User swipes the folders and selects the folder he want to rename
2. User clicks on menu option “Rename folder”
3. An input dialog pops up
4. User inserts the new folder name and clicks “Ok” button
5. The folder is renamed
-
Exceptions
4. User clicks the back button or “Cancel” button and the folder is not renamed.
3.3.5. UC0305 - Delete folder
This use case describes how to remove a business card. It is triggered by the user and starts at gallery
browser.
-
Main Scenario
1. User selects a specific folder by swiping the folders
2. User chooses menu option “Delete folder”
3. A confirmation dialog pops up
4. User clicks “Ok” button and the folder is deleted
-
Exceptions
4. User clicks the back button or “Cancel” button and the folder is not deleted.
3.3.6. UC0306 - Use a business card (SMS, Call, Email, etc.)
This use case describes usage of a business card, in order to call existing phone number, send Email or SMS,
and send via Bluetooth. It is triggered from gallery browser screen.
-
Main Scenario
1. User selects a specific folder by swiping the folders and clicks the folder
2. User searches the wanted card in the list by swiping the cards
3. User clicks on menu button and chooses the wanted action from the enabled actions
-
Branch
1b. User flips up the view
1b.1 Explorer view is opened with all of the folders as little icons
1b.2 User clicks on the wanted folder he wants to enter
1b.3 Continue to step 2
3.3.7. UC0307 - Move a card between folders
This use case describes how to move a business card from one folder to another using the gallery browser. It
is triggered by the user and starts at the gallery browser.
-
Main Scenario
1. User selects a specific folder by swiping the folders and clicks the folder
2. User searches the wanted card in the list by swiping the cards
3. User chooses menu option “Move”
4. A folder selection dialog pops up
5. User selects the folder to move the card to and clicks “Ok”
6. The card is moved to the selected folder
-
Branch
1b. User flips up the view
1b.1 Explorer view is opened with all of the folders as little icons
1b.2 User clicks on the wanted folder he wants to enter
1b.3 Continue to step 2
2b. User flips up the view
2b.1 Explorer view is opened with all of the cards in the folder as little icons
2b.2 User clicks on the wanted card
2b.3 Continue to step 3
-
Exceptions
5. User clicks the back button or “Cancel” button and the user returns to the current tab.
3.4.
UC04 – Bluetooth
These use cases describe usage scenarios for sending and receiving business cards via Bluetooth.
3.4.1. UC0401 - Send business card via Bluetooth
Starts at browser with a selected card
-
Main Scenario
1. User clicks on menu option "Send”
2. Device picker opens up with a list of paired devices
3. User clicks on a device
4. Connection is made with the device
5. The card is sent to the remote device
6. Application waits for a status response
7. Application displays the status to the user
-
Branch
3. If the device is not in the known device list
3b.1 User clicks on “Scan for new devices”
3b.2 Application request device detection
3b.3 Each detected device is added to the list
3b.4 User clicks on a device
3b.5 Continue to step 4
5b. If encryption is enabled
5b.1 Application asks user for a password
5b.2 User inserts an agreed upon password and clicks “ok”
5b.3 Application starts the EKE protocol to agree on a secret key
5b.4 Application sends an encrypted card using the key
5b.5 Continue to step 6
-
Exceptions
1. If bluetooth is not enabled ask user to enable bluetooth
1.1 If user clicks “cancel” the operation is canceled and the application return to the browser view
4. Connection to remote device fails
4.1 Display error message
5b.3 Authentication fails
5b.3.1 Display error message and abort operation
6. Read timeout exception
6.1 Display unknown response message
3.4.2. UC0402 - Receive a business card
Service listens for an incoming connection
-
Main Scenario
1. A remote device a connection is accepted
2. Service forks the socket to a receive handler
3. Receiver reads the data from the remote device
4. Receiver notifies the user about an incoming card
5. Receiver saves the card to the default “received” folder
6. Receiver sends the status (Accepted, Refused, Failed) to the remote device
-
Branch
4b. If the message is encrypted
3b.4 Receiver opens a password dialog
3b.5 User inserts a password and clicks on “ok”
3b.6 Receiver start the EKE protocol
3b.7 Receiver reads encrypted data from the remote device
3b. If the preference for “confirmation dialog” is checked
2b.4 Receiver open a save card dialog, showing the card
2b.5 User selects the location to save and clicks “ok”
2b.6 Receiver saves the card to that location
2b.7 Continue with step 6
-
Exceptions
1. If bluetooth is not enabled then nothing will happen
3. Read timeout exception
3.1 Display error message
3b.3 Authentication fails
3b.3.1 Display error message and abort operation
4. Design & Implementation
This project was designed in 3 layers - Android SDK Layer, Framework Layer and Business Card Application
Layer. Each layer is built on top of the previous layer, adding more functionality to the next one.
The Framework layer contains most of the code and is completely disconnected from the business card
aspect of the project. In the following sections we will describe the large components that make up this
layer.
Drawing 4.1 – Framework layer components in general
The Business Cards Application layer contains several UI components that are specific to editing and
managing business cards. It contains the logic concerning business cards structural data and utilities for
painting, importing Android contacts and business card theme management.
Drawing 4.2 – Business Cards Application layer components in general
4.1.
Background Service
“A Service is an application component representing either an application's desire to perform a longerrunning operation while not interacting with the user or to supply functionality for other applications to
use.” - Android docs
Our Background service runs as part of the application’s process (default behavior) in a separate thread. It
starts when the phone is started or when the application is opened. It handles incoming and outgoing
bluetooth messages using our bluetooth implementation.
The service allows for an application to register a message type to be handled either by a handler class or an
answer activity. The Business cards application registers a message of type “business card” in the service to
be handled either by an business card answer activity or by a batch handler (according to the preferences
set by the user). The service can also accept requests from activities in the application to send a message via
bluetooth to a specified device address. The bluetooth messaging sequences will be explained in the
bluetooth section later on.
The background service also uses the notification component to alert the user about changes in the
application such as “service started”, “bluetooth not available”, “incoming message”, etc.
In the following class diagram, you can see the “LocalService” which is the name of the class representing
the background service. In is started by a boot completed receiver which is an Android broadcast receiver.
An Android broadcast receiver is a class that listens to intents moving around the system. Each receiver
filters the intents it wants to accept by specifying an action to filter by. That way the receiver wakes up only
when an intent with that specific action is sent by another activity. The boot completed receiver listens to a
boot action only and wakes up accordingly.
As described above, the Registration block manages registration for message types and returns an
IRunnableBlock to handle the incoming message type data.
Here is a sample of code that registers a message type for an IRunnableBlock.
if (ask_confimation == true)
{
LocalService.RegisterMessageTypeFor(Constants.BUSINESS_CARD_TYPE,
RegisterationBlock.getAnswerActivityBlock(BusinessCardAnswerActivity.class));
}
else
{
LocalService.RegisterMessageTypeFor(Constants.BUSINESS_CARD_TYPE,
RegisterationBlock.getRunnableBlock(BusinessCardRunnableBlock.class));
}
Drawing 4.1.1 – registering a runnable block for a message type code snippet
The Bluetooth package represents the logic that manages bluetooth communication. The service uses this
package to spawn new senders when a request to send a message arrives and to keep a listener alive in
order to
accept incoming bluetooth connections.
class localserv ice
Notification Serv ice
Bluetooth Package
«use»
getRegistrationBlock()
new Sender()
new Listener()
Service
LocalServ ice
BroadcastReceiver
BootCompletedReceiv er
+
+
+
+
+
+
+
+
+
+
Start()
onReceive(Context, Intent) : void
getService() : LocalService
start(Context) : void
stop(Context) : void
RegisterMessageTypeFor(String, RegisterationBlock) : void
getRegistredBlockFor(String) : RegisterationBlock
onBind(Intent) : IBinder
onStartCommand(Intent, int, int) : int
onCreate() : void
onDestroy() : void
RegisterationBlock
«interface»
RegisterationBlock::IRunnableBlock
+
+
+
AnswerActivityClass: Class<?>
BlockType: EnumBlockType
+
+
getAnswerActivityBlock(Class<?>) : RegisterationBlock
getRunnableBlock(Class<?>) : RegisterationBlock
handleMessage(MessageBlock) : void
Drawing 4.1.2 – background service class diagram
+BlockType
«enumeration»
RegisterationBlock::
EnumBlockType
«enum»
AnswerActivity
Runnable
4.2.
Notifications
Android provides a way to interact with the user without blocking the current work, using it’s notification
mechanism. Each notification is an alert the shows up on the top panel of the screen. An application can
post, remove and update notifications as needed.
We added an abstraction over the basic android code that gives us the ability to keep the state of each
notification in its own class and change its layout and text as needed.
In the following class diagram you can see the notification service which is the notifications provider.
The service is a singleton and supplies activities with new notificators by returning one of the implemented
notificator objects (Notificator, ProgressBarNotificator). The common one is the notificator that supports
updating and canceling the notification, setting a title and a description. A notificator can also accept a
callback object which will be activated when the user click on the notification. This allows for interacting
with the user while waiting for a response (usually with a timeout).
class localserv ice
NotificationServ ice
-m_service
«interface»
INotificationService
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
getNotificator(String, String) : INotificator
getNotificator() : INotificator
getProgressBarNotificator(String) : ProgressBarNotificator
notify(int, Notification) : void
notify(int, String, String) : void
notify(int, String, String, Class<?>, Bundle, INotificationCallback) : void
getLocalNotificator() : INotificator
cancel(int) : void
-m_service
getInstance() : INotificationService
start(Context, String) : void
stop() : void
getLocalNotificator() : INotificator
getNotificator(String, String) : INotificator
getProgressBarNotificator(String) : ProgressBarNotificator
getNotificator() : INotificator
notify(int, String, String) : void
notify(int, String, String, Class<?>, Bundle, INotificationCallback) : void
notify(int, Notification) : void
cancel(int) : void
-m_service
-m_notificator
Notificator
ProgressBarNotificator
+
+
+
ProgressBarNotificator(Context, INotificationService, int, String)
notify(int) : void
cancel() : void
+
+
+
+
+
+
+
+
+
Notificator(INotificationService, int)
Notificator(INotificationService, int, String, String)
setTitle(String) : void
setDescription(String) : void
notify(String, String) : void
notify(String) : void
notify(String, String, Class<?>, Bundle, INotificationCallback) : void
notify(String, Class<?>, Bundle, INotificationCallback) : void
cancel() : void
«interface»
INotificator
+
+
+
+
+
+
+
notify(String, String, Class<?>, Bundle, INotificationCallback) : void
notify(String, Class<?>, Bundle, INotificationCallback) : void
notify(String, String) : void
notify(String) : void
cancel() : void
setTitle(String) : void
setDescription(String) : void
«use»
«interface»
INotificationCallback
+
Drawing 4.2.1 – notification service class diagram
onActivityResult(Intent) : void
The following code snippet shows how to create a notificator and add a notification to the alerts panel on
the screen.
INotificator notificator = NotificationService.getInstance().getNotificator();
// send a notification
notificator.notify("What's up...");
// send an update
notificator.notify("goodbye!");
// remove the notification
notificator.cancel();
Drawing 4.2.2 – notifications code snippet
4.3.
Storage Service
Android provides several options for persistency. It has internal storage visible only to the application and
external storage which is basically the SD-Card and SQLite databases.
In our design we added an abstraction over the storage type and automatically selected the external as
default or the internal storage if an SD-Card is missing. We used a strategy pattern for selecting a storage
adapter. There are several adapter types and a decorator cache adapter that can be used over the internal
and external adapters. The usage model is to first configure several adapters and access each using a key.
For example, using the key “images” will access an adapter which is directed to “images” directory. Same
applies with “cards”, “themes” or every other directory. This gives us the ability to use different directories
without the need to change the application accordingly.
In the following class diagram you can see the singleton storage service that allows adding new adapters.
The service uses the StorageFactory which is a simple factory pattern that we use to abstract access to the
actual class created. The null storage adapter is used when both the external and internal adapters fail to
instantiate. The storage service also provides two storage tools, the temporary storage that allows caching
data and the image storage that eases loading of resources.
class storage
StorageServ ice
«enumeration»
StorageAdapterFactory::
StorageType
+
+
+
+
+
+
+
«enum»
Internal
SdCard
ImageStorage
start(Context, String) : void
getAdapter(String) : IStorageAdapter
setAdapter(String, String, boolean) : IStorageAdapter
setAdapter(String, IStorageAdapter) : void
combinePath(String, String) : String
getImageStorage() : ImageStorage
getTemporaryStorage() : TemporaryStorage
+
+
+
+
+
+
ImageStorage(Context)
getBitmap(int) : Bitmap
getDrawable(int) : BitmapDrawable
unpackBitmap(byte[]) : Bitmap
packBitmap(Bitmap) : byte[]
asDrawable(Bitmap) : BitmapDrawable
TemporaryStorage
+
+
+
+
«use»
TemporaryStorage(Context)
read(String) : Object
remove(String) : void
cache(Serializable) : String
InternalStorageAdapter
StorageAdapterFactory
+
+
getAdapter(Context, String, StorageType, boolean) : IStorageAdapter
«interface»
IStorageAdapter
+
+
+
+
+
+
+
+
+
+
+
+
+
getPath() : String
read(String, String) : Object
write(Serializable, String, String) : void
delete(String, String) : void
getItems(String, Filter) : String[]
getFile(String, String) : File
readBitmap(String, String) : Bitmap
writeBitmap(Bitmap, String, String) : void
createFolder(String, String) : void
deleteFolder(String, String) : void
moveFolder(String, String, String, String) : void
move(String, String, String, String) : void
~m_adapter
setDefaultFolders(String[]) : void
InternalStorageAdapter(Context, String)
StorageAdapter
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
StorageAdapter(String)
getPath() : String
read(String, String) : Object
write(Serializable, String, String) : void
delete(String, String) : void
move(String, String, String, String) : void
getItems(String, Filter) : String[]
getFile(String, String) : File
readBitmap(String, String) : Bitmap
writeBitmap(Bitmap, String, String) : void
createFolder(String, String) : void
deleteFolder(String, String) : void
moveFolder(String, String, String, String) : void
combinePath(String, String) : String
makeSureExists(String) : void
setDefaultFolders(String[]) : void
SdCardStorageAdapter
+
+
+
SdCardStorageAdapter(String)
isWriteable() : boolean
isReadable() : boolean
NullStorageAdapter
«use»
StorageCache
+All
«enumeration»
IStorageAdapter::Filter::EnumFilter
«enum»
Directories
Files
All
IStorageAdapter::Filter
+
+
+
+Directories
+Files
Directories: Filter = new Filter(Enum... {readOnly}
Files: Filter = new Filter(Enum... {readOnly}
All: Filter = new Filter(Enum... {readOnly}
+
+
+
setIncludeVirtual() : Filter
equals(Object) : boolean
includeVirtual() : boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
StorageCache(IStorageAdapter)
getPath() : String
read(String, String) : Object
write(Serializable, String, String) : void
delete(String, String) : void
move(String, String, String, String) : void
getItems(String, Filter) : String[]
readBitmap(String, String) : Bitmap
writeBitmap(Bitmap, String, String) : void
getFile(String, String) : File
createFolder(String, String) : void
deleteFolder(String, String) : void
moveFolder(String, String, String, String) : void
setDefaultFolders(String[]) : void
Drawing 4.3.1 – storage service class diagram
+
+
+
+
+
+
+
+
NullStorageAdapter(String)
read(String, String) : Object
write(Serializable, String, String) : void
delete(String, String) : void
getItems(String, Filter) : String[]
getFile(String, String) : File
readBitmap(String, String) : Bitmap
writeBitmap(Bitmap, String, String) : void
4.4.
Bluetooth & Encryption
In Android 2.2 Bluetooth is supported, therefore there is a built-in API for creating Bluetooth connections
and using them for data transmission. That includes an automatic pairing action while trying to connect to
an unpaired remote device. As a result, the developer has to perform few actions in order to use Bluetooth:
connect or accept, depends if he is the server side or the client side, and after connection is established use
the read and write methods. This is an example of how is it done:
// *********** on the receiving side *********** //
// create a new listening server socket
BluetoothServerSocket server = adapter.listenUsingRfcommWithServiceRecord("btdevicename", "myid");
// wait for incoming connection
BluetoothSocket socket = socket.accept();
// *********** on the sending side *********** //
// create socket
BluetoothSocket socket = bluetoothAdapter.getRemoteDevice(deviceAddress)
.createRfcommSocketToServiceRecord(UUIDString);
// try to connect
socket.connect();
// *********** on both sides *********** //
// get input & output stream
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
// read bytes into buffer - blocking
in.read(buffer);
// do something with the data...
// send bytes to client
out.write(buffer);
// close the client
socket.close();
Drawing 4.4.1 – Bluetooth code snippet
In our design, we use one listening thread, which listens to incoming connections for our application, and an
additional thread for each card transfer – sending thread or receiving thread, depends on what side you are.
In general a UI thread should not be used to perform IO operations since these are blocking calls. Moreover,
in order to support multiple transmissions in and out, we use a different thread for each transmission.
These threads are created in the background service either by an incoming connection or by an activity’s
send request. The listening thread is started when the background service is started and waits for
connections. When the user chooses to send a business card, a request (using Android broadcast
capabilities) is sent to the background service with a reference to the card we want to send. The background
service creates and starts a sending thread, which is responsible for connecting to the remote device. After
the connection is established, the send thread sends the data block by block. On the receiving side, the
listening thread accepts the connection and starts a receiving thread with the accepted socket, which
handles the incoming blocks. After the listening thread creates the receiving thread, it continues to listen for
other connections. This gives us the ability to send multiple cards without waiting for each transfer to be
done.
In order to avoid deadlocks, while a thread waits for incoming blocks and no data is arrived, we built a
watchdog component. The watchdog is a thread which receives a timeout parameter and a callback. When
the timeout is over it triggers the callback. The watchdog can be stopped, reset, and started again to allow
reuse of the same instance. Each of the bluetooth threads start the watchdog when they perform blocking
operations such as read, write and connect. Our implementation for the callback is to close the socket and
cause an exception on the bluetooth thread which stops the blocking operation and handles the exception.
Another ability provided by Java is data encryption. Our encryption (detailed later) based on DH secret key
generator which is used to encrypt and decrypt the data on both sides. To create such a secret key we
implemented EKE protocol, based on a common password which is known to both sides. If encryption is
enabled on the sender’s side, encryption process is started and an “encryption header” message is sent to
the remote device. When the remote device receives this message, an encryption setup process is also
started on the receiving end (detailed later). After the encryption has ended successfully and both sides
have the same secret key, the card is encrypted under it and transmitted.
In the following class diagram, we can see that most of the logic is implemented in the abstract class
AbstractBluetoothThread. Both the BluetoothSendThread and BluetoothClientThread inherit from it and
reuses the common send/receive logic. The third thread is the BluetoothListenerThread which creates the
BluetoothClientThread in case of incoming connection.
One of the differences in the logic between the threads is the creation of Bluetooth sockets. The sending
thread initiates the connection and gets a socket when a connection is established, while the receiving
thread gets the socket from the listening thread which accepted the connection. Another difference is the
way the secret key is generated, since the protocol is different for the client side and server side. Both key
generators (AliceDHSecretKeyGenerator as sender, BobDHSecretKeyGenerator as receiver) inherit from
AbstractDHSecretKeyGenerator, which implements the common key generation logic. After the secret key is
generated, we use the CipherGenerator component which receives a secret key or a password to encrypt or
decrypt the data. The password is used for initiating the EKE protocol.
In the sending process, the data itself is wrapped with a MessageBlock object, which contains the
serializable data and the message type. This message block is used by the sending/receiving threads and by
the cipher generator in order to encrypt or decrypt existing message block. Another form of message block
is the CacheMessageBlock, which contains a temporary cached message. This is used in order to pass
business cards from the application to the sending thread, since we can’t pass it through the broadcast
Intent because of the card’s size and the intent’s size limit.
class crypto
Serializable
CacheMessageBlock
+
+
+
«enumeration»
AbstractBluetoothThread::
Status
CacheMessageBlock(MessageBlock)
getCachedMessage() : MessageBlock
remove() : void
«enum»
Accepted
Refused
Failed
Unknown
Serializable
MessageBlock
+
+
+
+
+
+
+
Thread
IWatchDogListener
AbstractBluetoothThread
MessageBlock(String, Serializable)
getType() : String
getData() : Serializable
cache() : CacheMessageBlock
isCached() : boolean
uncache() : MessageBlock
destroy() : void
Thread
BluetoothListenerThread
+
+
+
+
+
+
+
AbstractBluetoothThread(String)
onTimeout() : void
intToByteArray(int) : byte[]
byteArrayToInt(byte[]) : int
setProgress(int) : void
getProgress() : int
run() : void
+
+
+
BluetoothListenerThread()
run() : void
cancel() : void
BluetoothSendThread
BluetoothClientThread
«use»
+
+
+
BluetoothSendThread(String, MessageBlock)
connected() : void
ensurePaired(BluetoothDevice, String) : void
+
BluetoothClientThread(BluetoothSocket)
#m_cipher
BobDHSecretKeyGenerator
AliceDHSecretKeyGenerator
+
+
AliceDHSecretKeyGenerator()
getSecretKey(byte[]) : SecretKey
+
+
BobDHSecretKeyGenerator(byte[])
getSecretKey() : SecretKey
CipherGenerator
+
+
+
+
+
+
CipherGenerator(String)
CipherGenerator(SecretKey)
encrypt(MessageBlock) : MessageBlock
isEncrypted(MessageBlock) : boolean
decrypt(MessageBlock) : MessageBlock
generateRandomChallenge() : String
AbstractDHSecretKeyGenerator
+
+
AbstractDHSecretKeyGenerator(KeyPair)
getPublicKey() : byte[]
Drawing 4.4.2 – Bluetooth & Encryption class diagram
4.4.1. Send - Receive Sequence
This paragraph describes the sending – receiving sequence in details, in chronological order.
Receiver:
The background service creates a listening thread, which waits for incoming connections.
Sender:
The user selects a card to send and a device to send it to. The background service receives a
send request and creates a sending thread, which connects to the remote device.
Receiver:
The listening thread accepts the connection and creates a receiving thread, which waits for an
incoming message (blocking operation).
Sender:
The sending thread sends the message type.
Sender & Receiver:
If message type is “Encrypted” then EKE protocol is started.
Receiver:
Waits for an incoming message.
Sender:
Sends the message to the remote device and waits for a status message.
Receiver:
Receives a message. After a message is received, an answer activity is started according to the
message type. Finally, a status message is sent according to user’s answer.
sd BusinessCard
Device Picker
Background
Service
Background
Service
Send card
Listening Thread
New
Sending Thread
New
Connect
Accept
Receiving Thread
New
Send(message type)
opt Encryption
Send(card)
GetRunnableBlock(messageType)
Answer Activity
New
Show() :Boolean
Send(status)
Drawing 4.4.3 – Bluetooth & Encryption class diagram
4.4.2. Encryption Sequence
Here is the description of EKE sequence, including the secret key generation based on Diffie-Helman
protocol and user authentication. As mentioned before, a common password is used for setting up this
encryption method.
This is the sequence, as implemented, in chronological order:
Step 1 – Client A:
User inserts the password, which is scrambled with a hash function. This step is
necessary because otherwise an attacker could try to guess the password using a
dictionary attack. Sending the hashed password on the communication line
instead of the original one is essential for preventing Man-In-The-Middle attack.
A DH public key (ga mod p) is encrypted using the hashed password, and sent to
client B.
Step 2 – Client B:
Now client B scrambles the password with the same hash function. With the
hashed password he decrypts client A’s public key, and with his own private key,
he creates a common DH key – k = gab mod p.
Note: g and p are known constant numbers. Since g is very large, we can’t use k
and one of the public keys for computing the private ones.
In order to enable client A to create the same secret key, we send back client B’s
DH public key (gb mod p) encrypted under the hashed password. In addition, we
send a random challenge (called challengeB), encrypted under the secret key – k.
In each encryption setup a new random challenge is generated, therefore using
an old one won’t complete the encryption setup process. This step is necessary
because it defends against replay attack and also allows us to authenticate the
other side.
Step 3 – Client A:
Now client A can compute the secret key k, with his own private key and client B’s
public key. In order to authenticate that client A is actually client A, we decrypt
the received challengeB using the secret key, generate a new challenge (called
challengeA), merge them together and encrypt the merged challenge under k.
The new challenge is sent back to client B. Since only client A knows the secret
key, only he can decrypt the received challengeB and create a new encrypted
challenge that contains challengeA and challengeB.
Step 4 – Client B:
Client B decrypts the received challenge, which consists of challengeA and
challengeB. Since he knows challengeB, he can produce challengeA alone and
send it back encrypted under the secret key. The fact that only client B knows the
secret key k and the original challengeB, he can send back challengeA and prove
to client A that he is client B.
The secret key we generated here is used for data encryption while sending any data (e.g. cards,
statuses and more). This defends the session from session hijacking because even if an attacker would
take over the session,
and impersonate one of the sides, he can’t understand the messages.
sd Use Case Model
Client A
Client B
Device Name, Ew(g^a mod p)
w=f(password)
Ew(g^b mod p), Ek(challengeB)
k=g^ab(mod p)
Ek(challengeA,challengeB)
Ek(challengeA)
Drawing 4.4.4 –Encryption sequence diagram
w=f(password)
k=g^ab(mod p)
4.5.
Business Cards Data Structures
This paragraph describes the way business card is represented in our system. Our main considerations while
creating this structure were user convenience, memory usage, changeable properties and more…
The main idea is that each business card contains many different items, and the user can decide which items
he wants in the card. Each item can be edited, and the user can decide about the text, font, color and layout.
With the fact that each item is a standalone component, we could implement an editor screen which allows
us to handle each item alone, with no relation to other items on the card.
One other changeable property of the card is its background. The user can choose a background for his card
from the gallery of the device. That means you can take a picture and use it as background.
Note that because of its size there was a problem in saving the background as picture in the business card
structure, therefore we only saved a reference to the background file.
Another capability that we created, based on business card structure, is the themes manager. The themes
manager allows the user to apply a theme, which includes items with prepared layout and position, on his
card. That means that the texts will remain, but the layout of the card is changed. Also, a user can create a
theme from his designed or received cards, and later apply it on other cards. The theme structure is very
similar to a business card structure.
In order to improve user experience, we added a utility that imports all the phone's contacts and for each
contact creates a card based on its details. Note that the contact’s card isn't actually saved on the device,
and will be saved only if edited and saved as a card in another directory.
In the following class diagram you can see that BusinessCard contains many BusinessCardItem objects. Each
item has its type (ItemType), and its layout (BusinessCardItemLayout). You can also see that the layout
contains font, size and other parameters.
The themes manager (ThemesManager) contains a collection of BusinessCardTheme objects, while each
theme contains many items, similar to a BusinessCard structure. When applying a theme, the theme's items
would be copied to the business card items. This also includes the background.
In order to draw a business card or a theme on the screen, we use the BusinessCardPainter component
which allows us to take a business card and create a picture from it, including the background and all of its
items. This picture is used in the application’s activities to display the card or the theme.
The last component is the ContactUtils, which implements the contact import ability, as described before.
class themes
Serializable
ContactsUtils
+
+
BusinessCardBlock
initialize(Context) : void
getContacts() : Map<String, BusinessCard>
+
+
BusinessCardBlock(BusinessCard)
getBusinessCard() : BusinessCard
Serializable
BusinessCardItemLayout
+Default
Serializable
BusinessCard
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
BusinessCard(boolean)
BusinessCard(BusinessCard)
getFileName() : String
setFileName(String) : void
getItems() : List<BusinessCardItem>
getBackgroundFilename() : String
getBackground() : BitmapDrawable
setBackground(String) : void
setBackground(String, Bitmap) : void
getFirstName() : String
setItem(ItemType, String) : void
getLastName() : String
getFullName() : String
getPhoneNumber() : String
getEmail() : String
addItem(BusinessCardItem) : void
getItem(UUID) : BusinessCardItem
removeItem(UUID) : void
setItem(BusinessCardItem) : void
match(String) : boolean
removeItems() : void
+
+
+
BusinessCardItemLayout()
BusinessCardItemLayout(FontItem, FontSize, int, boolean, boolean, boolean)
BusinessCardItemLayout(BusinessCardItemLayout)
«enumeration»
ItemType
+m_layout
Serializable
BusinessCardItem
1..*
+
+
+
+
+
+
BusinessCardItem(ItemType, String)
BusinessCardItem(ItemType, String, int, int)
BusinessCardItem(ItemType, String, int, int, BusinessCardItemLayout, boolean)
GetInputType() : int
equals(Object) : boolean
equals(BusinessCardItem) : boolean
apply theme
1..*
Serializable
BusinessCardTheme
+
+
+
+
«use»
getName() : String
create(Map<ItemType, String>) : BusinessCard
apply(BusinessCard) : BusinessCard
fromBusinessCard(String, BusinessCard) : BusinessCardTheme
BusinessCardPainter
+
+
+
+
+
getBusinessCardAsBitmap(BusinessCard) : Bitmap
getBusinessCardAsBitmap(BusinessCard, int) : Bitmap
paintBusinessCardItems(Canvas, BusinessCard, int) : void
getScale(BusinessCard, int) : float
getPaint(Paint, BusinessCardItemLayout, int) : void
-m_defaultTheme
ThemesManager
{leaf}
-m_instance
+
+
+
+
+
+
+
+
initialize(Context) : void
getInstance() : ThemesManager
getThemes() : List<String>
getTheme(String) : BusinessCardTheme
getDefaultTheme() : BusinessCardTheme
save(BusinessCardTheme) : void
isDefault(String) : boolean
remove(String) : void
Drawing 4.5.1 – Business card structure class diagram
+m_type
«enum»
FirstName
LastName
Name
Phone
Address
Email
Company
Fax
Text
Institute
WorkPhone
Description
Profession
Department
Link
4.6.
Business Card Editor
The business card editor is made up of an activity that uses a surface view as its drawing surface. The system
sends a drawing event which is handled in the onDraw method. The surface view gets redrawn several times
a second. Each time we draw the background, and the business card items. Additionally, the editor uses
three activities.
The first one is the item layout activity, which allows editing the text, setting a type for the item, changing its
color, font, size and style.
The second is the items list activity which gives a global view of all items in the card and allows editing or
removing each item in the same screen. It’s the first thing that opens when a new card is created. The card is
created using the default theme and the items are filled with its default values. When this activity opens, the
user can edit the text values or remove some of the items. Once “save” is clicked, the surface gets repainted
with the updated items.
The third activity is the themes selector activity, which allows choosing a theme to apply to the card. When
opened it shows the card with the first theme applied on it. By swiping to the left the next theme will be
applied to the card and shown on the screen. Once a theme is selected, the surface gets repainted with the
selected theme causing items to change position and layout, but not changing the textual values of the
items.
Using the touch screen the user can manage the position and layout of the business card’s items. When the
user clicks on an item in the surface, the topmost item is selected and the surface view is updated to show a
bounding box and three clickable icons surrounding the item (edit, delete and move). When selecting the
edit icon the item layout activity is opened with the item’s properties. When selecting the delete icon, the
item is removed from the card and the surface view. In order to position an item on the card surface, the
user can drag the item or the move icon.
The editor also uses a menu option which allows selecting a background from the device’s gallery, saving a
theme based on the card’s layout, and displaying a grid. The grid can be used to align items on the surface. It
also supports snapping to grid lines for accurate alignment.
In the following class diagram, the main editor activity is located at the center and the three additional
activities are above it and are used by it. Below is the surface view that is interconnected to the activity.
There is also a save dialog used to save the card when done. The ItemList and the ItemLayout activities are
mainly written with an xml layout and have little dependencies in anything other than the business card
structures. The themes activity is based mainly on our framework gallery view code, which creates a very
simple tree of views. Like all activities it has a main view which is the header. The header view contains a
gallery view of themes. The activity also uses a swipe gesture listener we added to the framework in order
to detect swipes. Once a left or right swipe event is detected, we send the gallery view request to show the
next or previous theme respectively.
class editor
SimpleOnGestureListener
Sw ipeGestureDetectorListener
+
+
+
T
SwipeGestureDetectorListener(ISwipeListener)
onFling(MotionEvent, MotionEvent, float, float) : boolean
onDoubleTap(MotionEvent) : boolean
LinearLayout
HeaderView
ItemsView
ViewFactory
GalleryView
+
+
#
HeaderView(Context)
initialize() : void
setText(String) : void
getView() : View
~m_listener
«interface»
ISwipeListener
-m_themeHeader
+
+
onSwipe(int) : boolean
onDoubleTap() : boolean
Activity
BusinessCardThemeSelector
#
+
+
+
+
+
+
Activity
BusinessCardEditorItemToolbox
+
-
onCreate(Bundle) : void
updateControls() : void
setSpinner(Spinner, Object) : void
onCreate(Bundle) : void
setTheme() : void
deleteTheme() : void
onTouchEvent(MotionEvent) : boolean
onDoubleTap() : boolean
onSwipe(int) : boolean
onCreateOptionsMenu(Menu) : boolean
onMenuOpened(int, Menu) : boolean
onMenuItemSelected(int, MenuItem) : boolean
Activity
BusinessCardEditorItemsList
+
#
#
onCreate(Bundle) : void
setItemsView(LinearLayout, List<BusinessCardItem>) : void
saveItems() : void
addItemsToBusinessCard() : void
onSaveInstanceState(Bundle) : void
onRestoreInstanceState(Bundle) : void
Android:Activity
Activity
BusinessCardEditor
«use»
Dialog
UberColorPickerDialog
+
#
UberColorPickerDialog(Context, OnColorChangedListener, int)
onCreate(Bundle) : void
+
+
+
+
+
+
#
+
+
onCreate(Bundle) : void
onCreateOptionsMenu(Menu) : boolean
onMenuItemSelected(int, android.view.MenuItem) : boolean
saveTheme() : void
selectTheme() : void
getWidth() : int
getHeight() : int
selectBackground() : void
showEditItems() : void
saveBusinessCard() : void
makeToast(String) : void
showItemToolbox(BusinessCardItem) : void
onActivityResult(int, int, Intent) : void
getScreenWidth() : int
getScreenHeight() : int
Sav eInputDialog
«use»
+
showDialog() : void
«use»
OkCancelDialog
+
Android:View
View
BusinessCardEditorSurface
+
#
#
#
+
+
+
+
BusinessCardEditorSurface(BusinessCardEditor, BusinessCard)
getGridPaint() : Paint
getBoundingBoxPaint() : Paint
getTextPaint() : Paint
snapToAxis(int, int, int) : int
findSelected(int, int) : BusinessCardItem
onDraw(Canvas) : void
setBackgroundDrawable(Drawable) : void
toggleGridLines() : void
setBusinessCard(BusinessCard) : void
toggleSnapGridLines() : void
Drawing 4.6.1 – business card editor class diagram
showDialog() : void
4.7.
Business Cards Tabs Style Browser
In our application there are two methods to manage cards, which can be chosen through application
preferences at the main screen. The first method is the tabs browser.
In the tabs browser each tab represents a real directory in the file system, except for the special tabs
(search, contacts and new). Within each tab, the cards inside that directory are shown as a list. Moving from
one tab to another is done by clicking it. One special tab is the search tab, which allows the user to search
for cards that contains his search string. If there is a card (in the whole database) that contains this string in
one of its items, the card would be shown in the search tab list. Another special tab is the "new…" tab which
allows the user to create new tabs. The last special tab is the contacts tab (if enabled), which shows card for
each contact in the device (see section 4.5 for extra details).
In any tab, if there are cards shown, the user can select them by clicking the wanted card. When selected, a
yellow border appears around the card. When a card is selected, the user can use the card through the
menu options, to call the phone number in the card, send SMS, send email if an email address exists, and
send the card via Bluetooth. The user can also perform file operations, such as moving the card to another
directory or deleting it. If the user chooses the edit option, the editor is opened with the selected card, and
the user can edit the card items and layout.
If no card is selected, it means that the current tab is the selected directory. If the user presses the menu
button, directory options appears. The user can delete or rename the selected directory, or create a new
directory, which will appear as a new tab.
In the following class diagram we can see that the tabs activity contains a collection of
ViewBusinessCardTabBase objects. Notice that ViewBusinessCardTabBase is also an activity. This structure is
enforced in Android’s tabs implementation. The ViewBusinessCardTabBase includes all the main logic for
tabs implementation, and two components inherit from it – the ViewBusinessCardListViewTab and the
ViewBusinessCardSearchTab. The last one implements the search tab, as mentioned before. The
ViewBusinessCardListViewTab implements a general tab, which represents a directory or the contacts tab.
In order to create the card list, we expanded Android’s ListView component and created our own
BusinessCardListView. This view uses an expanded adapter, based on Android’s BaseAdapter. This is done in
order to create a list with a customized view – a business card in our case.
As you can see, the tabs browser uses two additional activities – the device picker and the editor.
The device picker is used for sending a card via Bluetooth. When a user wants to send a card, he presses the
send option in the menu, and then the device picker is opened. If the user presses on the edit option, the
editor opens with the selected card.
class v iew er
Android:Activ ity
Android:ListView
TabActivity
BaseAdapter
Filterable
TabsActiv ity
BusinessCardsAdapter
+
+
+
#
+
+
+
+
+
+
+
+
#
#
BusinessCardsAdapter(BusinessCardListView)
getFilter() : Filter
getView(int, View, ViewGroup) : View
getImage(BusinessCard) : Bitmap
getCount() : int
getItem(int) : BusinessCard
getItemId(int) : long
notifyDataSetChanged() : void
onCreate(Bundle) : void
setCurrentTab(String) : void
getCurrentTab() : String
reload() : void
addTab(Class<?>, String, String, String, Drawable) : void
onDestroy() : void
onResume() : void
Activity
v iew er::BluetoothDev icePicker
#m_listView
Activity
ViewBusinessCardsTabBase
ListView
OnItemClickListener
BusinessCardListView
+
+
+
#
+
BusinessCardListView(Context)
onItemClick(AdapterView<?>, View, int, long) : void
-m_listView
getSelected() : BusinessCard
getItems() : List<BusinessCard>
notifyDataSetChanged() : void
+
#
#
#
#
+
+
+
#
-
onCreate(Bundle) : void
getListView() : ListView
find(String, String) : BusinessCard
getBusinessCards() : List<BusinessCard>
createBusinessCards(String) : List<BusinessCard>
onCreateOptionsMenu(android.view.Menu) : boolean
onMenuOpened(int, Menu) : boolean
onMenuItemSelected(int, MenuItem) : boolean
onResume() : void
refresh() : void
«use»
«use»
BusinessCardEditor
View BusinessCardsSearchTab
View BusinessCardsListView Tab
+
onCreate(Bundle) : void
#
+
#
onStart() : void
onCreate(Bundle) : void
createBusinessCards(String) : List<BusinessCard>
Drawing 4.7.1 – business card editor class diagram
#
#
#
#
onCreate(Bundle) : void
send(int) : void
onStart() : void
setupBluetooth() : void
createDeviceInfo(BluetoothDevice, boolean)
discoverDevices() : void
stopDiscovery() : void
setStatus(String, String) : void
onDestroy() : void
onActivityResult(int, int, Intent) : void
4.8.
Business Cards Gallery Style Browser
The second business cards management style is the gallery browser. Like the tabs browser, it organizes the
cards into groups managed by the user and displays them in a gallery or in an explorer as icons. The view
hierarchy in this activity is made up of several framework code components we created.
The first is the gallery view which is a generic view structure that lets the user view images, one at a time,
letting the activity that uses it control when to switch to the next view (usually using swipe). It also allows
adding arrows to left and right so that the user can touch the arrows instead of swiping. This is the same
view we used in the editor for the theme selector activity.
The second is the explorer view which is also a generic structure. This one shows the images as small icons
allowing scrolling either way and selecting one of the images. Both the gallery view and the explorer view
are based on an items container interface and each image is an item in the list managed by the view. This is
used both for cards and folders.
The third view used here is the multi view. This view is specifically designed to combine the gallery and
explorer views together so we can alternate between the visual ways we show the items while using the
same list.
The gallery browser uses a view hierarchy made up of a header view that contains a search view. The search
view also contains a flipper view from android that can switch between two different views. The flipper
contains two multi views, one for the folders and the other for the cards themselves.
Similar to the tabs activity, cards and folders can be managed through menu options (the same logic is used
for both tabs and gallery activities).
In the following class diagram we can see the gallery view in the center. It has a reference to the search
view in order to control the filter and to the header view in order to control the header text. It also contains
a reference to the flipper. When a user clicks on a folder the flipper can update the cards multi view list and
flip between these view hierarchies to show the cards inside the folder.
The browser activity also uses the editor in order to allow the user to edit a card, and the device picker
activity in order to send the selected card to a remote device.
class gallery
v iew s::Android:View
LinearLayout
views::SearchView
+
+
+
+
+
+
+
v iew er::BusinessCardEditor
SearchView(Activity)
inSearchMode() : boolean
showSearch(boolean) : void
hideSearch(boolean, IAnimationEnd) : void
hideSearch(boolean) : void
setFilter(String) : void
getFilter() : String
+
-m_header +
-m_search
T
LinearLayout
views::HeaderView
FrameLayout
MultiView
HeaderView(Context)
setText(String) : void
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
«use»
Activity
IMenuActionListener
GalleryActiv ity
v iew er::Android:Activ ity
+
+
+
+
+
+
+
onBackPressed() : void
onTouchEvent(MotionEvent) : boolean
onActionCompleted(MenuAction, Object) : void
onActionCanceled(MenuAction) : void
onCreateOptionsMenu(Menu) : boolean
onMenuOpened(int, Menu) : boolean
onMenuItemSelected(int, MenuItem) : boolean
MultiView(Context, List<T>)
setItems(List<T>) : void
getItems() : List<T>
setSelected(T) : void
getSelected() : T
notifyDataChanged() : void
empty() : boolean
setupSwipe() : void
onTouchEvent(MotionEvent) : boolean
onSwipe(int) : boolean
onDoubleTap() : boolean
inExplorer() : boolean
showExplorer(boolean) : void
hideExplorer(boolean) : void
setFilter(String) : void
Activity
v iew er::BluetoothDev icePicker
«use»
T
T
ViewFactory
FrameLayout
views::ItemsView
views::GalleryView
+
+
+
+
+
+
+
+
+
GalleryView(Context, List<T>, boolean)
showPrevious() : void
showNext() : void
makeView() : View
hasArrows() : boolean
isCyclic() : boolean
setCyclic(boolean) : void
notifyDataChanged() : void
setItems(List<T>) : void
+
+
+
+
+
+
+
+
«interface»
views::ItemsContainer
ItemsView(Context, List<T>)
notifyDataChanged() : void
setItems(List<T>) : void
getItems() : List<T>
setSelected(T) : void
getSelected() : T
setSelectedIndex(int) : void
getSelectedIndex() : int
+
+
+
+
+
getSelected() : T
setSelected(T) : void
getItems() : List<T>
setItems(List<T>) : void
notifyDataChanged() : void
T
views::ExplorerView
ScrollView
v iew s::VerticalScrollView
+
+
+
+
ExplorerView(Context, List<T>, boolean)
notifyDataChanged() : void
getLayoutColumnsAmount() : int
setLayoutColumnsAmount(int) : void
Drawing 4.8.1 – gallery browser class diagram
-vscroll
+
+
+
VerticalScrollView(Context)
onTouchEvent(MotionEvent) : boolean
onInterceptTouchEvent(MotionEvent) : boolean
5. Optimizations
After implementing the application we tried to optimize its performance. Since Android limits memory
usage to 16MB per application, we had to use less memory and more IO. In order to find where we allocated
large blocks of memory, we used Eclipse Memory Analyzer and garbage collector logs. From these tools, we
found two main activities with the highest memory usage. Most of the memory was for bitmaps storage,
which was done for performance enhancement. In order to avoid application crashing due to out of memory
exceptions, we cached most of the bitmaps to files and stored only 3 bitmaps in memory at any given time.
Another problem was the size of the business card and the fact that we had to “transfer” it between
different activities in the application. In Android, in order to send data to another activity, Intent objects are
used. The size of an intent is limited and couldn’t contain the entire business card. In order to solve this
problem, we cached the card to temporary storage and sent references to the file instead. On the opened
activity, we used the reference to get the card’s instance.
Based on the results from the memory analyzer of from the logs, it seems that memory problem were
solved and the application became more stable.
6. References
•
Google’s Android Developers
–
•
Wikipedia
–
•
Bluetooth, encryption
Security in software applications - Course site
–
•
http://developer.android.com/index.html
http://webcourse.cs.technion.ac.il/236350/Spring2010/en/ho_Lectures.html
Java docs
–
http://java.sun.com/j2se/1.5/docs/api/
Download