
<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Mobile Applications &#38; Services Lab &#187; Blog</title>
	<atom:link href="http://masl.cis.gvsu.edu/category/our-blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://masl.cis.gvsu.edu</link>
	<description>Combining mobile technology, pervasive network services and social media...</description>
	<lastBuildDate>Tue, 09 Apr 2013 18:26:14 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.5</generator>
		<item>
		<title>iOS or Android?</title>
		<link>http://masl.cis.gvsu.edu/2013/04/08/ios-or-android/</link>
		<comments>http://masl.cis.gvsu.edu/2013/04/08/ios-or-android/#comments</comments>
		<pubDate>Mon, 08 Apr 2013 12:43:59 +0000</pubDate>
		<dc:creator>Vincent Sam</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1268</guid>
		<description><![CDATA[When I started out to explore mobile development, I was immediately drawn to the iOS mobile platform because I owned several generations of iPhone models. iOS seemed perfect to me because I used a variety of iPhone apps that inspired me to investigate mobile development. However it wasn’t until I delved further into mobile development [...]]]></description>
				<content:encoded><![CDATA[<p>When I started out to explore mobile development, I was immediately drawn to the iOS mobile platform because I owned several generations of iPhone models. iOS seemed perfect to me because I used a variety of iPhone apps that inspired me to investigate mobile development. However it wasn’t until I delved further into mobile development that I quickly realized as a developer, that there was more to the basis of my preference than just the mobile device in my jeans pocket.</p>
<p style="text-align: left;" align="center"><b><i><strong><i>How To Effectively Compare Mobile App Platforms</i></strong></i></b></p>
<p>Some readers might already be aware of my master’s project, “<i>Creating Multiplatform Native App Support for Locating H1B Jobs</i>”. The project investigates the differences between the iOS and Android platforms from a developer&#8217;s perspective. My perspective was informed by the app I developed and deployed on both iTunes App Store and Google Play. Developing for both platforms gave me insight into questions a programmer needs to typically ponder over before making when assessing the pros and cons of a given platform. Some of the questions also originate from selected conversations with my classmates as well as discussions from my job interviews with top companies like Amazon and Compuware.</p>
<p style="text-align: left;" align="center"><strong><i>Learning Curve and Marketing Dominance</i></strong></p>
<p>These days it seems you can’t turn around without running into someone with either an iPhone or an Android mobile device. It is probably not surprising that Android and iOS accounted for 90% of all smartphone sales. Although Apple seems to be selling iPhones at a fast pace, Android continues to dominate the market. Android is leading the market sector with 47% share sales while iOS is breathing down the neck of Android with 43%. [1] Therefore we can confidently say Google’s Android is in high demand today, closely followed by Apple’s iPhone.</p>
<p>Aside from that, the learning curve for Android development is relatively <i>less steep</i> than iOS. For me, my prior background in Java programming made the transition to Android development much smoother. I was able to transfer my expertise in pure Java coding to working in the Droid platform. However iOS was rather challenging. Without any prior knowledge in C programming, self-instructed lessons in Objective-C require a high level of dedication. The iOS lectures videos available on Stanford iTunes can be very condensed. As a result, I occasionally consult an alternate, basic training material “<i>Beginning iOS5 Development </i>–<i> Exploring the iOS SDK</i>”[2] authored by Mark et al.</p>
<p style="text-align: left;" align="center"><strong><i>Similarities and Differences in iOS &amp; Android UX Design</i></strong></p>
<p>The user experience designs of both Android and iOS are alike. The touch gesture controls are very comparable. For instance certain gestures such as <i>tap, pinch, swipe, slide, flick, hold and drag, </i>and <i>double tap </i>offer identical actions on both iOS and Android devices. Although the design treatment and UI placement might vary, basic components such as <i>buttons</i>, <i>switches, checkboxes, pickers, tabs</i> and <i>sliders</i> also have very similar functionalities in both platforms. Moreover, for both iOS and Android platforms, particularly in task-based applications, it is common to see hierarchical tree-based menu format where user navigates the app through a series of lists to dive deeper into specific information within the app.</p>
<p>However, there are some differences in the user experience designs of both platforms that strongly dictate development in either environment. The iOS smartphones comes in 2 screen sizes and resolutions. Android, on the other hand, has 4 generalized sizes and resolutions (densities). Furthermore, the tab navigation placement in both platforms is complete opposites. The tab navigation of iOS is represented as a tab bar at the bottom of the app. Android suggests tab should be placed at the top of the app.</p>
<p style="text-align: left;" align="center"><strong><i>Pros and Cons of Each Development Environment</i></strong></p>
<p>Firstly, let us review the advantages of both development environments. Xcode for iOS platforms has storyboarding, which makes development very easy. The storyboards are nice for prototyping. The use of storyboard segues helps to identify navigation/modal relationships.  Xcode also has a user-friendly Model-View-Controller (MVC) oriented organization. The emulator for both Android and iOS platforms allow you to conveniently test apps on a device from the comfort of your computer.</p>
<p>Unfortunately it could be debated that as storyboards expand, it gets difficult to keep track of the navigation relationships within the app. It almost seems like a “<i>spaghetti</i>” code and could get a little frustrating. The Eclipse emulator could be extremely slow to start up. At some point, it maxed out my computer RAM. When an emulator starts, it takes quite a while for the apps to also load. A quick fix around this is to have an Android device if you intend to develop efficiently. Sadly, with Xcode, developers need to register their device before they can test on an iPhone.</p>
<p style="text-align: left;" align="center"><strong><i>The Application Deployment Model Between Apple and Google</i></strong></p>
<p>Google Play developer’s account costs $25, which is a one-time fee. However the iTunes App Store charges an annual fee of $99. Also, publishing an app on Google Play is very easy. Once the developer completes development, he simply uploads the apk file(s) and instantly publishes the app on Google Play. iTunes App Store on the other hand has a very tedious review process. A developer typically submits the binary files for review and approval by the App Review Team. This review process usually takes approximately 8 business days prior to an official launch of an app on the iTunes App Store. Finally, Android developers have a variety of deployment avenues such as Amazon App Store for Android and AppsZoom, formerly AndroidZoom.</p>
<p style="text-align: left;" align="center"><b><i>Conclusion</i></b></p>
<p>Personally, the choice between the 2 platforms, iOS and Android, would be a challenge. To some degree they both have unique strengths and weaknesses. It is safe to say that no one platform is a <i>universal solution. </i>I am a huge fan of the Xcode storyboards. For me, the simple drag, drop is fantastic. However, as a student, the $99 annual fee is an expensive cost especially when my app isn’t monetized. On the other hand, Android development makes things easy for developers just like me to deploy apps without a rigorous review process. My proficiency in Java has made the Android platform very appealing to me. But the only thing that bugs me is the complexity of manually specifying relative layouts when I drag and drop UI components on an Android canvas or layout. If I had to pick one at the end of the day, I would base my choice on the best tool that can help me accomplish the job or task I have been assigned.</p>

		<div class='author-shortcodes'>
			<div class='author-inner'>
				<div class='author-image'>
			<img src='http://masl.cis.gvsu.edu/wp-content/uploads/et_temp/samv-profile-picture-461563_57x57.png' alt='' />
			<div class='author-overlay'></div>
		</div> <!-- .author-image -->
		<div class='author-info'>
			Vincent Sam (aka Kobby) recently graduated with his MS from Grand Valley State University. This article was based on his experiences writing the H1B Jobs app on both the iOS and Android platforms. You can download both apps from the <a href="https://itunes.apple.com/us/app/h1b-jobs/id579035735?mt=8" target="_blank">iTunes App Store</a> or <a href="https://play.google.com/store/apps/details?id=edu.gvsu.cis.h1bjobs" target="_blank">Google Play</a>. Vincent currently works as a mobile app developer at Compuware in Detroit, MI.
		</div> <!-- .author-info -->
			</div> <!-- .author-inner -->
		</div> <!-- .author-shortcodes -->
<p><strong>References</strong></p>
<p>[1] Kim, R. (2012, January 9). IPhone Breathing Down Neck of Android in U.S. Retrieved December 14,<br />
2012, from GigaOm website: http://gigaom.com/2012/01/09/iphone-breathing-down-the-neck-of-<br />
android-in-u-s/<br />
[2] Mark, D., Nutting, J., &amp; LaMarche, J. (2011). Beginning iOS 5 Development: Exploring the iOS SDK.<br />
New York, NY: Springer Science and Business Media New York.</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2013/04/08/ios-or-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MASL Meetup: November 30, 3pm</title>
		<link>http://masl.cis.gvsu.edu/2012/11/29/masl-meetup-november-30-3pm-effective-software-development/</link>
		<comments>http://masl.cis.gvsu.edu/2012/11/29/masl-meetup-november-30-3pm-effective-software-development/#comments</comments>
		<pubDate>Thu, 29 Nov 2012 16:32:01 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1255</guid>
		<description><![CDATA[Effective Software Development We will be having a MASL Meetup on Friday afternoon, November 30, at 3pm in B1-118 Mackinac Hall on the Allendale Campus. Anybody in the GVSU community interested in mobile technology and/or software development in general are welcome to attend. Speaker: Sam Serpoosh &#8211; Sam is a passionate software developer and graduate [...]]]></description>
				<content:encoded><![CDATA[<p><strong>Effective Software Development</strong></p>
<p>We will be having a MASL Meetup on Friday afternoon, November 30, at 3pm in B1-118 Mackinac Hall on the Allendale Campus. Anybody in the GVSU community interested in mobile technology and/or software development in general are welcome to attend.</p>
<p><strong>Speaker</strong>: Sam Serpoosh &#8211; Sam is a passionate software developer and graduate student in GVSU&#8217;s School of Computing.  Sam works as a graduate assistant in the Mobile Apps &amp; Services lab. Sam gets into writing awesome software and is interested in all things agile. You can follow Sam&#8217;s blog on software craftmanship <a href="http://masihjesus.wordpress.com/">here</a>.</p>
<p><strong>Abstract</strong>: With always-changing requirements during the software development life cycle you need to be fast and responsive. However, the only way to go fast is to go WELL! If your code is a mess and you don&#8217;t have an efficient way to test your changes you’ll be afraid to touch it, and hence you won&#8217;t be going anywhere! As Steve Freeman and Nat Pryce put it: “Fear kills Progress!”. However, we can make the fear disappear with efficient programming and software development techniques! One of the most important practices of effective software development is Test Driven Development. In this talk we will discuss these issues and try to inspire attendees to think more agile by adopting test driven development practices.</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/11/29/masl-meetup-november-30-3pm-effective-software-development/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MASL Meetup on Wednesday 10/17/2012</title>
		<link>http://masl.cis.gvsu.edu/2012/10/15/masl-meetup-on-wednesday-10172012/</link>
		<comments>http://masl.cis.gvsu.edu/2012/10/15/masl-meetup-on-wednesday-10172012/#comments</comments>
		<pubDate>Mon, 15 Oct 2012 22:11:25 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1238</guid>
		<description><![CDATA[There will be a MASL Meetup this Wednesday afternoon at 2pm &#8211; 2:50, in B2-116 MAK. GVSU Faculty and students interested in mobile technology are welcome to attend this meetup. We will be presenting a couple of papers on past and ongoing MASL projects. J. Engelsma, F. Jumah, A. Montoya, J. Roth, V. Vasudevan, and [...]]]></description>
				<content:encoded><![CDATA[<p>There will be a MASL Meetup this Wednesday afternoon at 2pm &#8211; 2:50, in B2-116 MAK.   GVSU Faculty and students interested in mobile technology are welcome to attend this meetup.  We will be presenting a couple of papers on past and ongoing MASL projects. </p>
<p>J. Engelsma, F. Jumah, A. Montoya, J. Roth, V. Vasudevan, and G. Zavitz.  Shop Social: The Adventures of a Barcode Scanning App in the Wild.  Fourth International Conference on Mobile Computing, Applications and Services. October 11-12, 2012. Seattle, WA.</p>
<p>Abstract: Mobile retail is a space rich with plausible hypotheses but sparse on longitudinal datasets that give us a corpus of user behavior to validate or disprove theories around the use of digital devices in a physical store. Popular price comparison apps such as ShopSavvy have shown that a smartphone in the aisle is a reality that brick-and-mortar retailers have to contend with. A nuanced, data-driven understanding of a smartphone powered shopper might enable store-based retailers to leverage the smartphone rather than fear it as something that leads to sales erosion. To this end, we built and deployed a novel, mobile retail app that blends mobile, media and social capabilities. In this paper, we describe the user needs and design axioms behind the app, and the data that we’ve collected over the course of its use by about 5,500 users over the period of a year.</p>
<p>A. Restrepo, J. Engelsma, T. Parker and J. Farris.  Accessorized Therapeutic Games Experiences for Tablets. Meaningful Play 2012 Conference. October 18-20, 2012. East Lansing, MI. </p>
<p>Abstract: In the world of physical therapy, a number of consumer gaming devices have been used with various levels of success. Most commercially available video games are designed for the general population and are, in most cases, overwhelming and difficult for traumatic brain injury (TBI) or stroke patients to use.  Specialized therapeutic medical devices are not only expensive and non-portable, they also make limited use of gamification techniques to better engage and motivate the patient. This paper examines the use of inexpensive, portable handheld devices, together with a custom sensor accessory in order to drive a set of therapist designed and configured, short video games. Games have been designed that are intended to elicit specific therapeutic movements from the patient, are customizable by the therapist for a given patient’s needs, and also produce clinical output for the therapists to use.  The games have been evaluated in clinics by physical therapists who treat TBI patients, and the results indicate our approach addresses the shortcomings therapists have experienced with prior attempts at gamification in physical therapy.  Moreover, game controllability by the therapist has been identified as a key component in successfully gamifying treatment of TBI patients as it allows the therapist to customize the game experience to suit a patient’s individual needs. </p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/10/15/masl-meetup-on-wednesday-10172012/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A Summer Inside Microsoft</title>
		<link>http://masl.cis.gvsu.edu/2012/09/13/inside-microsoft-a-summer-on-windows-phone/</link>
		<comments>http://masl.cis.gvsu.edu/2012/09/13/inside-microsoft-a-summer-on-windows-phone/#comments</comments>
		<pubDate>Thu, 13 Sep 2012 15:23:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Featured]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1228</guid>
		<description><![CDATA[GVSU MASL graduate assistant Juan Mejia spent his summer working in Redmond for Microsoft. In particular, Juan worked on Microsoft&#8217;s Window Phone. On Friday, September 21 Juan will be giving a &#8220;MASL Meetup&#8221; talk on his experiences working at Microsoft. Juan will be sharing his internship experiences by talking about what its like to work [...]]]></description>
				<content:encoded><![CDATA[<p>GVSU MASL graduate assistant Juan Mejia spent his summer working in Redmond for Microsoft.  In particular, Juan worked on Microsoft&#8217;s Window Phone.  On Friday, September 21 Juan will be giving a &#8220;MASL Meetup&#8221; talk on his experiences working at Microsoft.  Juan will be sharing his internship experiences by talking about what its like to work at Microsoft and how a very large company builds and ships a product like Windows Phone.  The talk will also present some technical observations on Microsoft&#8217;s mobile platform and include some general information about Microsoft&#8217;s internship program.  We welcome all students, faculty and staff in the GVSU community who are interested in mobile technology to attend this presentation.</p>
<p>Where: B-1-118 Mackinac Hall (Allendale Campus)<br />
When: 3pm &#8211; 3:50pm, Friday September 21.</p>
<p>Note: No Microsoft confidential proprietary information will be presented! </p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/09/13/inside-microsoft-a-summer-on-windows-phone/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mobile Moves Michigan Event</title>
		<link>http://masl.cis.gvsu.edu/2012/07/18/the-mobile-moves-michigan-conference/</link>
		<comments>http://masl.cis.gvsu.edu/2012/07/18/the-mobile-moves-michigan-conference/#comments</comments>
		<pubDate>Wed, 18 Jul 2012 18:54:49 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Featured]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1185</guid>
		<description><![CDATA[Fellow Michiganders, are you interested in broadening your mobile tech horizons this summer?  If so, you&#8217;ll definitely not want to miss the upcoming Mobile Moves Michigan Conference @ The Motor City Casino in Detroit Michigan on July 30-31, 2012.  The event, hosted by the Mobile Technology Association of Michigan, includes the Mobile/Wireless Technology Symposium (7/31), [...]]]></description>
				<content:encoded><![CDATA[<p>Fellow Michiganders, are you interested in broadening your mobile tech horizons this summer?  If so, you&#8217;ll definitely not want to miss the upcoming Mobile Moves Michigan Conference @ The Motor City Casino in Detroit Michigan on July 30-31, 2012.  The event, hosted by the <a href="http://www.gomobilemichigan.org">Mobile Technology Association of Michigan</a>, includes the Mobile/Wireless Technology Symposium (7/31), a mobile developer conference and Hack-a-thon (7/30 &amp; 7/31) and mobile technology Exhibition (7/31). Learn about the Mobile Technology industry in Michigan and see how it affects all of us in business, government, education, insurance and literally every business vertical. Michigan is taking a leadership position in this field and our forward-looking strategy will be discussed at the Symposium. Your input is crucial for developing a well-structured plan of action for Michigan to be Engaged, Inspired and Enabled! What’s happening at the event?</p>
<p>&nbsp;</p>
<p><strong> July 31: Mobile / Wireless Technology Symposium</strong>: Leaders in government business, government, education, manufacturing, healthcare and other critical verticals will be exposed to local, national and international experts in various mobile / wireless sectors. Attendees will participate in a strategic planning session lead by industry leaders. Our objective is to develop a strategy that can be adopted and tailored for different organizations desiring to take advantage of mobile technologies. This collaboration is the first step for “Mobile Moves Michigan” to develop strategies for Michigan to take a national leadership role in the industry.</p>
<p><strong>July 31: Michigan Mobile / Wireless Technology Exhibition:</strong> Open to the general public, as well as invite-only symposium attendees, the Michigan Mobile / Wireless Technology Exhibition will enable attendees to view exhibits from Michigan-based firms currently providing and/or utilizing a variety of mobile / wireless technologies.</p>
<p><strong>July 30 and 31: WIPJam + Muther! of all Hack-a-thons:</strong> Produced by internationally renowned Wireless Industry Partnership (WIP), the WIPJam + Muther! of all Hack-a-thons is a mobile developer conference and hack-a-thon event which will provide education from, and direct access to, national and international companies in the mobile / wireless industry. Developers will receive training, access to resources, and one-on-one engagement with industry experts. Participants will have the opportunity to win prizes based on apps developed during the hack-a-thon portion of the program.</p>
<p>For more Information: <a href="http://www.mobilemovesmichigan.com ">http://www.mobilemovesmichigan.com</a></p>
<p>Symposium Information: <a href="mailto:info@GoMobileMichigan.org">info@GoMobileMichigan.org</a></p>
<p>Exhibition Information: <a href="http://www.gomobilemichigan.org/events/mobile-moves-michigan---request-to-exhibit.html">http://www.gomobilemichigan.org/events/mobile-moves-michigan&#8212;request-to-exhibit.html</a></p>
<p>Hack-a-thon Information: <a href="http://wipconnector.com/wipjam/entry/wipjam_muther_michigan">http://wipconnector.com/wipjam/entry/wipjam_muther_michigan</a></p>
<p><strong>Venue / Hotel Information:</strong><br />
Motor City Casino – Hotel<br />
2901 Grand River Ave<br />
Reservations: 866.782.9622 Request “Mobile Moves Michigan” Rate of $139</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/07/18/the-mobile-moves-michigan-conference/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MASL Meetup: Mobile App Dev</title>
		<link>http://masl.cis.gvsu.edu/2012/02/22/masl-meetup-mobile-app-development-compuware/</link>
		<comments>http://masl.cis.gvsu.edu/2012/02/22/masl-meetup-mobile-app-development-compuware/#comments</comments>
		<pubDate>Wed, 22 Feb 2012 19:37:21 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1161</guid>
		<description><![CDATA[On Thursday this week, mobile technologists from Compuware Corporation will be presenting their perspectives on mobile app development. They will talk about deciding factors for native vs web, hybrid app frameworks, and best practices for mobile technology in the enterprise. All GVSU students &#038; staff interested in mobile technology are encouraged to attend this presentation: [...]]]></description>
				<content:encoded><![CDATA[<p>On Thursday this week, mobile technologists from Compuware Corporation will be presenting their perspectives on mobile app development.  They will talk about deciding factors for native vs web, hybrid app frameworks, and best practices for mobile technology in the enterprise.  All GVSU students &#038; staff interested in mobile technology are encouraged to attend this presentation: </p>
<p><strong>When</strong>: 1pm &#8211; 1:50pm Thursday, February 23, 2012</p>
<p><strong>Where</strong>: B1-116 Mackinac Hall</p>
<p><strong>Note</strong>: Compuware will also be giving a <a href="http://www.cis.gvsu.edu/node/1871">public CIS seminar</a> on a related topic early in the day.  The MASL talk will be a deeper technical dive than the earlier presentation.  </p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/02/22/masl-meetup-mobile-app-development-compuware/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java Client for GAE Channels</title>
		<link>http://masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/</link>
		<comments>http://masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/#comments</comments>
		<pubDate>Tue, 31 Jan 2012 15:17:09 +0000</pubDate>
		<dc:creator>Tom Parker</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Technical Articles]]></category>
		<category><![CDATA[appengine]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=994</guid>
		<description><![CDATA[AppEngine Channels Google AppEngine Channels create a persistent connection between your client and the server running the Channel API Code. Information is passed between the two in real time without the use of polling, even between multiple clients, using the server as a mediator. For instance what if you wanted to create a Java client [...]]]></description>
				<content:encoded><![CDATA[<h1>AppEngine Channels</h1>
<p>Google AppEngine Channels create a persistent connection between your client and the server running the Channel API Code. Information is passed between the two in real time without the use of polling, even between multiple clients, using the server as a mediator. For instance what if you wanted to create a Java client to use these channels to receive push notifications from a server, or to push data to android devices without the use of sockets and worrying about port numbers. Playing a simple tic-tac-toe game over the internet could get complicated if there wasn’t a way for the other player to easily notify his opponent that a move had taken place. Well&#8230; you would have been out of luck. Up until now there wasn&#8217;t a way to use Java to do this using Google&#8217;s Channel API, it was just available in JavaScript. Luckily there is a solution to this, below is a simple framework that does just that. It allows you to utilize Google&#8217;s Channel API in Java.</p>
<h2>Framework Overview</h2>
<p><strong>Channel Creation</strong></p>
<p>The Client instantiates an instance of the ChannelAPI. The framework then requests a channel to be created with a given key that the user has chosen. The Server creates a channel with the provided key and returns a token which the client then uses to listen to the channel.</p>
<p><a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Channel-Framework-Overview.jpg"><img class="alignnone size-medium wp-image-1122" title="Channel Framework Overview" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Channel-Framework-Overview-300x151.jpg" alt="" width="300" height="151" /></a></p>
<p><strong>Message Sending</strong></p>
<p>The Client sends a message using its channel token. The Server receives the message and propagates it to all the other client channels with the same channel key.</p>
<p><a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Channel-Message.jpg"><img class="alignnone size-medium wp-image-1123" title="Channel Message" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Channel-Message-300x293.jpg" alt="" width="300" height="293" /></a></p>
<h2>Framework Details</h2>
<ul>
<li>Channel Creation</li>
<li>Client Side Message Sending</li>
<li>Server Side Message Sending</li>
</ul>
<p><strong>Channel Creation</strong></p>
<pre class="brush: java; gutter: true">ChatListener chatListener = new ChatListener();
ChannelAPI channel = new ChannelAPI(&quot;http://localhost:8888&quot;, &quot;key&quot;, chatListener);
channel.open();</pre>
<p>There are three main parts to creating a channel:</p>
<ul>
<li>Base URL</li>
<li>ChannelService class Implementation</li>
<li>Channel Key</li>
</ul>
<p>The <span style="text-decoration: underline;">Base URL</span> is the location of where your ChannelServer is stood up. In this example dealing with our ChatServer we are going to use  localhost, so our base URL ends up being &#8220;http://localhost:8888&#8243;</p>
<p>The <span style="text-decoration: underline;">ChannelService</span> class Implementation is just simply that. We need to create a class that implements the ChannelService interface class.</p>
<pre class="brush: java; gutter: true highlight: 4">package edu.gvsu.cis.masl.chat;
import edu.gvsu.cis.masl.channelAPI.ChannelService;

public class ChatListener implements ChannelService{</pre>
<p>In this example the &#8220;ChatListener&#8221; is our implementation of the ChannelService class. Methods from this class get called by the channel you are about to create. Of all the methods being called the one that is most relevant to our example would be the &#8216;onMessage&#8217;:</p>
<pre class="brush: java; gutter: true">/**
* Method gets called when the server sends a message.
 */
@Override
public void onMessage(String message) {
	System.out.println(&quot;Server push: &quot; + message);
}</pre>
<p>this method gets called when the server or other clients push messages to a channel with the same key that you are using.</p>
<p>The <span style="text-decoration: underline;">Channel Key</span> is just that, A key. You can use any string you want for it, but keep in mind that channels with the same key receive the same messages from the server. We&#8217;ll go into more detail on how the server sends messages to clients, but the highlighted line below shows how messages are sent using a Channel Key on the server side.</p>
<pre class="brush: java; gutter: true highlight: 9">public class ChatServlet extends HttpServlet {
  @Override
  public void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
    String channelKey = req.getParameter(&quot;channelKey&quot;);
    String message = req.getParameter(&quot;message&quot;);

    //Send a message based on the &#039;channelKey&#039; any channel with this key will receive the message
    ChannelService channelService = ChannelServiceFactory.getChannelService();
	channelService.sendMessage(new ChannelMessage(channelKey, message));
  }
}</pre>
<p>Every client gets a different channel, but clients can have similar keys.</p>
<p>Once the client has instantiated a ChannelAPI object the class does the rest of the work setting up the channel for you. The constructor calls the method &#8220;createChannel(channelKey)&#8221; and passes it the Channel Key you defined.</p>
<pre class="brush: java; gutter: true highlight: 4">public ChannelAPI(String URL, String channelKey, ChannelService channelService) throws IOException, ClientProtocolException {
    	this.clientId = null;
    	this.BASE_URL = URL;
    	this.channelId = createChannel(channelKey);
    	this.applicationKey = channelKey;

    	if (channelListener != null) {
            this.channelListener = channelService;
        }
    }</pre>
<p>The purpose createChannel() is to prompt the server to create a Channel for us and then send back a channel token. The channel token is what we use to communicate with our channel as well as the server and other clients.</p>
<pre class="brush: java; gutter: true highlight: 6">private String createChannel(String key) throws IOException, ClientProtocolException{
    	String token = &quot;&quot;;
		HttpClient staticClient = new DefaultHttpClient();
		HttpGet httpGet = new HttpGet(BASE_URL + &quot;/?c=&quot; + key);
		try{
			XHR xhr = new XHR(staticClient.execute(httpGet));
			System.out.println(xhr.getResponseText());
			JSONObject json = new JSONObject(xhr.getResponseText());
			token = json.getString(&quot;token&quot;);
		} catch (JSONException e) {
			System.out.println(&quot;Error: Parsing JSON&quot;);
		}
    	return token;
    }</pre>
<p><strong>Client Side Message Sending</strong></p>
<p>There are two main parts to sending a message from the client to the server:</p>
<ul>
<li>The Message</li>
<li>The Location</li>
</ul>
<div>The <span style="text-decoration: underline;">message</span> is any string you want to send, but the <span style="text-decoration: underline;">location</span> is where on the server it should be looking for that message. For example in our ChatExample we use the location &#8216;/chat&#8217; this means when the server gets a message at that location it knows how to handle it, because we are expecting clients to push messages to us there.</div>
<pre class="brush: java; gutter: true highlight: 7">/***
* Sends your message on the open channel
* @param message
*/
public void sendMessage(String message){
try {
		channel.send(message, &quot;/chat&quot;);
	} catch (IOException e) {
		System.out.println(&quot;Problem Sending the Message&quot;);
	}
}</pre>
<p>If you wanted to change where the server is looking for the messages you can change the &#8220;web.xml&#8221;:</p>
<pre class="brush: xml; gutter: true highlight: 21">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;web-app xmlns:xsi=&quot;http://www.w3.org/2001/XMLSchema-instance&quot;
xmlns=&quot;http://java.sun.com/xml/ns/javaee&quot;
xmlns:web=&quot;http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot;
xsi:schemaLocation=&quot;http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd&quot; version=&quot;2.5&quot;&gt;
	&lt;servlet&gt;
		&lt;servlet-name&gt;ChatChannelServlet&lt;/servlet-name&gt;
		&lt;servlet-class&gt;edu.gvsu.cis.masl.channel.ChatChannelServlet&lt;/servlet-class&gt;
	&lt;/servlet&gt;
	&lt;servlet-mapping&gt;
		&lt;servlet-name&gt;ChatChannelServlet&lt;/servlet-name&gt;
		&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
	&lt;/servlet-mapping&gt;
  &lt;servlet&gt;
    &lt;servlet-name&gt;ChatServlet&lt;/servlet-name&gt;
    &lt;servlet-class&gt;edu.gvsu.cis.masl.channel.ChatServlet&lt;/servlet-class&gt;
  &lt;/servlet&gt;
  &lt;servlet-mapping&gt;
    &lt;servlet-name&gt;ChatServlet&lt;/servlet-name&gt;
    &lt;url-pattern&gt;/chat&lt;/url-pattern&gt;
  &lt;/servlet-mapping&gt;
&lt;/web-app&gt;</pre>
<p>The &#8216;&lt;url-pattern&gt;&#8217; highlighted above is the line you would change, because the ChatServlet class is the one handling all of the messages from the clients. If you had different classes handling different types of client messages then you would change the appropriate lines in your &#8220;web.xml&#8221; to match your needs.</p>
<p><strong>Server Side Message Sending</strong></p>
<p><strong></strong>There are three main parts to sending a message on the server-side:</p>
<ul>
<li>ChannelService</li>
<li>The ChannelKey</li>
<li>The Message</li>
</ul>
<pre class="brush: java; gutter: true highlight: 2">//Send a message based on the &#039;channelKey&#039; any channel with this key will receive the message
ChannelService channelService = ChannelServiceFactory.getChannelService();
channelService.sendMessage(new ChannelMessage(channelKey, message));</pre>
<p>An instance of the<span style="text-decoration: underline;"> ChannelService</span> needs to be instantiated so we are able to pass a message through it. We instantiate it by grabbing an instance of the class from the ChannelServiceFactory. As seen in the highlighted line above. We then call the channelService.sendMessage() function and pass it an instance of a ChannelMessage. Seen below.</p>
<pre class="brush: java; gutter: true highlight: 3">//Send a message based on the &#039;channelKey&#039; any channel with this key will receive the message
ChannelService channelService = ChannelServiceFactory.getChannelService();
channelService.sendMessage(new ChannelMessage(channelKey, message));</pre>
<p>The ChannelMessage needs two things to send a message: One being the &#8216;<span style="text-decoration: underline;">Channel Key</span>&#8216; and the other being &#8216;<span style="text-decoration: underline;">The Message</span>&#8216;. You can either have the client push its channel key to you, or you can keep track of them in a hash table on your server. In the example code below, the client sends its &#8216;Channel Key&#8217; to the server, and then the server sends a message back to the client using the Channel Key. The &#8216;Message&#8217; can be anything from xml to json, as long as it can be converted to a string.<br />
<strong>***Updated: Production Issue Has Been Resolved. Thanks in large part to Dean Harding and Lohre.***</strong></p>
<p>The Source Code &amp; Framework can be found on GitHub: <a href="https://github.com/gvsumasl/jacc">https://github.com/gvsumasl/jacc</a> happy coding! <img src='http://masl.cis.gvsu.edu/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>

		<div class='author-shortcodes'>
			<div class='author-inner'>
				<div class='author-image'>
			<img src='http://masl.cis.gvsu.edu/wp-content/uploads/et_temp/TomParker-18848_57x57.png' alt='' />
			<div class='author-overlay'></div>
		</div> <!-- .author-image --> 
		<div class='author-info'>
			Tom Parker is currently working on his Masters Degree in Computer Science at Grand Valley State University. He completed his undergraduate studies in Computer Science at Michigan State University. He works as a Grad Assistant developing mobile phone applications in the GVSU Mobile Applications and Services Lab. When he&#8217;s not in the lab or busy doing homework, you can usually find him at the gym, but he also likes to dirt bike, snowboard, workout and run, as well as work on various programming projects of his own.
		</div> <!-- .author-info -->
			</div> <!-- .author-inner -->
		</div> <!-- .author-shortcodes -->
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/01/31/java-client-for-appengine-channels/feed/</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>Echoprint for Android</title>
		<link>http://masl.cis.gvsu.edu/2012/01/25/android-echoprint/</link>
		<comments>http://masl.cis.gvsu.edu/2012/01/25/android-echoprint/#comments</comments>
		<pubDate>Wed, 25 Jan 2012 14:34:05 +0000</pubDate>
		<dc:creator>Alex Restrepo</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Demos]]></category>
		<category><![CDATA[Featured]]></category>
		<category><![CDATA[Technical Articles]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[Audio Fingerprinting]]></category>
		<category><![CDATA[Echoprint]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=1053</guid>
		<description><![CDATA[I recently had the opportunity to work in Motorola Mobility&#8217;s Betaworks Lab as an intern, it was a great learning experience. One of my projects there was the inspiration for this project: get to run the audio fingerprinting library on an Android device. Echoprint (http://echoprint.me) is an open source C++ fingerprinting library that is available [...]]]></description>
				<content:encoded><![CDATA[<p>I recently had the opportunity to work in Motorola Mobility&#8217;s Betaworks Lab as an intern, it was a great learning experience. One of my projects there was the inspiration for this project: get to run the audio fingerprinting library on an Android device.</p>
<p>Echoprint (<a href="http://echoprint.me">http://echoprint.me</a>) is an open source C++ fingerprinting library that is available for desktop computers and iOS devices, however, as far as I know, there isn’t an Android-compatible version, until now <img src='http://masl.cis.gvsu.edu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>This article is divided into 3 steps, the first one is how to compile the Echoprint C++ code as an Android native library, the second one on how build a reusable Android fingerprinting library project, and finally, step 3 is how to put everything together in your own projects, so without further ado, let’s get started.</p>
<p><strong>Creating the Android native library.<br />
</strong>The codegen library does all the heavy lifting, it actually processes the audio samples and generates a set of hashes that are the actual audio fingerprint.</p>
<p>For this step you will need:</p>
<p>- Android’s NDK (r6 or better)</p>
<p>- Echoprint codegen source, available at <a href="https://github.com/echonest/echoprint-codegen">https://github.com/echonest/echoprint-codegen</a><br />
Once you download the project, go to the src folder and rename all .cxx files to .cpp, this is necessary as the NDK doesn’t accept files with .cxx extension. Move the downloaded folder (echonest-echoprint-codegen-v4.11-45-g7bc4764 or something similar) to a new folder (I named it jni) and rename it “codegen” or whatever makes sense to you</p>
<p>- Boost C++ libraries src (<a href="http://www.boost.org">http://www.boost.org</a>/) and add the boost_1_XX_X folder to the jni folder (I used version 1.47.0)</p>
<p>Now fire up Eclipse and create a new Android project, I used “EchoprintLib” as the name of the project, but you can use anything you like.<br />
In order to use a native library, some jni code needs to be written, as well as glue java code to invoke the jni code. Create a new java class, I used Codegen.java and declare the following native method:</p>
<pre class="brush: java; gutter: true">native String codegen(float data[], int numSamples);</pre>
<p>Your class should look like this:</p>
<pre class="brush: java; gutter: true">public class Codegen
{
	native String codegen(float data[], int numSamples);
}</pre>
<p>Save your changes as we will need the compiled .class file.<br />
Now, navigate to the bin folder of your project and run the javah tool, this tool will generate the required .h file needed to implement the native jni code.</p>
<pre class="brush: shell; gutter: true">alex$ javah edu.gvsu.masl.echoprint.Codegen</pre>
<p>Once it finishes, you will see a edu_gvsu_masl_echoprint_Codegen.h file that was generated, move this file to your jni folder.</p>
<p>Now it’s time to write the actual jni code that will invoke the codegen library and will return the results to our java library.</p>
<p>Create a new C++ file AndroidCodegen.cpp and add the following code:</p>
<pre class="brush: cpp; gutter: true">#include &lt;android/log.h&gt;
#include &lt;string.h&gt;
#include &lt;jni.h&gt;
#include &quot;edu_gvsu_masl_echoprint_Codegen.h&quot;
#include &quot;codegen/src/Codegen.h&quot;

JNIEXPORT jstring JNICALL Java_edu_gvsu_masl_echoprint_Codegen_codegen
  (JNIEnv *env, jobject thiz, jfloatArray pcmData, jint numSamples)
{
    // get the contents of the java array as native floats
	float *data = (float *)env-&gt;GetFloatArrayElements(pcmData, 0);

    // invoke the codegen
	Codegen c = Codegen(data, (unsigned int)numSamples, 0);
	const char *code = c.getCodeString().c_str();

    // release the native array as we&#039;re done with them
	env-&gt;ReleaseFloatArrayElements(pcmData, data, 0); 

    // return the fingerprint string
	return env-&gt;NewStringUTF(code);
}</pre>
<p>The actual signature of the codegen function is machine generated by the javah tool, in the edu_gvsu_masl_echoprint_Codegen.h file.</p>
<p>We now have all the necessary code to compile the codegen code as an Android native library, however the NDK requires two more files in order to build the code: the Android.mk and Application.mk files.</p>
<p>Create a new text file and name it Android.mk, this file is the equivalent of a makefile for the NDK, it contains the list of files needed as well as other parameters used by the NDK. Add the following to the Android.mk file:</p>
<pre class="brush: shell; gutter: true">LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

LOCAL_MODULE    :=echoprint-jni

LOCAL_SRC_FILES :=AndroidCodegen.cpp \
			/codegen/src/Codegen.cpp \
			/codegen/src/Whitening.cpp \
			/codegen/src/SubbandAnalysis.cpp \
			/codegen/src/MatrixUtility.cpp \
			/codegen/src/Fingerprint.cpp \
			/codegen/src/Base64.cpp \
			/codegen/src/AudioStreamInput.cpp \
			/codegen/src/AudioBufferInput.cpp

LOCAL_LDLIBS    :=-llog\
		-lz
LOCAL_C_INCLUDES :=&lt;path to your jni folder&gt;/codegen/src \
			&lt;path to your jni folder&gt;/boost_1_47_0				

include $(BUILD_SHARED_LIBRARY)</pre>
<p>In the LOCAL_C_INCLUDES line, make sure you replace the &lt;path to your jni folder&gt; placeholder with your actual path to the jni folder.</p>
<p>Create a new text file, Application.mk and add the following line:</p>
<pre class="brush: shell; gutter: true">APP_STL := gnustl_static</pre>
<p>Basically, all this file does is enable STL support in the NDK compiler.</p>
<p>Your jni folder should now look similar to this:<a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen1.png"><img class="alignnone size-full wp-image-1073" title="Screen1" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen1.png" alt="" width="413" height="125" /></a></p>
<p>If everything looks good, fire up a terminal window and run the ndk-build tool, from within your jni folder:</p>
<pre class="brush: shell; gutter: true">$ &lt;path to your ndk&gt;/ndk-build</pre>
<p>if everything goes well you should see something similar to this:</p>
<pre class="brush: shell; gutter: false">Compile++ thumb  : echoprint-jni &lt;= AndroidCodegen.cpp
Compile++ thumb  : echoprint-jni &lt;= Codegen.cpp
Compile++ thumb  : echoprint-jni &lt;= Whitening.cpp
Compile++ thumb  : echoprint-jni &lt;= SubbandAnalysis.cpp
Compile++ thumb  : echoprint-jni &lt;= MatrixUtility.cpp
Compile++ thumb  : echoprint-jni &lt;= Fingerprint.cpp
Compile++ thumb  : echoprint-jni &lt;= Base64.cpp
Compile++ thumb  : echoprint-jni &lt;= AudioStreamInput.cpp
Compile++ thumb  : echoprint-jni &lt;= AudioBufferInput.cpp
Prebuilt       : libstdc++.a &lt;= &lt;NDK&gt;/sources/cxx-stl/gnu-libstdc++/libs/armeabi/
SharedLibrary  : libechoprint-jni.so
Install        : libechoprint-jni.so =&gt; libs/armeabi/libechoprint-jni.so</pre>
<p>The freshly built native library now resides in a “libs” folder next to your jni folder:<br />
<a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen2.png"><img class="alignnone size-full wp-image-1075" title="Screen2" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen2.png" alt="" width="202" height="46" /></a></p>
<p>Go ahead and copy the libs folder into your EchoprintLib project folder.<br />
<a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen3.png"><img class="alignnone size-full wp-image-1076" title="Screen3" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen3.png" alt="" width="617" height="168" /></a></p>
<p>We can now write the rest of the glue code from the java side, open your EchoprintLib project and select the Codegen.java file.</p>
<p>In order to use the native library we need to load it, we just need to do this one time, when the class is loaded. To do so we add a static block that loads the library:</p>
<pre class="brush: java; gutter: true">static
{
	System.loadLibrary(&quot;echoprint-jni&quot;);
}</pre>
<p>As it turns out, the codegen code expects the audio samples to be floats in the [-1, 1] range, however, Android records audio samples as 16 bit shorts. The solution is simply to normalize the audio before is sent to the native library, to do so we define a normalizing value:</p>
<pre class="brush: java; gutter: true">private final float normalizingValue = Short.MAX_VALUE;</pre>
<p>Finally, the actual generate method will normalize the audio samples and then invoke the  codegen native method:</p>
<pre class="brush: java; gutter: true">public String generate(short data[], int numSamples)
{
	float normalizeAudioData[] = new float[numSamples];
	for (int i = 0; i &lt; numSamples - 1; i++)
		normalizeAudioData[i] = data[i] / normalizingValue;

	return this.codegen(normalizeAudioData, numSamples);
}</pre>
<p>For completeness, I’m adding an overloaded method that expects already normalized values as floats:</p>
<pre class="brush: java; gutter: true">public String generate(float data[], int numSamples)
{
	return codegen(data, numSamples);
}</pre>
<p>This is the complete Codegen class:</p>
<pre class="brush: java; gutter: true">package edu.gvsu.masl.echoprint;

public class Codegen
{
	private final float normalizingValue = Short.MAX_VALUE;

	native String codegen(float data[], int numSamples);

	static
	{
        	System.loadLibrary(&quot;echoprint-jni&quot;);
    	}

	/**
	 * Invoke the echoprint native library and generate the fingerprint code.&lt;br&gt;
	 * Echoprint REQUIRES PCM encoded audio with the following parameters:&lt;br&gt;
	 * Frequency: 11025 khz&lt;br&gt;
	 * Data: MONO - PCM enconded float array
	 *
	 * @param data PCM encoded data as floats [-1, 1]
	 * @param numSamples number of PCM samples at 11025 KHz
	 * @return The generated fingerprint as a compressed - base64 string.
	 */
	public String generate(float data[], int numSamples)
	{
		return codegen(data, numSamples);
	}

	/**
	 * Invoke the echoprint native library and generate the fingerprint code.&lt;br&gt;
	 * Since echoprint requires the audio data to be an array of floats in the&lt;br&gt;
	 * range [-1, 1] this method will normalize the data array transforming the&lt;br&gt;
	 * 16 bit signed shorts into floats.
	 *
	 * @param data PCM encoded data as shorts
	 * @param numSamples number of PCM samples at 11025 KHz
	 * @return The generated fingerprint as a compressed - base64 string.
	 */
	public String generate(short data[], int numSamples)
	{
		float normalizeAudioData[] = new float[numSamples];
		for (int i = 0; i &lt; numSamples - 1; i++)
			normalizeAudioData[i] = data[i] / normalizingValue;

		return this.codegen(normalizeAudioData, numSamples);
	}
}</pre>
<p>All the code needed to invoke the codegen native library is now in place, let’s now start step 2 and turn the project into a library and add a class that records audio from the microphone and returns its fingerprint.</p>
<p><strong>Turning the project into a reusable library<br />
</strong>This is actually pretty simple, all we need to do is go to the properties of the project, and under the Android category, check the appropriate “Is Library” checkbox:<br />
<a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen4.png"><img class="alignnone size-full wp-image-1077" title="Screen4" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen4.png" alt="" width="670" height="338" /></a></p>
<p>Your project can now be used as a library for other projects to use, let’s now add some code to take care of the audio recording and returning the results back to the client code.</p>
<p>First, let’s define an interface to communicate the results (or problems) back to whatever code is using the fingerprinter. My background is in iOS so you’ll find that the name of the methods closely resemble iOS delegate method names, but you can rename them to whatever you like:</p>
<pre class="brush: java; gutter: true">/**
 * Interface for the fingerprinter listener&lt;br&gt;
 * Contains the different delegate methods for the fingerprinting process
 * @author Alex Restrepo
 *
 */
public interface AudioFingerprinterListener
{
	/**
	 * Called when the fingerprinter process loop has finished
	 */
	public void didFinishListening();

	/**
	 * Called when a single fingerprinter pass has finished
	 */
	public void didFinishListeningPass();

	/**
	 * Called when the fingerprinter is about to start
	 */
	public void willStartListening();

	/**
	 * Called when a single listening pass is about to start
	 */
	public void willStartListeningPass();

	/**
	 * Called when the codegen libary generates a fingerprint code
	 * @param code the generated fingerprint as a zcompressed, base64 string
	 */
	public void didGenerateFingerprintCode(String code);

	/**
	 * Called if the server finds a match for the submitted fingerprint code
	 * @param table a hashtable with the metadata returned from the server
	 * @param code the submited fingerprint code
	 */
	public void didFindMatchForCode(Hashtable&lt;String, String&gt; table, String code);

	/**
	 * Called if the server DOES NOT find a match for the submitted fingerprint code
	 * @param code the submited fingerprint code
	 */
	public void didNotFindMatchForCode(String code);

	/**
	 * Called if there is an error / exception in the fingerprinting process
	 * @param e an exception with the error
	 */
	public void didFailWithException(Exception e);
}</pre>
<p>Now, let’s create an AudioFingerprinter class, and define a few keys to extract the metadata returned from the echoprint server:</p>
<pre class="brush: java; gutter: true">public final static String META_SCORE_KEY = &quot;meta_score&quot;;
public final static String SCORE_KEY = &quot;score&quot;;
public final static String ALBUM_KEY = &quot;release&quot;;
public final static String TITLE_KEY = &quot;track&quot;;
public final static String TRACK_ID_KEY = &quot;track_id&quot;;
public final static String ARTIST_KEY = &quot;artist&quot;;</pre>
<p><strong>NOTE:</strong> the metadata dictionary IS NOT included by default in the echoprint server API, to add it, just replace line 66/67 in API.py with:</p>
<pre class="brush: python; gutter: true">return json.dumps({&quot;ok&quot;:True,&quot;message&quot;:response.message(), &quot;match&quot;:response.match(), &quot;score&quot;:response.score, \
&quot;qtime&quot;:response.qtime, &quot;track_id&quot;:response.TRID, &quot;total_time&quot;:response.total_time, &quot;metadata&quot;:response.metadata})</pre>
<p>Then let’s declare some constants for our audio settings, as the codegen requires the audio to be uncompressed PCM, mono @ 11Khz:</p>
<pre class="brush: java; gutter: true">private final int FREQUENCY = 11025;
private final int CHANNEL = AudioFormat.CHANNEL_IN_MONO;
private final int ENCODING = AudioFormat.ENCODING_PCM_16BIT;</pre>
<p>With these constants in place, we can now initialize the audio recorder and start listening for audio:</p>
<pre class="brush: java; gutter: true">// create the audio buffer
// get the minimum buffer size
int minBufferSize = AudioRecord.getMinBufferSize(FREQUENCY, CHANNEL, ENCODING);

// and the actual buffer size for the audio to record
// frequency * seconds to record.
bufferSize = Math.max(minBufferSize, this.FREQUENCY * this.secondsToRecord);

audioData = new short[bufferSize];

// start recorder
mRecordInstance = new AudioRecord(MediaRecorder.AudioSource.MIC,
					FREQUENCY, CHANNEL,
					ENCODING, minBufferSize);

mRecordInstance.startRecording();</pre>
<p>At this point the audio recording has started, in this loop we extract the audio samples,  invoke the codegen class to extract their fingerprint and submit the fingerprint to your own echoprint server in order to get the metadata of the fingerprinted audio. The results are then forwarded to the client code, via an interface, as a hashtable.</p>
<p>I have defined a <em>continuous</em> variable to allow the class to listen for audio continuously, if it’s set to true, the loop will be repeated until the stop method is called in the AudioFingerprinter instance:</p>
<pre class="brush: java; gutter: true">do
{
	try
	{
		// fill audio buffer with mic data.
		int samplesIn = 0;
		do
		{
			samplesIn += mRecordInstance.read(audioData, samplesIn, bufferSize - samplesIn);

			if(mRecordInstance.getRecordingState() == AudioRecord.RECORDSTATE_STOPPED)
				break;
		}
		while (samplesIn &lt; bufferSize);				

		// create an echoprint codegen wrapper and get the code
		Codegen codegen = new Codegen();
		String code = codegen.generate(audioData, samplesIn);

		if(code.length() == 0)
		{
			// no code?
			// not enough audio data?
			continue;
		}

		// fetch data from echoprint server
		String urlstr = SERVER_URL + code;
		HttpClient client = new DefaultHttpClient();
		HttpGet get = new HttpGet(urlstr);

		// get response
		HttpResponse response = client.execute(get);
	    	// Examine the response status
		Log.d(&quot;Fingerprinter&quot;,response.getStatusLine().toString());

		// Get hold of the response entity
		HttpEntity entity = response.getEntity();
		// If the response does not enclose an entity, there is no need
		// to worry about connection release

		String result = &quot;&quot;;
		if (entity != null)
		{
			// A Simple JSON Response Read
			InputStream instream = entity.getContent();
			result= convertStreamToString(instream);
			// now you have the string representation of the HTML request
			instream.close();
		}	     			

	    	// parse JSON
		JSONObject jobj = new JSONObject(result);
		if(jobj.has(&quot;match&quot;))
		{
			if(jobj.getBoolean(&quot;match&quot;))
			{
				Hashtable&lt;String, String&gt; match = new Hashtable&lt;String, String&gt;();
				match.put(SCORE_KEY, jobj.getDouble(SCORE_KEY) + &quot;&quot;);
				match.put(TRACK_ID_KEY, jobj.getString(TRACK_ID_KEY));

				if(jobj.has(&quot;metadata&quot;))
		    		{
					JSONObject metadata = jobj.getJSONObject(&quot;metadata&quot;);
			    		if(metadata.has(SCORE_KEY)) match.put(META_SCORE_KEY, metadata.getDouble(SCORE_KEY) + &quot;&quot;);
					if(metadata.has(TITLE_KEY)) match.put(TITLE_KEY, metadata.getString(TITLE_KEY));
					if(metadata.has(ARTIST_KEY)) match.put(ARTIST_KEY, metadata.getString(ARTIST_KEY));
					if(metadata.has(ALBUM_KEY)) match.put(ALBUM_KEY, metadata.getString(ALBUM_KEY));
		    		}

		    		didFindMatchForCode(match, code);
			}
			else
				didNotFindMatchForCode(code);
		}
		firstRun = false;

	}
	catch(Exception e)
	{
		e.printStackTrace();
		Log.e(&quot;Fingerprinter&quot;, e.getLocalizedMessage());
	}
}
while (this.continuous);</pre>
<p>We now have a complete library that can listen to audio, invoke the codegen native library and return the computed fingerprint back to your code.</p>
<p>The final step is then create a sample project that uses the completed code library.</p>
<p><strong>Creating a sample project that uses the library<br />
</strong>Create a new project in eclipse, I chose EchoprintTest as its name, and in its properties, go to the Android category and add the EchoprintLib library to the project:<br />
<a href="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen5.png"><img class="alignnone size-full wp-image-1078" title="Screen5" src="http://masl.cis.gvsu.edu/wp-content/uploads/2012/01/Screen5.png" alt="" width="397" height="190" /></a></p>
<p>In this sample project, I added a button (recordButton) and a TextView (status) to the main Activity, in order to start/stop the audio fingerprinting process and to display the results from the echoprint server.</p>
<p>In the main activity, we need to implement the AudioFingerprinterListener interface:</p>
<pre class="brush: java; gutter: true">public class EchoprintTestActivity extends Activity implements AudioFingerprinterListener
...
public void didFinishListening()
{
	btn.setText(&quot;Start&quot;);

	if(!resolved)
		status.setText(&quot;Idle...&quot;);

	recording = false;
}

public void didFinishListeningPass()
{}

public void willStartListening()
{
	status.setText(&quot;Listening...&quot;);
	btn.setText(&quot;Stop&quot;);
	recording = true;
	resolved = false;
}

public void willStartListeningPass()
{}

public void didGenerateFingerprintCode(String code)
{
	status.setText(&quot;Will fetch info for code starting:\n&quot; + code.substring(0, Math.min(50, code.length())));
}

public void didFindMatchForCode(final Hashtable&lt;String, String&gt; table,
		String code)
{
	resolved = true;
	status.setText(&quot;Match: \n&quot; + table);
}

public void didNotFindMatchForCode(String code)
{
	resolved = true;
	status.setText(&quot;No match for code starting with: \n&quot; + code.substring(0, Math.min(50, code.length())));
}

public void didFailWithException(Exception e)
{
	resolved = true;
	status.setText(&quot;Error: &quot; + e);
}</pre>
<p>In order to start the fingerprinting process, all we need to do is create an instance of the AudioFingerprinter class and call the fingerprint method, specifying how many seconds of audio to record per listening pass, the maximum is 30 and the minimum is 10. I’ve found out that for better results, anything above 15 should work fine:</p>
<pre class="brush: java; gutter: true">btn = (Button) findViewById(R.id.recordButton);
btn.setOnClickListener(new View.OnClickListener()
{
    public void onClick(View v)
    {
    	if(recording)
    	{
		fingerprinter.stop();
    	}
    	else
    	{
    		if(fingerprinter == null)
    			fingerprinter = new AudioFingerprinter(EchoprintTestActivity.this);

    		fingerprinter.fingerprint(15);
    	}
    }
});</pre>
<p>And voila, all you need to do now is do anything interesting with the results returned from the server in the <em>didFindMatchForCode</em> method!</p>
<p>One final thing though, don’t forget to add</p>
<pre class="brush: xml; gutter: true">&lt;uses-permission android:name=&quot;android.permission.RECORD_AUDIO&quot;/&gt;
&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot;/&gt;</pre>
<p>To your manifest file in order to enable audio recording and internet access!</p>
<p>Now go ahead and download the echoprint server, feed it with some audio files (check the documentation on how to do that) and start developing your own audio fingerprinting apps!</p>
<p>Download the complete source from GitHub repo: <a href="https://github.com/gvsumasl/EchoprintForAndroid" target="_blank">https://github.com/gvsumasl/EchoprintForAndroid</a>.</p>
<p>Happy coding!</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2012/01/25/android-echoprint/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>MASL Grad Students Presentations</title>
		<link>http://masl.cis.gvsu.edu/2011/12/13/masl-grad-students-presentations/</link>
		<comments>http://masl.cis.gvsu.edu/2011/12/13/masl-grad-students-presentations/#comments</comments>
		<pubDate>Tue, 13 Dec 2011 16:08:17 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[art]]></category>
		<category><![CDATA[gamification]]></category>
		<category><![CDATA[iOS]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=983</guid>
		<description><![CDATA[Two MASL graduate students will be presenting this Thursday morning in D-1-117 MAK during the scheduled graduate student presentations: Andres Solano (Master&#8217;s Project Presentation) When: 9:30 &#8211; 10:15am Title: GVSU Art Gallery Meets iOS: How To Cram 10k+ Works of Art Into Your Pocket Abstract: The Grand Valley State University Art Gallery has over ten thousand [...]]]></description>
				<content:encoded><![CDATA[<p>Two MASL graduate students will be presenting this Thursday morning in D-1-117 MAK during the scheduled graduate student presentations:</p>
<p><strong>Andres Solano</strong> (Master&#8217;s Project Presentation)</p>
<p><strong>When</strong>: 9:30 &#8211; 10:15am</p>
<p><strong>Title</strong>: GVSU Art Gallery Meets iOS: How To Cram 10k+ Works of Art Into Your Pocket</p>
<p><strong>Abstract</strong>: The Grand Valley State University Art Gallery has over ten thousand works of original art, including paintings, sculptures, ceramics, and more.  A large portion of this collection is displayed across GVSU&#8217;s campuses. These pieces of art are used by students for courses and research and are also simply enjoyed by people each day as they encounter them on campus.  Although each individual work has a placard describing it and its artist, these do not help people locate specific works of art around the different campuses and buildings. Furthermore, the amount of information that can be displayed on a work of art is limited to the size of the placard.  Another difficulty is that there is no way for a person to share or comment on a work of art that they really appreciate. This project addressed these problems by developing and deploying a mobile application that allows users to browse and locate works of art using their iPhone and its network connection and GPS capabilities.  Furthermore, users can use the application to go on virtual art tours, and they can interact with their friends around a piece of art via integration with Facebook, Twitter, and other social networks, all from their iPhone.</p>
<p><strong>Alex Restrepo</strong> (Masters Thesis Proposal)</p>
<p><strong>When</strong>: 10:30am &#8211; 11:15am</p>
<p><strong>Title</strong>: Accessorized Therapeutic Game Experiences for Touch-Enabled Devices</p>
<p><strong>Abstract</strong>: In the world of physical therapy, a number of consumer gaming devices have been used with various levels of success. Most commercially available video games are designed for the general population and are, in most cases, overwhelming and difficult for traumatic brain injury (TBI) or stroke patients to use.  Specialized therapeutic medical devices are not only expensive and non-portable, they also make limited use of gamification techniques to better engage and motivate the patient. This thesis aims to study the use of inexpensive, portable handheld devices, together with a custom sensor accessory in order to drive a set of therapist designed and configured, short video games. The games are intended to elicit specific therapeutic responses from the patient, and also produce clinical output for the therapists to assess the patient&#8217;s progress and refine the treatment regimen.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2011/12/13/masl-grad-students-presentations/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MASL Meetup &#8211; Mango Smoothie</title>
		<link>http://masl.cis.gvsu.edu/2011/11/09/masl-meetup-mango-smoothie-a-developer-overview/</link>
		<comments>http://masl.cis.gvsu.edu/2011/11/09/masl-meetup-mango-smoothie-a-developer-overview/#comments</comments>
		<pubDate>Wed, 09 Nov 2011 21:20:19 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[mango]]></category>
		<category><![CDATA[windows phone]]></category>

		<guid isPermaLink="false">http://masl.cis.gvsu.edu/?p=961</guid>
		<description><![CDATA[Title: Mango Smoothie &#8211; A Developer Overview When: Friday, November 11, 2pm-3pm Where: D2-168 MAK  (IT conference room) Who: Any GVSU faculty/students who are interested in mobile technology Abstract: This presentation will give an overview of Microsoft&#8217;s Windows Phone Mango.  We will talk about the tools/technologies used to develop for Windows Phone, and showcase the [...]]]></description>
				<content:encoded><![CDATA[<div id="attachment_963" class="wp-caption alignleft" style="width: 167px"><a href="http://masl.cis.gvsu.edu/wp-content/uploads/2011/11/WindowsPhone.png"><img class="size-medium wp-image-963" title="WindowsPhone" src="http://masl.cis.gvsu.edu/wp-content/uploads/2011/11/WindowsPhone-157x300.png" alt="" width="157" height="300" /></a><p class="wp-caption-text">Preview of the soon to be released Windows Phone edition of GVSU Laker Mobile.</p></div>
<p><strong>Title</strong>: Mango Smoothie &#8211; A Developer Overview</p>
<p><strong>When</strong>: Friday, November 11, 2pm-3pm</p>
<p><strong>Where</strong>: D2-168 MAK  (IT conference room)</p>
<p><strong>Who</strong>: Any GVSU faculty/students who are interested in mobile technology</p>
<p><strong>Abstract</strong>:</p>
<p>This presentation will give an overview of Microsoft&#8217;s Windows Phone Mango.  We will talk about the tools/technologies used to develop for Windows Phone, and showcase the controls available.  We will also discuss our experiences developing a Windows Phone edition of the GVSU Laker Mobile app in the mobile lab.  Our goal is to bring the audience up to date on Microsoft&#8217;s new Windows Phone platform. Attendees will gain a good overall understanding of the platform and how to get started developing for it.</p>
<p><strong>Speaker</strong>:  Juan Mejia is a graduate assistant in the GVSU Mobile Applications and Services Lab.  He previously graduated with his computer science degree from EAFIT University in Columbia.  Juan is interested in .NET and Silverlight development, and is a Microsoft Certified Professional.</p>
]]></content:encoded>
			<wfw:commentRss>http://masl.cis.gvsu.edu/2011/11/09/masl-meetup-mango-smoothie-a-developer-overview/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
