Finally, Google Summer of Code 2014 is Over Successfully

Though the major part of my project – i.e. programming for app –  was almost completed, but still one thing was missing. I still had to clean my code, organize the whole package in better way, review all the files, re-factor the variable names, methods, remove unused commented code and add proper comments (whereby missing). After discussion with my mentor, i finally did all this and submitted my code on Google-Melange as well as committed to GitHub.

for-blog-featured-image_completed

On August 27, 2014, I got the confirmation email from Google that my Final Evaluations results are processed and I have successfully completed and passed Google Summer of Code 2014. Yaaaayyy 😀

gsoc_final_eval

A big Thank-you to my mentor, Sir Christian Garbers, INCF and Google for this opportunity and continuous support. GSoC was an incredible experience and a great inspiration for moving towards open-source development in future. Participating in Google Summer of code and do coding was indeed FUN, full of learning.

My pull request was accepted and got merged with G-Node Repo, thus marking my first ever official open-source contribution :)

Anyone who wants to see my project and what I coded can download my submission files from Google Melange Project page: http://www.google-melange.com/gsoc/project/5724160613416960 and it’s available on GitHub as well: https://github.com/G-Node/GCA-Android/pull/3. You can download the zip and import it into eclipse directly as an Android Project.

Besides this, Google also sent a T-shirt and a certificate.

 gdoes_14

Google Summer of Code – week # 10 – 11

This blog post covers previous last 2 weeks – Though most of the Schedule section had been covered till last week, it wasn’t still complete yet. I mentioned this in my last blog post as well that Schedule may take another week to complete and by week # 10, it was complete. Let’s move on towards the details…

for_blog_week10-11

Schedule:

The idea was that clicking on any of the Schedule item should show it’s detail. But as Schedule item can be any from Session, Track or Event, approach was supposed to cover these 3 differently. Initially, I created an Activity: ScheduleItemExtended.java – Clicking on the Schedule item opens this activity and that Schedule item is passed to the activity.

The problem that I encountered there was to pass custom objects (Event, Session, Track object) in intent because these weren’t simple strings those can be passed by calling putString() method. For this purpose, I converted these custom objects to serializable by making each class to implement serializable interface, because a serializable can be passed to an intent by calling bundle.putSerializable() method.

//Passing object to intent

 Intent intent = new Intent(getActivity(), ScheduleItemExtended.class);

 Bundle bundle = new Bundle();
 bundle.putSerializable("event", eventObject);

 intent.putExtras(bundle);
 startActivity(intent);

 // Getting the passed object in activity
 EventScheduleItem event = (EventScheduleItem) bundle.getSerializable("event");

The example above shows passing of an ‘Event’ to intent whereas any of the Schedule objects can be passed in the same way.  Next I created 3 different layout files each for a Schedule object and based on the type of object that’s passed to ScheduleItemExtended Activity, the relevant layout is set for that activity. If the object is Session, it shows the information about TRACKS in that SESSION – Clicking on any of the TRACK Button shows the EVENTS inside that TRACK – Clicking on any of the EVENT Button shows the detail of that particular Event. (Will be more clear in the screenshot).

Launching Abstract from the Event (if exists)

An event may have an Abstract linked with it. The task was to implement option for opening relevant Abstract from Event if it exists. Details about this can be found here on issue # 13 on GitHub that my mentor opened.

This is the example of abstract key in event JSON Object:

{
 "title": "Neuro-electric Transitions",
 "subtitle": "might be there",
 "start": "13:30",
 "end": "14:30",
 "location": "B01.063",
 "date": "2014-08-01",
 "authors": ["George Martin"],
 "type": "talk",
 "abstract": "http://abc.xyz.org/api/conferences/ba604a3c-e95x-4569-14a9-7d4dedd08310/abstracts/993aa24d-6b48-4283-9643-619d371dbafc"
 }

In this example, Event ‘Neuro-electric Transitions‘ has associated Abstract with it and the UUID of that Abstract is the part of URL after last slash (/) – First step was to extract the UUID of Abstract from the URL. For this purpose, I used JAVA’s String lastIndexOf method to find the last occurring slash (/) and extract string starting after that slash till end. This code did the job:

String event_uuid = event_abstract_url.substring(event_abstract_url.lastIndexOf("/")+1, event_abstract_url.length());

// event_abstract_url is the complete URL string from event object's Abstract Key

