CS8803 Advanced Internet Application Development Follow Me Project Report Spring 2009 Dinesh A. Joshi <dinesh.joshi@gatech.edu> Kunal Chawla <chawlakunal@gatech.edu> Radhika Shivapurkar <radhika.shivapurkar@gatech.edu> Shantanu Gupta <sgupta65@gatech.edu> @gatech.edu> Contents 1. 2. 3. 4. 5. 6. 7. 8. 9. Introduction Problems being addressed Design Implementation a. User Interface on Android b. Maps c. Web Service Contributions of this project a. Hands on experience b. From the class c. Extension of project Performance Evaluation Technical challenges faced Conclusion References 1 1 Introduction Many location based services using GPS have been implemented and are in day to day use to locate everything from points of interest to family members, from restaurants to ATMs. In most of these location based usage scenarios we know the address of our destination. We ask GPS to help us get there. GPS coordinates are available and the GPS device guides us with what directions to take, which landmarks should we follow etc. But real life scenarios are always not ideal like knowing the address. Many times we just know how to reach a destination not knowing the address. How many times are we following a car and a red light spoils the tracking. What happens? We are Lost .We are clueless which way to go unless we contact the person and take manual direction from the car we were following. Our GPS won’t guide us in this case because we do not know the destination address. What if it’s a trek on a mountain and you are following you friend? This is still worse. Don’t you think we need an application which can help us to follow our guide who can be your friend or your friend’s car? Yes we indeed do. This has motivated us to create ‘FollowMe’ an application which will allow us trace and follow the path of the leader.’ FollowMe’ will continuously update you with the path taken by your guide. And you Follow the Footsteps!!! 2 2 Problems The problems being addressed by our project are varied: 1. 2. 3. 4. 5. User interaction issues Display of path information Data transfer / Bandwidth usage Efficient server implementation Compatibility with other services 1. User interaction issues: There are many systems out there in the market but they rarely have simple and intuitive user interface ( UI ). One of the goals of our system is to have a minimalistic UI which provides all the features with minimal hassles. 2. Display of path information: A natural question arises, how do I display the path? We could use lines to mark the route. But this is not very intuitive as the user sees only a line which is confusing. The direction is unknown unless there are arrows marked on the line. We use way points to simply mark the way throughout the journey. This makes it easy for the user to recognize the path and is an efficient way of displaying information. 3. Data transfer / Bandwidth usage: This is a major concern for our system. Since we’re using hand held devices, the application is constricted with the bandwidth available and the amount of processing power available. Thus we offload all the processing to the server and the device merely acts as an interface to the application. We also use built in Google maps instead of serving it from the server this increases our efficiency many folds. We have built a JSON based web service which is far more bandwidth efficient than an XML based web service. 4. Efficient server implementation: A major challenge was to select the appropriate storage technology. We benchmarked two database servers and observed their effect on our web service’s performance. The results are attached at the end of this report and they are pretty interesting! Another challenge in efficient implementation was to make the source as compact as possible with as little over head as possible. Thus the source is a hybrid of PHP and Python. 5. Compatibility with other services: We understood the need of the time is not to burden the users with an additional user account information. Every service requires registration but our service works out of the box with your Google account! The positive aspect of this is, our service gives the user a fully integrated experience with your GMail / GTalk account. You can see your existing friends list and you don’t need to go through the whole process of registration and inviting all your friends! 3 3 Design of the system Overall Backend / Webservice: PHP/HTML Web Service Python Apache MySQL Data Store PostgreSQL / BerkeleyDB Interaction diagram: 3b: Post Location 4: Query C2’s location 5: Web Service Responds Web Service 3b: Post Location Client 2 Client 1 1a: Query Location 2a: GPS Responds 1b: Query Location 2b: GPS Responds GPS 4 4 Implementation User Interface After researching about the scenarios when our application would be used, we realized that it will be very important for the user to get to core of our application that is following someone or allowing someone to follow in as few steps as possible. So the user can reach the core of our application in just 2 steps (3 for first time users). The first screen allows the user to enter his Google credentials so that the FollowMe web server can pull his contact list. The user has the option of saving his credentials so that he can avoid entering it again. The user can follow anyone from this list that has an active FollowMe Session or allow anyone from the list to follow him. After the first screen the user gets the option of either following someone or being followed i.e. starting a new FollowMe Session. Depending on his selection he either selects whom to follow or whom all to be allowed for following. Screen Shots User Login Option to follow someone or allow someone to follow you: 5 Selecting friends to be allowed for following: 6 Selecting friend to follow: Following Someone: 7 All Android applications have a main activity file which loads up when you start the application. The main activity file for our application is FollowMe.java. This file acts as an interface between b logging into Google and the actual service provided by the application. On start it loads up LoginScreen.java to get the user credential. It then uses Login.java to actually log on to Google and get friends list. After this FollowMe.java loads up FFollowMeOption.java ollowMeOption.java activity file which allows the user to Follow someone or be followed by someone. Depending on the user’s selection either Follower.java is loaded or Followee.java. If the user selects the option of ‘Start FollowMe Session’ Followee.java is loaded. This displays the Google contact list of the user. He then can select whom all he wants to be allowed to follow him. This load up FolloweeMap.java which starts sending the users coordinates to the server. If the user selects, Follow someone’ Follower.java is loaded which givess the user the option to select from one of the friends who have an active FollowMe Session. Once the user selects whom he wants to follow FollowerMap.java is loaded which shows the other persons real-time time location on the map. The user keeps on getting periodic updates about the person whom he is following. 8 Design and Implementation of the Map: Google Maps on Android delivers a totally new experience for users through features that allow exploration of new and favorite places. The phone comes preloaded with Search, Maps, Gmail with Contacts, Calendar, Google Talk, and YouTube. The Maps application, specifically, lets users take advantage of GPS when in a new city or part of town. Android provides a GoogleMap API for rendering maps on the Andorid phones. Map rendering requires that you have the Google Maps external library installed in your SDK environment. By default the Android 1.5 SDK includes the Google APIs add-on, which in turn includes the Maps external library. To use the classes of the Maps external library in your application, you need to: • Install the Google APIs add-on, as described in the Installing document. If you are using the Android 1.5 SDK, you don't need to install the add-on — it's preinstalled in the SDK package. • Set up a new Android project — or reconfigure an existing one — to build against the installed Google APIs add-on • Set up an Android Virtual Device configuration that uses a the Google APIs add-on • Use the Maps classes in your application • Obtain a Maps API Key For Follow ME it was important to show live updates on the maps for the locations of the follower and the followee. For this purpose we have used the GoogleMap API for android. The Google APIs add-on includes a Maps external library, com.google.android.maps . The classes of the Maps library offer built-in downloading, rendering, and caching of Maps tiles, as well as a variety of display options and controls. Using this facility we tried to exploit the functionality of Google Map API in Follow ME application to create cool street and satellite views of the traces surrounding us. Taking real time updates for GPS location was not possible due to some constraints we developed a GPS traced and tested the Map rendering for the follower as well as the followee on the traced path We went about the entire process and the experience in map development was new and creative with good documentation for the API enabling us to do something that was not achievable without Google API. Getting a Map API key: MapView objects are views that display Maps tiles downloaded from the Google Maps service. To ensure that applications use Maps data in an appropriate manner, the Google Maps service requires that you register with the service, agreeing to the Terms of Service and supplying an MD5 fingerprint of 9 the certificate(s) that you will use to sign your application. For each registered certificate fingerprint, the service then provides the developer with a Maps API Key — an alphanumeric string that uniquely identifies you and your certificate. You then store your API Key in an attribute in your MapView elements, so that when your MapView requests data, the server can determine that you have registered with the service. If you do not supply a Maps API Key in your MapView elements, you will be able to compile and run your application, but the MapView elements won't be able to display data from the Maps server. To obtain the key for follow me we performed the following steps. Traced the location of android which was “ C:\Users\Radhika\AppData\Local \Android ” . The filename of the debug keystore is debug.keystore. For deploying to a real Android device, substitute the debug.keystore file with your own keystore file. To make things simple we just added (debug.keystore) to a folder in C:\ (for example, create a folder called "C:\Android"). Using the debug keystore, you need to extract its MD5 fingerprint using the Keytool.exe application included with your JDK installation. This fingerprint is needed to apply for the free Google Maps key. You can usually find the Keytool.exe from the "C:\Program Files\Java\\bin” folder. Issue the following command to extract the MD5 fingerprint. keytool.exe -list -alias androiddebugkey -keystore "C:\android\debug.keystore" -storepass android keypass android Once a certificate is ontained like: Certificate fingerprint (MD5): 00:11:22:33:44:55:66:77:88:99:AA:BB:CC:DD:EE:FF We used this to register for API key for Android Google Maps. Using Map Classes for Follow ME: The key class in the Maps library is MapView, a subclass of ViewGroup in the Android standard library. A MapView displays a map with data obtained from the Google Maps service. When the MapView has focus, it can capture keypresses and touch gestures to pan and zoom the map automatically, including handling network requests for additional maps tiles. It also provides all of the UI elements necessary for users to control the map. Your application can also use MapView class methods to control the MapView programmatically and draw a number of Overlay types on top of the map. In general, the MapView class provides a wrapper around the Google Maps API that lets your application manipulate Google Maps data through class methods, and it lets you work with Maps data as you would other types of Views. What we will do is, create a MapActivity(extend it) and setup a MapView-Object. 10 The Main steps are: 1. Setup MapView 1.1. Locate a positon and zoom 2. Toggle to sattelite mode 3. register some key-events on the MapActivity For Follow Me application we continuously send and receive the GPs co-ordinates in alt,lang format form the Follow Me web service .Also the real time mapping of the follower and followee is involved hence we have used the map classes and imposed Overlays. The following steps were involved in implementing maps. To use the Google Maps in Follow ME Android application, we needed to modify our AndroidManifest.xml file by adding the <uses-library> element together with the INTERNET permission: <uses-permission android:name="android.permission.INTERNET" /> To display the Google Maps in Follow ME Android application, we modified the main.xml file located in the res/layout folder by adding the library for the maps. <com.google.android.maps.MapView android:id="@+id/mapView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:enabled="true" android:clickable="true" android:apiKey="Follow ME key" /> Then we implement the respective code which renders the follower and followee using the Map Activity class by adding and rendering markers creating map overlays, providing different Android views etc. The Map Class basic structure can be given as below. Added functionality can be implemented to this structure. package com.FollowMe.GoogleMaps; import com.google.android.maps.MapActivity; 11 import com.google.android.maps.MapView; import android.os.Bundle; public class MapsActivity extends MapActivity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } @Override protected boolean isRouteDisplayed() { return false; } } Web Service Implemention General We have given the API used to access the web service in the last part. We now document the protocol and the format in which the data is sent and received over the web service. All the data being sent to the web service is URL Encoded and sent as GET requests while the data is returned as JSON objects. An example follows: After the following API call: http://localhost/fmws/session.php?start The result is: [0, “Successfully created session!”] 12 After the following API call: http://localhost/fmws/session.php?get&sid=1234&lastid=3 The result is: [ 2, [ {"locid":"4", "latitude":"41.960617", "longitude":"-87.646054"}, {"locid":"5", "latitude":"41.960991", "longitude":"-87.646073" } ]] When the user logs in with his GMail credentials, the web service returns the session id, message and the list of friends in his friends list. A sample response would be: ["c7f85a2cf45c68b7f055be31e087118d", "Success!", [{"nick": "radhikashivapurkar", "id": "radhikashivapurkar@gmail.com"}, {"nick": "", "id": "followme.me01@gmail.com"}, {"nick": "", "id": "thisisshantzz@gmail.com"}, {"nick": "", "id": "linux.future@gmail.com"}, {"nick": "", "id": "followme.aiad@gmail.com"}, {"nick": "", "id": "chawlakunal86@gmail.com"}]] MySQL Implementation Both backends use the same tables since we wanted to perform a performance evaluation at the end. The web service maintains two tables: 1. Session Table 2. Session Updates Table The session table stores the active sessions as follows: Session_id User_id List_ids S1 Linux.future Chawla.kunal, shivapurkar.radhika S2 Test.user1 Shantanu.gupta 13 The fields are pretty self explanatory. The list_ids field stores the list of friends that are allowed to follow you. An example of session update table ( session_S1 ) Locid Latitude Longitude 1 20.23232 -82.232323 2 21.233233 -82.445334 The session update tables are created on the fly when a new session is created. This is done because they are transactional tables. PostgreSQL Implementation The implementation here is the same, the only difference is the PHP classes used to create and manage the database connectivity are changed to reflect the PHP PostgreSQL API. BerkeleyDB Implementation We were unable to implement the system on BerkeleyDB. MySQL 5 has pulled out the support for BerkeleyDB and the stand alone implementation was insufficient for us. The detailed reasons are noted at the end of the document. 14 5 Contributions of this project This project takes a new look at the location based services. Most services simply reuse existing information while our project enables us to generate new information! Complete location privacy: One of the most important implications of FollowMe is location privacy while you’re travelling. Lets say we store the information of a FollowMe session starting from Georgia Tech and going to Georgia Aquarium. Now suppose someone wishes to travel from Georgia Tech to the Georgia Aquarium, he can do this without worrying about revealing his location! This is a big advantage for the end user who doesn’t wish to have location privacy! The FollowMe server doesn’t know the GPS location of the user requesting the FollowMe session. Hence the user gets the route without ever broadcasting his location. More accurate mapping and updating existing information: Another important offshoot of this project is updating existing map routes. Suppose I’m travelling from Georgia Tech to Dunwoody and I notice the old Walmart store has been now converted to some Mall, I can immediately notify the service about the change. The service will then tag the nearest way point with the change. The FollowMe service could be extended to allow for this. Apart from these extension to our project, we had a lot of hands on experience: 1. 2. 3. 4. 5. 6. 7. Learning to work with the Android SDK Building a real live web service Learning to work with Google Maps Hybrid programming – Java / PHP / Python Protocol building Integration with other services – Google Accounts / GTalk Mobile platform programming These are just some of the learning experiences we had. From the class we applied the following concepts: 1. 2. 3. 4. 5. 6. 7. Scaling Performance Tuning Privacy issues with location based services Performance measurement Efficient code implementation Cross platform interaction Efficient protocol implementation 15 6 Performance Measurements The reason to implement the Web Service using two different database servers was to figure out which server would provide better performance for a web service such as this. For measuring the performance, we queried the web service repeatedly with around 30,000 queries for insertion ( PUT ) and then 30,000 retrieval queries ( GET ) and noted the time that it took for the web service to respond. The results are displayed as graphs. On the X-axis, we have the query number while on the Y-axis we have the time taken for the web service ( note this is not the same as the time taken for the database server to insert / retrieve ) to respond with either a success or an error message. MySQL Backend GET performance We observed that the general performance was very good. There were some anomalous peaks. 16 MySQL Backend PUT performance Even here observed that the general performance was very good. There were some anomalous peaks. 17 PostgreSQL Backend GET performance PostgreSQL Backend PUT performance 18 Conclusions – Performance Evaluation From the above graphs it is clear that MySQL is more suitable. It does show high retrieval / insertion time in certain cases but in the common case we observe that it is faster. 19 7 Technical Challenges Faced We faced several technical challenges while working on this projects, some of them are detailed below. Facebook integration We had originally decided to import the user's Facebook friend list rather than creating our own social networking component so that the user can decide who to follow or who should be following him. We found out that Facebook provides an API called Facebook connect that allows third party applications to connect to Facebook and use information from the user's Facebook profile. Since Facebook connect allowed third party applications to use information on the user's profile page, the user needed to authenticate himself and thus, instead of creating our own authentication component, we decided that we would let Facebook authenticate users for us. We were able to achieve almost everything that was needed. We managed to get a API key and secret key from Facebook since Facebook treats all third party websites that use Facebook connect to access a user's profile page as applications. We also created a cross domain receiver file that would provide secure cross domain communication with Facebook since Facebook Connect requires to have a secure connection with the Facebook server when authenticating the user. We created this file as a .htm file but ran javascript to provide the actual secure connection. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" > <body> <script This is a sample of the cross domain receiver file that we used. Once login was successful, we wrote a php script that would import the user's friend list onto our application. All this worked when we tried it as a web service. $friends = $facebook->api_client->friends_get(); PHP script to get friend list of user. But when we tried to import this script onto Android, it did not work. At first we thought that Android was not able to run the php script, so we changed the php script to javascript. Javascript required a special Facebook library to call Facebook specific functions. <script src="http://static.ak.connect.facebook.com/js/api_lib/v0.4/FeatureLoader.js.php" type="text/javascript"> .... FB.Facebook.apiClient.friends_get(null, function(result, ex) 20 Sample javascript code to get friend list of user This did not work as well. After some research we were able to determine that Facebook Connect did not support the Android platform due to compatibility issues. So we decided to use pull friends of Google Talk. We used XMPPPY (XMPP API in python) for this purpose since Google Talk works on the XMPP protocol. The advantage of using this API was that it did not require secure cross domain communication unlike Facebook. Due to this, we were able to provide authentication even when Android did not support XMPPPY but our web server did. In our case, the Android client passed the username and password as command line arguments to a python script running on our web server and our web server was able to relay this information to Google using the API. Once authentication was done, we used the API to get the list of friends listed on the user's Google Talk friend list. Once we were able to get the friend list, the web server created a session for the Android client. We did this by creating a MD5 hash of the current time and sent the session id to the client. Implementation and Performance testing on Berkeley DB : Berkeley DB is an Open Source embedded database system that supports concurrent access by multiple users and provides industrial strength transaction support, including surviving system and disk crashes. We had originally decided to use Berkeley DB because it was said to be very resilient to system crashes and also it was supposed to provide very good performance when it came to insertion and retrieval of data. But there was a big problem with Berkeley DB. MySQL was actually supporting Berkeley DB engine upto MySQL ver 5.0. For all later releases of MySQL, there was no support for Berkeley DB. So we installed Berkeley DB from its source code. This code was provided by Oracle. Berkeley DB supports only a few programming languages like C, C++, Java, Tcl and Perl. Since we were using PHP as the server side scripting language, we had to change to a completely different style of programming. Since, Berkeley DB was originally written for programming in C, we decided to write functions in C. The second problem was that Berkeley DB did not have the concept of tables. It stored data in files and it assumed a collection of records as a database. Moreover, Berkeley Db does not support industrystandard programmatic interfaces like ODBC, OleDB or SQL etc. and so, there was no interoperability among Berkeley DB and the other database systems we used like MySQL and PostgreSQL. Moreover, it stores data in the form of (key, data) pairs. Since it does not support the concept of tables, data from individual fields becomes difficult. Also, there were many data types that were defined for PHP but not defined for C which we had to create ourselves. The concept of autonumber was not defined for C and implementing autonumber for C is difficult because obtaining individual fields from whole records is difficult in Berkeley DB. We needed this type because we had defined location id to be an autonumber. Challenges faced while implementing the Maps: The location updates are constantly plotted on the map. However these are only points and does not involve driving directions between two GPS co-ordinates. Plotting a drivable path hence was an important challenge .However due to the limitation of android-sdk-windows-1.5 version of Android it 21 was not possible to implement the driving direction concept. The implementation requires Google nav package used for goggle Map navigation. However the current Android versions do not have a support for these. The support was available in earlier versions of Android. Another major problem we came across while developing on Android was the generation and implementation of API key. Due to buggy nature of the Android emulator the Rendering of Map; sometimes becomes irrespective of proper setting of permissions as well as using an appropriate key. Android is not a completely bug free platform. The android emulator has a large number of bugs. The emulator many a times does not reflect map features irrespective of all the things being in the right place. General Challenges on the Android platform: The R.java file which is generated by the IDE for us should not be modified; everyone knows this. Not just this but it cannot be overwritten with the previous version also. We learned this hard way while restoring one of our backup copies. Android uses XML for designing the UI. This was a very new way of designing UI for all of us so it took us quite a bit of time in getting hang of designing UI using XML. Android provides quite a few set of components for designing UI but the components are very basic in nature. To design a list of checkboxes we had to start from very basic stuff like combining a CheckBox along with TextView and then add it to the list. This was one of the most challenging part of our project. 22 8 Conclusion The project was pretty challenging technologically. The problems we faced were compounded by the fact that Android released a new SDK while we were developing the application. This forced us to rewrite major parts of the code since they changed API calls which broke our functionality. Another problem faced was that our machines were 64 bit and the Android emulator is known to have unpredictable behavior on 64bit platforms – especially with Windows Vista. The project is a good concept and as detailed in the report can have several uses including a big impact on the location privacy aspect. Unfortunately, given the time, resources and skill set we were unable to implement it effectively. 23 9 References 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. http://mobiforge.com/developing/story/using-google-maps-android http://developer.android.com/reference/packages.html http://developer.android.com/guide/tutorials/views/hello-mapview.html http://developer.android.com/guide/topics/location/geo/mapkey.html http://developers.facebook.com/connect.php http://wiki.developers.facebook.com/index.php/Trying_Out_Facebook_Connect http://xmpppy.sourceforge.net/apidocs/index.html http://developer.android.com/ http://www.anddev.org http://www.php.net http://docs.python.org http://java.sun.com/docs http://www.w3c.org 24