Once I had the Abstract UUID, I added a simple check to see if there’s any Abstract against that UUID in Database by executing an SQL Query to fetch Abstracts and putting a check condition in where clause. In case of no Abstract for that UUID, cursor.getCount returns < 1 – Based on this cursor count value, ‘Open Abstract’ button is enabled (if Abstract exists) or disabled (if Abstract doesn’t exist).

schedule_extended_module_screenshot(Screenshot showing Schedule Details for Session, Track and Event)

What Else ?

Besides Schedule, I also worked on Main Menu screen and completely revamped it’s layout and that really looks stylish now (Shall post screenshot soon in next blogpost). Another thing that wasn’t done till now was Up/Back navigation wasn’t implemented for any of the section. I worked on that part and implemented back/up navigation and set parentActivity attribute for activities in  manifest.xml.

Major part of the app has been completed and time is being spent on code improvement and performance optimization now.

That’s all for past 2 weeks – if you have any question about the code or related, feel free to ask in comments and do share your thoughts and feedback on it in comments below. I’ll be looking forward to any suggestions or feedback.

GSoC Week # 10,11  – (20 July 2014 – 03 August 2014)

Google Summer of Code – week # 9

One of the most important and necessary feature for the application is ‘Schedule’ section and as I mentioned in my last week blog post, this week wandered around working on implementation of ‘Schedule’. Though it’s work in progress and may take another week for completing it’s implementation but the basic, most-needed and challenging part is completed. Let’s take a look at this..

for_blog_week9

Schedule:

Just like the Abstracts, organization had changed the format of Schedule and it’s data model so the previous data-model, JSON Parser and previous implementation wasn’t going to work anymore So, I had to work in Schedule from scratch. The new Schedule Model JSON file can be found online here.  In the new data model, Schedule has 3 different components which you can see in data file too. Let me describe the different schedule components:

1 – EventBasically an Event is what the name says. It can for example be a talk, a coffe break a workshop.
2 – TrackA track is a collection of events (at least one) that happen after each other.
3 – Session: A session is a collection of tracks that might take place at the same time.

This can be bit complicated to understand but here’s the illustration (provided to me by my mentor) on how these are all related:

schedule_components_illustration

I hope above posted illustration makes the relation among these components clear. Since we now have 3 different components, I had to make 3 different classes. (each for one schedule component i.e. event, track and schedule). Thus, I created 3 Classes: EventScheduleItem.java, TrackScheduleItem.java and SessionScheduleItem.java. The interesting is here is ‘some nesting in classes’  because Track consists of events so the Track Class has an array of Events (EventScheduleItem) for maintaining the events for the track. And the Session Class has an array of Tracks (TrackScheduleItem) and Track class as I just mentioned has array of Events (EventScheduleItem).  Instead of storing the schedule data into Database after parsing, I stored all the schedule stuff into the 3 Arraylists – each for a schedule component maintaining the events, tracks and sessions. Those arraylists will be populated during the process of JSON parsing.

Besides these 3 classes, I required another class for maintaining the order and relationship of all schedule components as per the data source. That class was required for maintaining the index of schedule item on it’s respective arraylist, that’s to be displayed. For example, after the schedule would be parsed and arraylists will be populated – events have own arraylist holding events one after another but that’s not the case for main schedule. An event can be followed by an Track or Session or vice versa so some sort of mechanism was required that what’s to be fetched next and that’s why I created an class ScheduleItemRecord.java. This maintains the type of schedule component, it’s index on respective array and date on that Schedule Components respective ArrayList. This would tell e.g first schedule component is ‘event’ and located on ‘event’s arraylist at index 0’, second schedule component is ‘session’ and located on ‘session’s arraylist at index 3’ etc.

So uptill now, I have talked about the 4 Arraylists that get’s populated while the JSON is being parsed. The ListView adapter get’s the ArrayList of ScheduleItemRecords and then uses that to bring the content to be displayed from it’s respective ArrayList.

Schedule implementation has been most challenging part uptill now. Unfortunately it’s code is much complex and consists of more than Thousand lines so I can’t write that all here. But the Good part is, its done finally :)

All the code is available on Github and you are most welcome to explore and ask me questions if you don’t understand any part of it. Github Link: https://github.com/shumail92/GCA-Android/tree/master/Conference-v2/src/com/g_node/gca/schedule

Here are the final Screenshots of Schedule section:

As you can sport the ‘Tabbed Layout’ in screenshots above, this was the most challenging part and took most time in implementation of the Schedule. Just to summarize it’s implementation, I first wrote a function for grouping the events according to the Date. And then the ScheduleTabsAdapter manages fetching the respective list of events itself. Once again, because of it’s complexity and little mess I can’t go to it’s whole detail here. The important thing is the function that does grouping of events according to date so here’s code for that function:


void groupEventsByDate() {

	Log.i(LOG_TAG, "in groupEvents func");
	List<String> differentDatesForGroups = new ArrayList<String>();
	int indexOfCurrentDate;

	for(int i=0; i<scheduleRecordsArray.size(); i++) {
		Log.i(LOG_TAG, "in groupEvents func for loop ");
		//get current event record from indexes array
		ScheduleItemRecord temperoryScheduleItem = scheduleRecordsArray.get(i);

		String dateOfCurrentEventItem = temperoryScheduleItem.getEvent_date();

		if(!differentDatesForGroups.contains(dateOfCurrentEventItem)) {
			//if date is not already in record, add it
			differentDatesForGroups.add(dateOfCurrentEventItem);

			indexOfCurrentDate = differentDatesForGroups.size() -1;
		} else {
			//get index of the date
			indexOfCurrentDate = differentDatesForGroups.indexOf(dateOfCurrentEventItem);
		}
		//now check the List of GroupEvents for this Index

		DateWiseEventsRecord tempDateGroup;

		try {
			tempDateGroup = dateWiseEventsRecordList.get(indexOfCurrentDate);
		} catch (IndexOutOfBoundsException e) {
			// TODO: handle exception
			dateWiseEventsRecordList.add(new DateWiseEventsRecord(dateOfCurrentEventItem));
			tempDateGroup = dateWiseEventsRecordList.get(indexOfCurrentDate);
		}

		if(tempDateGroup == null ) {
			dateWiseEventsRecordList.add(new DateWiseEventsRecord(dateOfCurrentEventItem));
			tempDateGroup = dateWiseEventsRecordList.get(indexOfCurrentDate);
		} //end if condition for null

		//add the index of this event item into the group eventsForThisDate
		tempDateGroup.addEventsForDate(i);

		//Update the main list
		dateWiseEventsRecordList.set(indexOfCurrentDate, tempDateGroup);

	} //end outer for loop - iterating for indexes array
} //end function groupEventsByDate

So that’s all for this week – if you have any question about the code or related, feel free to ask in comments and do share your thoughts and feedback on it in comments below. I’ll be looking forward to any suggestions or feedback.

GSoC Week # 9 – (14 July 2014 – 20 July 2014)

Google Summer of Code – week # 8

Since I had implemented the Tabbed layout for Abstracts Activity last week with 2 Tabs, one for the main Abstract Content and other for Notes – it was time now to implement ‘Notes‘ feature that’ll give user an option for taking notes against an Abstract if he would want to note something or write anything for that particular Abstract.

Notes:

The first step for implementation of ‘Notes’ was to create a separate table in Database for it.  So i added a Table named ABSTRACT_NOTES in existing database with 4 columns i.e. NOTE_ID, ABSTRACT_UUID, NOTE_TITLE, NOTE_TEXT.  You might be wondering about the ABSTRACT_UUID column here; well that’s intended for maintaining the Abstract UUID of the Abstract for which user is taking the note. The rest of columns are self-explanatory. The query for this table goes like this:

CREATE TABLE IF NOT EXISTS " + TABLE_ABSTRACT_NOTES + "(NOTE_ID INTEGER PRIMARY KEY,
ABSTRACT_UUID VARCHAR NOT NULL, NOTE_TITLE TEXT, NOTE_TEXT TEXT);

-- Query for table creation

Besides this, I also created 3 functions in DatabaseHelper for db functionality of Notes – one for adding notes, second for updating note and the last one for deleting note functionality.  Following is the code for the 3 functions:


//Function for adding notes for some abstract into Database TABLE_ABSTRACT_NOTES
public static void addInABSTRACT_NOTES(String abstractUUID, String noteTitle, String NoteText) {

 ContentValues values = new ContentValues();

 values.put("ABSTRACT_UUID", abstractUUID);

 values.put("NOTE_TITLE", noteTitle);

 values.put("NOTE_TEXT", NoteText);

 long note_id;
 note_id = database.insert(TABLE_ABSTRACT_NOTES, null, values);
 Log.i("GCA-DB", "Note inserted: id = > " + note_id);
}

//Function for delete notes for some abstract from Database TABLE_ABSTRACT_NOTES
public static void deleteFromABSTRACT_NOTES(long id) {
 long rows_affected = database.delete(TABLE_ABSTRACT_NOTES, "NOTE_ID = ?", new String[] { String.valueOf(id)});
 Log.i("GCA-DB", "deleted Note from db - no: " + rows_affected);
}

//Function for updating the Note if user edits it
public static void updateNoteABSTRACT_NOTES(String note_id, String noteTitle, String NoteText) {

 ContentValues values = new ContentValues();

 values.put("NOTE_TITLE", noteTitle);

 values.put("NOTE_TEXT", NoteText);

 long rows_affected = database.update(TABLE_ABSTRACT_NOTES, values, "NOTE_ID = ?", new String[] { note_id} );
 Log.i("GCA-DB", "Updated Note from db - no: " + rows_affected);
}

Next step was the layouts implementation. For displaying the Notes in Notes Fragment, ListView was the best option which I moved for. Since it involved fetching from database, i needed some sort of Cusror implementation. Thanks to the availability of SimpleCursorAdapter in Android SDK, it saved time and hassle as I didn’t have to implement custom cursorAdapter for this. If you don’t know of SimpleCursorAdapter, do check it out – it’s Great thing.

SimpleCursorAdapter adapter = new SimpleCursorAdapter(getActivity(),
      R.layout.noteslist_item_layout, notesCursor,</pre>
      new String[] {"NOTE_TITLE"}, new int[] { R.id.noteTitle}, 0);

//do Check out the SimpleCursorAdapter documentation for understanding the parameters in constructor.

// NotesCursor is the DB Cursor that has fetched data from db

// NOTE_TITLE is the name of column that's mapped onto R.id.noteTitle TextView

Screenshots – ListView of Notes
notes_module_screenshot_1

After that, I implemented the ListView onItemClickListener so if user clicks on some note, it shows up. Initially I was going for a separate activity for displaying note but then I thought that would be little messy than if note shows up in a pop-up dialog. Thus I tried showing it in DialogFragment. It worked out better and looked Great. (See in the screenshot later)

Like displaying the note in DialogFragment, I decided to implement ‘Adding new Note’ with DialogFragment too. But this was little tricky than the basic dialog. I had to show 2 fields in add new note Dialog where user can input title and text of note that he’s adding. For this purpose, I had to create a separate Layout for the ‘AddNoteDialogFragment and inflate it in onCreateDialog.  The layout file has 2 simple textViews for labels and 2 EditTexts for taking input. (See the final UI in screenshot later)

I reused the same layout file (that was used for AddNoteDialogFragment) for the EditNoteDialogFragment too. The major difference was that in this dialog the title and note text fields are already populated with the existing data and user can edit in those fields and then on clicking of dialog positive button ‘Update’, the note update function is called and the note is updated with the new values for Title and Text.

To provide user the options for Editing and Deleting a note, I had to add Context menu for the ListView so if user long-presses an listview item, the menu pops up with 2 options – EDIT and DELETE. On Clicking Edit, it opens up EditNoteDialogFragment and or clicking Delete, it gets the ID of that Note (from the Cursor _id column) and calls delete function for it.

notes_module_screenshot_2

You might be wondering here that what’s ‘REFRESH’ button for – Well, that’s to refresh the notes list after user edits or adds a new note so that the notes are fetched again from DB and the ListView updates with latest record.

The complete code for this Notes Feature can be found on Github repo of this project – link:
https://github.com/shumail92/GCA-Android/tree/master/Conference-v2/src/com/g_node/gca/abstracts

if you have any question about the code or related, feel free to ask in comments and do share your thoughts and feedback on it in comments below. I’ll be looking forward to any suggestions or feedback.

GSoC Week # 8 – (07 July 2014 – 13 July 2014)

p.s I also worked a little on Schedule section as well in this week, but will cover that in detail in next week blog post.

Google Summer of Code – Week # 7

As the Abstracts section’s implementation was completed last week, it was time to move forward. The plan was to implement the ‘Schedule’ Section but unfrotunately my mentor, Sir Christian Garbers, told that they still had not finalized the Schedule JSON Format and he would be AFK for next few days. So I decided to skip ‘Schedule’ section for the moment and go on…

for_blog_week7

Maps:

The basic task was to port the map activity for new version and layout from previous version, which I managed to do easily. The next step was to activate Google Maps API V2 by getting API key from Google. Google has outlined the process for getting API Key for your android app here: https://developers.google.com/maps/documentation/android/start

I decided to extend the maps functionality for adding Navigation option so user can route himself or get directions for any of the marked locations on map from his/her current position, by clicking on the Marker infoWindow on the Map. For this purpose, I drafted custom layout for the marker infoWindow to add a ‘route’ icon alongwith the location label. Here’s how I did that:


 //adapter for custom info-window - added icon for navigation
 supportMap.setInfoWindowAdapter(new InfoWindowAdapter() {

 @Override
 public View getInfoWindow(Marker arg0) {
 // TODO Auto-generated method stub
 return null;
 }

 @Override
 public View getInfoContents(Marker arg0) {
 // TODO Auto-generated method stub
 // Getting view from the layout file info_window_layout
 View v = getLayoutInflater().inflate(R.layout.info_window_layout, null);

 // Getting reference to the TextView to set title
 TextView note = (TextView) v.findViewById(R.id.note);

 note.setText(arg0.getTitle() ); //sets marker title

 // Returning the view containing InfoWindow contents
 return v;
 }
 });

Note the R.layout.info_window_layout in getInfoContents method. That’s the layout file for the marker custom infoWindow – loaded with a TextView and an icon.

The layout is now ready – Next step was to implement navigation feature via Googel Maps App i.e. when user would click on the marker, it should open Google Maps application with marker pointed at that location. The functionality of  ‘Route’ / Navigation already exists in Google Maps app. Android provides option for GeoIntents – Intents that open Google maps app automatically. You just pass that intent with Longitude, Latitude and Label as parameters – Rest it handles itself. So in  setOnInfoWindowClickListener, I first got Title, Longitude and Latitude values for that marker and then passed that with GeoIntent. The GeoIntent URI format is: geo:0,0?q=lat,lng(label)  – This is how i did that:

Map.setOnInfoWindowClickListener(new OnInfoWindowClickListener() {
 public void onInfoWindowClick(Marker marker) {
 LatLng position = marker.getPosition();
 Intent navigateIntent = new Intent(Intent.ACTION_VIEW);

 String currentLat = String.valueOf(position.latitude);  //Get Lat value
 String currentLong = String.valueOf(position.longitude);  //Get Long value
 String currLabel = marker.getTitle();  //Get Title of Location

 //Format URI as per required format which is > geo:0,0?q=lat,lng(label)
 String geoLocation = "geo:0,0?q=" + currentLat + "," + currentLong + "(" + currLabel + ")";
 navigateIntent.setData(Uri.parse(geoLocation));
 startActivity(navigateIntent);

 }
 });

The complete code for Map feature can be found here: https://github.com/shumail92/GCA-Android/blob/~gca/map/MapActivity.java

Following are the screenshots of map activity:

maps_module_screenshot

 

Tabbed layout for AbstractContent Activity

The app is also supposed to have ‘Notes’ Section for Abstracts so user can take note against some particular Abstract. But before implementation of Notes section, I had to do something with Layout of AbstractContent Activity for making space for Notes. I did a lot of research on it and the only good solution was to implement tabbed layout with ViewPager and Fragments. 

Uptill now, I had never worked with Fragments so I was little confused and this was a challenging task. Thanks to the Documentation and Androidhive guy, he has a great tutorial on Viewpager and Fragments, I finally managed to convert the AbstractContent Activity into Viewpager with 2 Fragments layout.

The new structure goes something like this: AbstractContent Activity is now parent activity that hosts the ViewPager. ViewPager hosts Tabbed layout with 2 Tabs and 2 Fragments respectively via custom FragmentPagerAdapter (Needed to override some methods ). AbstractContentTabFragment is the fragment for the default tab and shows all the Abstract Content just like it used to in previous activity. The other Fragment is AbstractNotesFragment which is for the 2nd tab i.e ‘Notes’.

I won’t go into detail of code for each of these but here is the link for the commit where I converted the Activity into Viewpager and Fragments. abf8cdfbefa806348058afcd857c9376bfa63fa4

If you have any question about the code or related, feel free to ask in comments and do share your thoughts and feedback on it in comments below. I’ll be looking forward to any suggestions or feedback.

GSoC Week # 7 – (30 June 2014 – 06 July 2014)