<?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>Do it yourself Android</title>
	<atom:link href="http://blog.doityourselfandroid.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.doityourselfandroid.com</link>
	<description>A blog about developing on the Android platform and much more</description>
	<lastBuildDate>Sat, 07 Apr 2012 17:33:58 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>PhoneGap &#8211; migrating iOS applications to Android (Part 1)</title>
		<link>http://blog.doityourselfandroid.com/2012/04/06/phonegap-migrating-ios-application-android/</link>
		<comments>http://blog.doityourselfandroid.com/2012/04/06/phonegap-migrating-ios-application-android/#comments</comments>
		<pubDate>Fri, 06 Apr 2012 21:18:09 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[PhoneGap]]></category>
		<category><![CDATA[css3]]></category>
		<category><![CDATA[htlm5]]></category>
		<category><![CDATA[mobile development]]></category>
		<category><![CDATA[phonegap]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=1134</guid>
		<description><![CDATA[In this post, I&#8217;ll be discussing the steps required to created an Android application using the PhoneGap framework. For those of you who don&#8217;t know, PhoneGap is an HTML5 app platform that allows you to author native applications with web technologies. So although we are generating a native Android application (APK file) that can be [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tr>
<td>
In this post, I&#8217;ll be discussing the steps required to created an Android application using the <a href="http://phonegap.com" target="_blank">PhoneGap framework</a>. For those of you who don&#8217;t know, PhoneGap is an HTML5 app platform that allows you to author native applications with web technologies. So although we are generating a native Android application (APK file) that can be put on Google Play, the actual views of our application will be made up by web pages, embedded in your native app in a WebView. </p>
<p>
PhoneGap promotes the idea of a single code-base (the part containing the html / javascript / stylesheets) where you use the PhoneGap platform to generate native packages for different mobile platforms like iOS, Android, &#8230;&#8230; There will always be a mobile platform specific part associated with a PhoneGap project, the native part, required to generate the mobile platform specific artifact (Android APK file, iOS IPA file,&#8230;.)
</p>
</td>
<td><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/phonegaplogosmall.png"></td>
</tr>
</table>
</div>
<h2><span id="more-1134"></span></h2>
<h2>The applications</h2>
<p>
Writing a fully featured cross platform app is beyond the scope of this particular blog post. Depending on the complexity of the app, and the target platforms that need to be supported, developing such an application can be very complex. In this blog post I will pick 2 very simple mobile webapps that were packaged using PhoneGap as native iOS applications. I&#8217;ll try to get a feel on the effort required to port them to the Android platform.
</p>
<p>
The idea behind this approach is to see how easy it is to have a truly cross-platform application with PhoneGap. After all, PhoneGap uses standard and common web technologies like html5 / css3 / jquery so it shouldn&#8217;t be that hard right ? </p>
<p><p>
The holy grail of development, where you <b>&#8220;write once&#8221;</b> and <b>&#8220;run anywhere&#8221;</b>.
</p>
<p>
Unfortunately things aren&#8217;t always as simple as that. From my own personal experience, it has been always been more along the lines of &#8220;write once&#8221;, &#8220;try to run anywhere&#8221;, &#8220;tweak your writings to get it to run anywhere&#8221;.
</p>
<p>
I&#8217;ll be using 2 PhoneGap applications that were originally targetting iOS, and see what it takes to convert them to Android. </p>
<ul>
<li>
<b>Room112</b> is a sample application created by Jesse Freeman, outlined in his excellent blog post entitled <a href="http://jessefreeman.com/articles/room112-phonegap-exploration/" target="_blank">&#8220;Room112 – PhoneGap Exploration&#8221;</a>. The full source code of the sample app created in his blog post can be found <a href="https://github.com/jessefreeman/Room112">on github</a>. Jesse created his application for iOS specifically, so we&#8217;ll now start porting it to Android.
</li>
<li>
The second sample is an <a href="http://coenraets.org/blog/2011/10/sample-app-using-the-phonegap-database-api/" target="_blank">Employee Directory application using using the PhoneGap Database API</a>. It is created by <a href="http://coenraets.org/blog/bio/" target="_blank">Christophe Coenraets</a>. Please checkout his blog for a lot of interesting posts on app development using web techniques.
</li>
</ul>
<p>
The source for this sample is still a work in progress, but you can already grab a copy on the <a href="https://github.com/ddewaele/PhoneGapAndroidConversion" target="_blank">PhoneGapAndroidConversion GitHub repository.</a></p>
<h2>The development environment</h2>
<p>
I&#8217;m going to be using Eclipse as my IDE. There are no PhoneGap specific plugins to install, but we obviously require the Android SDK and the ADT plugin to be installed to facilitate Android development.
</p>
<p>
I&#8217;m adding all the steps that are required to setup a new PhoneGap Android Project. You can also clone my <a href="https://github.com/ddewaele/PhoneGapAndroid" target="_blank">skeleton project for PhoneGap Android</a> if you don&#8217;t wan to perform the manual steps below. It sets up a basic PhoneGap skeleton project for Android with a simple webview.
</p>
<p>
We&#8217;ll start by creating a standard Android Project.
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/create_project.png"/></center></p>
<p>
We&#8217;ll be targeting the Android 4.0 platform (API level 14). This will allow us to configure hardwareAcceleration on the platforms that support it.
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/selectandroidtarget.png"/></center></p>
<h2>Hardware acceleration</h2>
<p>
In order to ensure that our application runs as smoothly as possible on Android, we&#8217;ll need to enable hardware acceleration where supported. The way hardware acceleration is enabled depends on the Android version you are running.
</p>
<ul>
<li>In Android 3.0 (Honeycomb API level 11) developers can choose to opt-in to the new hardware accelerated pipeline. It&#8217;s not enabled by default.</li>
<li>In Android 4.0 (API level 14), hardware acceleration is enabled by default for all applications </li>
</ul>
<p>
For applications running on lower API levels, you can turn it on by adding android:hardwareAccelerated=&#8221;true&#8221; to the <application> tag in your AndroidManifest.xml.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    package=&quot;com.ecs.phonegap.android.conversion&quot;
    android:versionCode=&quot;1&quot;
    android:versionName=&quot;1.0&quot; &gt;

    &lt;uses-sdk android:targetSdkVersion=&quot;14&quot; android:minSdkVersion=&quot;7&quot; /&gt;
	&lt;uses-permission android:name=&quot;android.permission.INTERNET&quot; /&gt;

    &lt;application
        android:icon=&quot;@drawable/ic_launcher&quot;
        android:label=&quot;@string/app_name&quot;
        android:hardwareAccelerated=&quot;true&quot;
        android:debuggable=&quot;true&quot;&gt;
....
    &lt;/application&gt;
&lt;/manifest&gt;
</pre>
</p>
<p>
As we want to target as many devices as possible (including pre-Honeycomb devices) while still make use of the new hardwareAcceleration option,  we&#8217;re going to set the <b>targetSDK</b> to level 14, and a <b>minSdkVersion</b> to 7 (Android 2.1).
</p>
<h2>The PhoneGap activity</h2>
<p>
We&#8217;ll let the Android Project wizard generate a default activity, so we already have that in place.
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/create_project2.png"/></center></p>
<p>
PhoneGap has an excellent <a href="http://phonegap.com/start">Getting Started Guide</a> where the different steps for the different mobile platforms are outlined. In case of Android, the following simple steps need to be executed.
</p>
<ul>
<li>Download PhoneGap from the PhoneGap website (<a href="https://github.com/phonegap/phonegap/zipball/1.5.0">direct link</a>)</li>
<li>Extract the PhoneGap zip file somewhere on your filesystem.</li>
<li>Create an /assets/www folder in your Android project</li>
<li>Create a /libs in your Android project</li>
<li>Copy cordova-1.x.x.js from your android directory of your PhoneGap download earlier to /assets/www</li>
<li>Copy cordova-1.x.x.jar from your android directory of your PhoneGap download earlier to /libs</li>
<li>Copy xml folder from your PhoneGap download earlier to /res</li>
</ul>
<p>For those that like to script this, just fill in the correct location of your eclipse project and phonegap download and execute the commands below :</p>
<pre class="brush: java;">
export ECLIPSE_PROJECT=/Users/ddewaele/Projects/workspace/Room12PhoneGapAndroid
export PHONEGAP_DOWNLOAD=/Users/ddewaele/Projects/PhoneGap/phonegap-phonegap-de1960d
mkdir $ECLIPSE_PROJECT/assets/www
mkdir $ECLIPSE_PROJECT/libs
cp  $PHONEGAP_DOWNLOAD/lib/android/cordova-1.5.0.js $ECLIPSE_PROJECT/assets/www/
cp  $PHONEGAP_DOWNLOAD/lib/android/cordova-1.5.0.jar $ECLIPSE_PROJECT/libs/
cp -r $PHONEGAP_DOWNLOAD/lib/android/xml $ECLIPSE_PROJECT/res/
</pre>
<p>We&#8217;ll need to add the cordova-1.5.0.jar file to the build path of our Android project.</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/add_cordoval_lib.png"/></center></p>
<p>With that into place, our app looks like this :</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/projectlayout.png"/></center></p>
<h2>Attaching the sources</h2>
<p>
If you want to get serious with PhoneGap development, having the PhoneGap sources attached to your project can help speed up debugging issues. The <a href="https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=summary" target="_blank">PhoneGap source code</a> is made available through Apache.
</p>
<p>
This sample is available in Github with all the libraries and sources properly setup. If you&#8217;re using the sample from the git repository there is no need to execute the steps below. I&#8217;ve just added them here for informational purposes.
</p>
<p>
We start by cloning the git repository containing the PhoneGap source code :
</p>
<pre class="brush: java;">
git clone https://git-wip-us.apache.org/repos/asf/incubator-cordova-android.git

Cloning into incubator-cordova-android...
remote: Counting objects: 10357, done.
remote: Compressing objects: 100% (3032/3032), done.
remote: Total 10357 (delta 5819), reused 9451 (delta 5299)
Receiving objects: 100% (10357/10357), 19.32 MiB | 243 KiB/s, done.
Resolving deltas: 100% (5819/5819), done.
Davys-MacBook-Air:PhoneGap ddewaele$ ls -ltr
total 0
</pre>
<p>
We then continue to switch to the current production tag,  1.5.0 :
</p>
<pre class="brush: java;">

cd incubator-cordova-android
git checkout tags/1.5.0
Note: checking out 'tags/1.5.0'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by performing another checkout.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -b with the checkout command again. Example:

  git checkout -b new_branch_name

HEAD is now at 8923e52... Adding support for legacy plugins
</pre>
<p>
Now that we&#8217;ve checked out the code, we can zip up the PhoneGap sources (located in framework/src) in a file called cordova-src.zip
</p>
<pre class="brush: java;">
cd /Users/ddewaele/Projects/PhoneGap/incubator-cordova-android/framework/src
zip cordova-1.5.0-src.jar -r *
</pre>
<p>
We&#8217;ll now attach this source file into our Eclipse project :
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/attach_cordova_source.png"/></center></p>
<h2>Starting the Room112 migration</h2>
<p>We&#8217;ll start by checking out the original sources of the Room112 application. The sources are located in Github and can be checked out from the command line like this:</p>
<pre class="brush: java;">
git clone https://github.com/jessefreeman/Room112
</pre>
<p>
If you have XCode installed, you can click on the xcodeproj file and open the project in XCode. After launching it on the iPhone simulator, you should see something like this :
</p>
<p>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_ios_room112.png"/></center>
</p>
<p>
The bulk of this git repository contains XCode specific files, files we&#8217;re not interested in. We&#8217;re only interested in the web files, located in <b>the www folder</b>. There are however a couple of things we need to take into account :
</p>
<ul>
<li>The Room112 iOS sample uses PhoneGap v1.3.0, while we are going to use the latest version available at the time of writing, v1.5.0.</li>
<li>We&#8217;ve stumbled upon our first issue that prevents us from making this example truly cross-platform. The Room112 iOS code contains an iOS specific phonegap-1.3.0.js file that cannot be used on Android. </li>
<li>The Android specific phonegap javascript file (called cordova-1.5.0.js) is located in the PhoneGap distribution we downloaded earlier. It is also available in my skeleton Github repo.</li>
</ul>
<h2>The JSON bug</h2>
<p>When we attempt to start the application for the first time on an Android 2.3.3 device, we are presented with the following screen :<br />
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/json_crash.png"/></center></p>
<p>
Besides the fact that the background image is not correctly aligned, the major issue here is that our app crashes, failing to show the hotel card.
</p>
<p>
When we look at the Webconsole logs we see this :
</p>
<pre class="brush: java;">
04-02 22:11:15.066: E/Web Console(13752): Uncaught illegal access at file:///android_asset/www/js/lawnchair-0.6.1.min.js:8
</pre>
<p>
The Room12 application uses a framework called <a href="http://westcoastlogic.com/lawnchair/" target="_blank">Lawnchair</a> as a replacement for html5 local storage. It promotes itself as being a lightweight, adaptive, simple and elegant persistence solution.
</p>
<p>
Unfortunately on our Android device, this is causing some problems. It&#8217;s not a problem with the framework as such, but rather related to a bug in the V8 JavaScript engine of the browser (WebView). The bug described <a href="http://code.google.com/p/android/issues/detail?id=11973" target="_blank">in the Android issue tracker.</a>.
</p>
<p>
Certain Android devices are having issues when a JSON.parse(null) call is executed. Instead of returning null, as most devices do, we are confronted with an uncaught illegal access in  the JSON object. </p>
<p><p>
We can workaround this issue by putting the following code on top of our javascript :
</p>
<pre class="brush: java;">
JSON.originalParse = JSON.parse;

JSON.parse = function(text){
	if (text) {
		return JSON.originalParse(text);
	} else {
		// no longer crashing on null value but just returning null
		return null;
	}
}
</pre>
<h2>Viewport properties</h2>
<p>On my Android 4.0.4 device, I noticed the following errors in the Web Console when launching the app. It seems that hte preferred way of seperating viewport arguments is a &#8220;comma&#8221;. More information on this can be found in the <a href="http://dev.w3.org/csswg/css-device-adapt/#viewport-properties" target="_blank">CSS Device Adaptation</a>.</p>
<pre class="brush: java;">
04-03 00:30:51.265: E/Web Console(21509): Viewport argument value &quot;device-width;&quot; for key &quot;width&quot; not recognized. Content ignored. at file:///android_asset/www/index.html:5
04-03 00:30:51.265: V/Web Console(21509): Viewport argument value &quot;1.0;&quot; for key &quot;initial-scale&quot; was truncated to its numeric prefix. at file:///android_asset/www/index.html:5
04-03 00:30:51.265: V/Web Console(21509): Viewport argument value &quot;0;&quot; for key &quot;user-scalable&quot; was truncated to its numeric prefix. at file:///android_asset/www/index.html:5
</pre>
<h2>Android Room112 screenshots</h2>
<p>The Room112 application was specifically designed for the iPhone and the nature of the app makes it ao that it doesn&#8217;t render well on different screen resolutions.</p>
<p>
By providing additional image resources we could optimizing the application for larger type screens. (although we won&#8217;t be covering that here.)
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_screenshot_gingerbread.png"/><br/><i>Samsung Galaxy S running Gingerbread 2.3.3</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_screenshot_ics.png"/><br/><i>Samsung Galaxy Nexus running ICS 4.0.4</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_screenshot_galaxymini.png"/><br/><i>Samsung Galaxy Mini running Gingerbread 2.3.4</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_screenshot_asus_tablet.jpg"/><br/><i>Asus TF101 Transformer running ICS 4.0.3</i></center></p>
<p/>
<h2>Starting the Employee Directory migration</h2>
<p>
The original Employee Directory source code is available <a href="http://coenraets.org/apps/directory/EmployeeDirectoryLocal.zip">here</a>. The zip file only contains the www folder so you&#8217;ll need to create a new PhoneGap project in XCode, build it, setup the www folder, and replace the content of that www folder with the content found in the Employee Directory download. When launching it in the iPhone simulator, you should see something like this :
</p>
<p>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_ios_employee_directory.png"/></center>
</p>
<h2>QueryString errors</h2>
<p>
In the Employee Directory sample, query strings are used to pass the ID of the selected employee to the detail page. This causes a problem on Android version 3.0 and up. The following error is being shown when we load up a page containing a query string.<br />
The problem is described in <a href="" target="_blank">this Android issue</a>. The issue is fixed but marked for a &#8220;Future version&#8221;. We can only hope that it becomes available in the next Android point release (4.0.5) so that we can all benefit from fixes like that.
</p>
<h2>Using local storage as a workaround</h2>
<p>
As a quick workaround, we can try to use HTML5 local storage to pass data around instead of using query strings.
</p>
<p>
My initial workaround involved something like this when clicking on an employee :
</p>
<pre class="brush: java;">
function loadEmployeeDetail(id) {
	localStorage.setItem( &quot;employeeId&quot;, id );
	location.href=&quot;employeedetails.html&quot;;
}
</pre>
<p>Unfortunately this doesn&#8217;t work, as it generated JSCallback errors on Android,  again due to <a href="http://code.google.com/p/android/issues/detail?id=9122" target="_blank">an Android issue</a>.</p>
<p>04-04 22:20:53.379: I/Web Console(1523): JSCallback Error: Request failed. at :1194134965</p>
<p>
In an effort to fix the error above, and as indicated by PhoneGap, a fix involved using the navigator.app object to load a URL (instead of using the location.href) :
</p>
<pre class="brush: java;">
function loadEmployeeDetail(id) {
	localStorage.setItem( &quot;employeeId&quot;, id );
	//location.href=&quot;employeedetails.html&quot;; // this doesn't work on Android (see )
	navigator.app.loadUrl(&quot;file:///android_asset/www/employeedirectory/employeedetails.html&quot;);
}
</pre>
<p>
Although this fixed my problem on Android, it broke the iOS implementation.
</p>
<p>
Phonegap exposes <a href="http://docs.phonegap.com/en/1.0.0/phonegap_device_device.md.html" target="_blank">a &#8220;device&#8221; object</a> that we can use to detect the platform that we&#8217;re running on. In an ideal cross-platform-one-codebase world we wouldn&#8217;t be needing this, but in reality, you&#8217;ll need it whenever you want to do something specific for a particular platform.
</p>
<p>
A more robust way of handling the query string issue would be to use a different approach altogether, using a REST-style URL approach where employee details are fetched using employeedetails/1 instead of employeedetails.html?id=1. However, this would have a more fundamental impact on the original application  and those changes are out of scope for this article. It just goes to show that what seems trivial at first (passing parameters from one page to another) can cause a lof of headaches when moving to different platforms.
</p>
<h2>Android Employee Directory screenshots</h2>
<p>The Employee Directory renders correctly on all Android devices. Obviously, it is not optimized for tablet usage (lots of white space) as is the case with most of the mobile apps I&#8217;ve seen using web technologies.</p>
<p>Creating tablet optimized versions obviously requires additional work, as it involves developing different screens for different sizes. This is however also the case for native applications. Although it would be interesting to see how this should be tackled for a mobile app created with web technologies, it would require a dedicate article on its own.</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_directory_combined_galaxy_nexus.png"/><br/><i>Samsung Galaxy Nexus running ICS 4.0.4</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_directory_combined_galaxys.png"/><br/><i>Samsung Galaxy S running Gingerbread 2.3.3</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_directory_combined_galaxymini.png"/><br/><i>Samsung Galaxy Mini running Gingerbread 2.3.4</i></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/app_directory_combined_tablet.png"/><br/><i>Asus TF101 Transformer running ICS 4.0.3</i></center></p>
<h2>Android point upgrades</h2>
<p>A couple of weeks ago, while my phone was still running Android ICS 4.0.2, I <a href="https://plus.google.com/112215288642007559493/posts/crgaVYrRjL1" target="_blank">posted on G+</a> that 2 featured cross-platform apps (Diary Mobile created using PhoneGap and GetoGrapher created using Sencha Touch) looked like stretched out iPhone  apps.
</p>
<p>
Much to my surprise I noticed that after Android ICS 4.0.4 was rolled out to my phone, these apps started to look &#8220;normal&#8221; again, as can be screen in the screenshots below (granted, they still look like iPhone apps) :
</p>
<p><center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/ics_point_upgrade1.png"/><br/></center></p>
<p/>
<center><img src="http://dl.dropbox.com/u/13246619/Blog%20Articles/PhoneGap/ics_point_upgrade2.png"/><br/></center></p>
<p>
This just goes to show that there can be a major impact on how your app looks and behaves, even between these maintenance point releases.
</p>
<h2>Hardware acceleration</h2>
<p>
I already talked a bit about hardware acceleration on Android, and how it can speed up animations. The Room 112 application uses an animation to slide the hotel room card onto the screen. With hardware acceleration disabled, the animation is horribly slow. Especially on ICS. Even Gingerbread (that has no hardware acceleration enabled) was faster than ICS. It wasn&#8217;t as smooth as on the iPhone, but acceptable. Only when we enabled hardware acceleration on ICS did we get the same level of performance as on the iPhone.
</p>
<p>
As we&#8217;ve already seen, hardware acceleration can be enabled/disabled on the application level (application tag in the manifest xml), as well as on the activity level. This is a good thing, as it allows you to tweak the settings right to the activity detail.
</p>
<p>
The Employee Directory uses an iScroll library in the employee list screen for enhanced scrolling on iOS. It seems that the iScroll library performs a lot slower when hardware acceleration enabled. In order to get a smooth result we had to run that screen without hardware acceleration. In that respect it&#8217;s nice to be able to disable hardware acceleration on the activity that is hosting that particular screen.
</p>
<pre class="brush: xml;">
        &lt;activity
            android:hardwareAccelerated=&quot;false&quot;
            android:label=&quot;@string/employeedirectory&quot;
            android:configChanges=&quot;orientation|keyboardHidden&quot;
            android:name=&quot;.EmployeeDirectoryActivity&quot; &gt;
            &lt;intent-filter &gt;
                &lt;action android:name=&quot;android.intent.action.MAIN&quot; /&gt;
                &lt;category android:name=&quot;android.intent.category.LAUNCHER&quot; /&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
</pre>
<h2>Conclusions</h2>
<p>
These trivial sample apps show that it is not that straightforward to create a cross-platform app using a single codebase. Each platform (and different versions of the same platform) behave differently and often require their own dedicated tweaks and fixes. Although the scope of this first part was just to get a very basic version of these apps up and running on Android, we already stumbled upon several issues like :</p>
<ul>
<li>Webview javascript engine issues &#8211; JSON.parse(null)</li>
<li>QueryString handling not working</li>
<li>Hardware acceleration tweaks</li>
</ul>
<p>
Keep in mind that this was a very limited exercise using relatively simple applications, where we didn&#8217;t take into account platform look and feel and proper CSS styling for multiple screen resolutions</p>
<p>
It seems to be very difficult to find real-world examples of such multi-platform apps that follow good design, are feature-rich and are truly multi-platform. Out of the 7 featured apps on PhoneGap, only 2 run on both Android and iOS. The rest is targeting a single platform. The ones that are truly multi platform don&#8217;t run all that great. The ones that do work are usually very simple apps that could have just as well been mobile websites.
</p>
<p>
After spending some time looking and using those multi-platform frameworks, I&#8217;m not convinced yet. If you really want to deliver a high quality experience on multiple platforms, the effort required to get it right using web technologies cannot be under-estimated.
</p>
<p>
We are already seeing companies moving away from this approach and rewriting their apps in a native way.
</p>
<p>
On the other hand, one cannot argue the fact that web technologies like html5 / css3 are becoming increasingly important and they cannot be overlooked. They do provide several advantages over doing things natively and maintaining different code-bases. If your application is relatively simple, and you don&#8217;t care about platform look and feel affinity, they are definitely an option. For those type of applications it will be cheaper / easier to develop something using these technologies.
</p>
<p>
In a follow-up post, I&#8217;ll try to tackle the following topics :</p>
<ul>
<li>the various CSS related issues that you need to take into account when working with multiple screen resolutions</li>
<li>how to organize your SCM for cross platform projects</li>
<li>use some of the PhoneGap APIs to access the device capabilities, and see how they translate in a multi-platform setup</li>
</ul>
<h2>References</h2>
<p>&nbsp;</p>
<p><b>Inspiration for this article</b></p>
<ul>
<li><a href="http://jessefreeman.com/articles/room112-phonegap-exploration/" target="_blank">Room112 – PhoneGap Exploration</a></li>
<li><a href="http://coenraets.org/blog/2011/10/sample-app-using-the-phonegap-database-api/" target="_blank">Sample App using the PhoneGap Database API</a></li>
</ul>
<p><b>Sources</b></p>
<ul>
<li><a href="https://github.com/ddewaele/PhoneGapAndroid" target="_blank">Skeleton project for PhoneGap Android.</a></li>
<li><a href="https://github.com/ddewaele/PhoneGapAndroidConversion" target="_blank">Source code for this article.</a></li>
</ul>
<p><b>Hardware acceleration</b></p>
<ul>
<li><a href="https://plus.google.com/105051985738280261832/posts/2FXDCz8x93s" target="_blank">How about some Android graphics true facts?</a></li>
<li><a href="http://www.youtube.com/watch?feature=player_embedded&#038;v=v9S5EO7CLjo" target="_blank">Google I/O 2011: Accelerated Android Rendering</a></li>
<li><a href="http://android-developers.blogspot.com/2011/11/android-40-graphics-and-animations.html" target="_blank">Android 4.0 graphics and animations</a></li>
<li><a href="http://android-developers.blogspot.com/2011/03/android-30-hardware-acceleration.html" target="_blank">Android 3.0 HW Acceleration</a></li>
<li><a href="http://atnan.com/blog/2011/11/10/ios-vs-android-ics-hardware-accelerated-graphics-pipelines/" target="_blank">iOS vs Android ICS hardware accelerated graphics pipelines</a></li>
<li><a href="http://developer.android.com/guide/topics/manifest/application-element.html" target="_blank">Android application element</a></li>
<li><a href="http://themaninblue.com/writing/perspective/2010/03/22/" target="_blank">HTML5 versus Flash: Animation Benchmarking</a></li>
</ul>
<p><b>Tools</b></p>
<ul>
<li><a href="http://www.eclipse.org/downloads/" target="_blank">Eclipse downloads</a></li>
<li><a href="http://developer.android.com/sdk/index.html" target="_blank">Android SDK</a></li>
<li><a href="http://developer.android.com/sdk/eclipse-adt.html#installing" target="_blank">Eclipse ADT</a></li>
<li><a href="https://github.com/phonegap/phonegap/zipball/1.5.0" target="_blank">PhoneGap 1.5.0</a></li>
<li><a href="http://phonegap.com/2012/03/19/phonegap-cordova-and-what%E2%80%99s-in-a-name/" target="_blank">PhoneGap / Cordova naming</a></li>
</ul>
<p><b>Misc libraries / frameworks used in the samples</b></p>
<ul>
<li><a href="http://playground.benbarnett.net/jquery-animate-enhanced/" target="_blank">jquery.animate-enhanced plugin</a></li>
<li><a href="http://cubiq.org/iscroll" target="_blank">iScroll</a></li>
<li><a href="http://westcoastlogic.com/lawnchair/" target="_blank">Lawnchair</a></li>
</ul>
<p><b>Android issues</b></p>
<ul>
<li><a href="http://simonmacdonald.blogspot.com/2012/02/android-issues-all-phonegap-developers.html" target="_blank">Android issues all Phonegap developers should star</a></li>
<li><a href="http://code.google.com/p/android/issues/detail?id=17535" target="_blank">WebView &#8211; URL mechanism is broken</a></li>
<li><a href="http://stackoverflow.com/questions/6185578/android-webviews-and-internal-querystrings" target="_blank">Android Webviews and internal querystrings</a></li>
<li><a href="http://stackoverflow.com/questions/9302306/issue-with-loading-local-javascript-files-inside-a-webview" target="_blank">Issue with loading local javascript files inside a webview</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2012/04/06/phonegap-migrating-ios-application-android/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>30 minute guide to integrating Foursquare in your Android application</title>
		<link>http://blog.doityourselfandroid.com/2011/09/05/integrate-foursquare-android-application/</link>
		<comments>http://blog.doityourselfandroid.com/2011/09/05/integrate-foursquare-android-application/#comments</comments>
		<pubDate>Mon, 05 Sep 2011 22:36:35 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[foursquare]]></category>
		<category><![CDATA[google-api-java-client]]></category>
		<category><![CDATA[oauth]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=1096</guid>
		<description><![CDATA[In this article, I&#8217;m going to show you how you can use Foursquare in your Android application using OAuth 2.0. We&#8217;ll be using&#160; the foursquare-api-java to do the actual Foursquare calls. the Google APIs Client Library for Java to help us out with the OAuth 2.0 flow I&#8217;ve decided to use the foursquare-api-java, a project [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tbody>
<tr>
<td>In this article, I&#8217;m going to show you how you can use Foursquare in your Android application using <strong>OAuth 2.0</strong>.</p>
<p>We&#8217;ll be using&nbsp;</p>
<ul>
<li>the <a href="https://code.google.com/p/foursquare-api-java/" target="_blank">foursquare-api-java</a> to do the actual Foursquare calls.</li>
<li>the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a> to help us out with the OAuth 2.0 flow</li>
</ul>
<p>I&#8217;ve decided to use the <a href="https://code.google.com/p/foursquare-api-java/" target="_blank">foursquare-api-java</a>, a project hosted at Google Code, as it offers a rich interface to interact with Foursquare. The same API calls are possible through the Google API client for Java, but it would require you to write your own model classes to do the JSON to Java translation.<br />
I will post some sample code here on how this can be done with the Google APIs client library for java.</p>
<p>In the <a href="https://github.com/ddewaele/AndroidFoursquareGoogleApiJavaClient" target="_blank">sample application hosted at Github</a>, we&#8217;re going to display a map where the user can select a location. Upon selecting a location, we&#8217;ll load up a list of Foursquare venues that the user can select.<br />
Upon selecting a venue, we&#8217;ll return to our map, put a marker on the map representing the venue, and allow the user to perform a checkin.</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare.jpg"><img class="aligncenter size-full wp-image-1098" title="foursquare" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare.jpg" alt="" width="168" height="168" /></a></td>
</tr>
</tbody>
</table>
</div>
<h2><span id="more-1096"></span></h2>
<h2>The sample application</h2>
<p>All dependencies are included in the lib folder of the project, so after doing a checkout of Github, you should have no problem</p>
<ul>
<li>checking out everything from Git</li>
<li>importing the project in Eclipse and run it from there.</li>
<li>change your Oauth2 properties</li>
<li>run the project on your emulator or phone</li>
</ul>
<p>This is by no means a complete production ready sample. The goal of the sample is to show you how to do the OAuth2 flow, retrieve an access token, and make some API calls.<br />
The Oauth2 properties are defined in <a href="https://github.com/ddewaele/AndroidFoursquareGoogleApiJavaClient/blob/master/src/com/ecs/android/foursquare/oauth2/OAuth2ClientCredentials.java">the OAuth2ClientCredentials class</a>,<br />
You&#8217;ll need to register a new OAuth2 consumer on the Foursquare website (<a href="https://foursquare.com/oauth/register" target="_blank">Foursquare Application Registration</a>), where you need to provide</p>
<ul>
<li>an application name (ex: AndroidFSSample)</li>
<li>an application website (ex: http://localhost:8888)</li>
<li>a callback URL (ex: http://localhost:8888)</li>
</ul>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/consumer_registration2.png"><img class="aligncenter size-full wp-image-1106" title="Foursquare Oauth 2 consumer registration" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/consumer_registration2.png" alt="" width="425" height="322" /></a>After registration, you should see something like this:</p>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/consumer_definition.png"><img class="aligncenter size-full wp-image-1107" title="Foursquare Oauth2 consumer definition" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/consumer_definition.png" alt="" width="523" height="247" /></a></p>
<h2>Our main Foursquare activity</h2>
<p>Our main activity will allow the user to authorize against foursquare. It shows 2 buttons allowing to user to start the authorization process, and another button to clear the access tokens received from Foursquare.</p>
<p style="text-align: center;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/app_not_authorized1.png"><img class="aligncenter size-full wp-image-1110" title="app_not_authorized" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/app_not_authorized1.png" alt="" width="336" height="560" /></a></p>
<pre class="brush: java;">
/**
 * Launch the OAuth flow to get an access token required to do authorized API calls.
 * When the OAuth flow finishes, we redirect to this Activity to perform the API call.
 */
Button launchOauth = (Button) findViewById(R.id.btn_launch_oauth);
launchOauth.setOnClickListener(new View.OnClickListener() {
	public void onClick(View v) {
		startActivity(new Intent().setClass(v.getContext(),OAuthAccessTokenActivity.class));
	}
});

/**
 * Clearing the credentials and performing an API call to see the unauthorized message.
 */
Button clearCredentials = (Button) findViewById(R.id.btn_clear_credentials);
clearCredentials.setOnClickListener(new View.OnClickListener() {
	public void onClick(View v) {
		clearCredentials();
		new PerformApiCallTask().execute();
	}

});
</pre>
<h2>The OAuth2 flow</h2>
<p>The project will use the Google API Java client to do the Foursquare OAuth2.0 flow. We&#8217;ll start by defining the activity that will allows us to retrieve an OAuth 2.0 access token. It&#8217;s a simple activity that is dedicated for this task.</p>
<pre class="brush: xml;">
		&lt;activity android:name=&quot;.OAuthAccessTokenActivity&quot; android:launchMode=&quot;singleTask&quot;&gt;&gt;
			&lt;intent-filter&gt;
				&lt;action android:name=&quot;android.intent.action.VIEW&quot; /&gt;
				&lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
				&lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; /&gt;
				&lt;data android:scheme=&quot;http&quot; android:host=&quot;localhost&quot;  /&gt;
			&lt;/intent-filter&gt;
		&lt;/activity&gt;
</pre>
<p>This activity doesn&#8217;t come with its own layout file, but rather embeds a WebView component programmatically. We&#8217;ll be using the WebView component to launch the Foursquare authorization URL, where we&#8217;ll need to login, and authorize the application access to our Foursquare data.<br />
We enable javascript on the webview component, set it to visible (more on that later), and set it to the ContentView.</p>
<pre class="brush: java;">
	@Override
	protected void onResume() {
		super.onResume();
		WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.setVisibility(View.VISIBLE);
        setContentView(webview);
</pre>
<p>You&#8217;ll notice that there a lot of code between the snippet above and the code that actually launches the authorization URL, but more on that later.<br />
In order to retrieve an access token, we need to redirect the user to the Foursquare authorization URL (More info can be found on https://developer.foursquare.com/docs/oauth.html).<br />
We build up an AuthorizationRequestUrl object (part of Google APIs client library for Java), pass on the Client ID and the Redirection URI (=callback) as defined when registering our consumer, and we launch the URL.</p>
<pre class="brush: java;">
AuthorizationRequestUrl authorizationRequestUrl = new AuthorizationRequestUrl(OAuth2ClientCredentials.AUTHORIZATION_URL);
authorizationRequestUrl.clientId = OAuth2ClientCredentials.CLIENT_ID;
authorizationRequestUrl.redirectUri = OAuth2ClientCredentials.REDIRECT_URI;
webview.loadUrl(authorizationRequestUrl.build());
</pre>
<p>The snippet above will pop the following screen:<br />
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_auth_page1.png"><img class="aligncenter size-full wp-image-1111" title="foursquare_auth_page1" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_auth_page1.png" alt="" width="336" height="560" /></a></span><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">When pressing the login button, you can login with your Foursquare credentials</span><br />
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_auth_page2.png"><img class="aligncenter size-full wp-image-1112" title="foursquare_auth_page2" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_auth_page2.png" alt="" width="336" height="560" /></a><br />
</span><br />
And after that, you should see the following screen (the fact that you now see a map instead of the error message means you&#8217;ve authenticated successfully to Foursquare. :<br />
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/app_authorized.png"><img class="aligncenter size-full wp-image-1113" title="app_authorized" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/app_authorized.png" alt="" width="336" height="560" /></a><br />
</span><br />
For those of you that looked at <a href="http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/" target="_blank">Oauth 2.0 flow in Android</a> article, you might recall we used the following code to build up an authorization URL for the Latitude API</p>
<pre class="brush: java;">
String authorizationUrl = new GoogleAuthorizationRequestUrl(OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.OAUTH_CALLBACK_URL, OAuth2ClientCredentials.SCOPE).build();
</pre>
<p>The Google APIs client library for Java offers ready made Google specific OAuth2 classes. Obviously, it doesn&#8217;t offer those for APIs such as Twitter,Foursquare,Gowalla or Facebook, but it does offer the base classes  (AuthorizationRequestUrl) that you can use  to construct the same authorization URL.</p>
<p>The code that&#8217;s sitting in between the 2 snippets is what will allow us to intercept the access token that is provided by Foursquare once you hit the authorize button in the embedded<br />
browser. The OAuth2.0 flow used here is a web based flow that does the following:</p>
<ul>
<li>redirects the user to Foursquare</li>
<li>allows the user to login using the Foursquare login page (meaning no password is captured by the browser)</li>
<li>allows foursquare to check your credentials and present you with an auhorization screen.</li>
<li>On this screen, you can allow this application access to your Foursquare data, or deny access.</li>
<li>If you decide to grant access, foursquare redirects to another page referred to as a callback URL, containing a token that allows this application to access your data.</li>
</ul>
<p>We need to be able to intercept this redirect, capture the token, and store it on the phone so we can begin interacting with Foursquare.</p>
<p>Retrieving the access token is illustrated by the following code. Using the WebView component, we intercept the redirect, check if there is a token in the URL,<br />
and if so, continue our processing.</p>
<pre class="brush: java;">
@Override
public void onPageFinished(WebView view, String url)  {
	if (url.startsWith(OAuth2ClientCredentials.REDIRECT_URI)) {
	            		try {
	            			if (url.indexOf(&quot;code=&quot;)!=-1) {
		            			String code = extractCodeFromUrl(url);
</pre>
<p>Once we&#8217;ve retrieved the code from the Foursquare server, we can exchange it for an access token. This is done using the following code:</p>
<pre class="brush: java;">
AuthorizationCodeGrant request = new AuthorizationCodeGrant(new NetHttpTransport(),
        new JacksonFactory(),
        OAuth2ClientCredentials.ACCESS_TOKEN_URL,
        OAuth2ClientCredentials.CLIENT_ID,
        OAuth2ClientCredentials.CLIENT_SECRET,
        code,
        OAuth2ClientCredentials.REDIRECT_URI);
AccessTokenResponse accessTokenResponse = request.execute();

CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
credentialStore.write(accessTokenResponse );
</pre>
<p>For those who looked at my <a href="http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/" target="_blank">Oauth 2.0 flow in Android</a> article, you&#8217;ll notice that the only difference when dealing with non Google APIs is that we use the AuthorizationCodeGrant class instead of the Google specific GoogleAuthorizationCodeGrant. Other than that, the code is pretty much identical. I&#8217;ve put the Google specific code here for reference:</p>
<pre class="brush: java;">
  AccessTokenResponse accessTokenResponse = new GoogleAuthorizationCodeGrant(new NetHttpTransport(),
			      new JacksonFactory(),
			      OAuth2ClientCredentials.CLIENT_ID,
			      OAuth2ClientCredentials.CLIENT_SECRET,
			      code,
			      OAuth2ClientCredentials.REDIRECT_URI).execute();

  CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
  credentialStore.write(accessTokenResponse);
</pre>
<p>We store the access token in a credential store (the shared preferences of our application).<br />
Now that the app has an access token, we can launch our main activity and start interacting with Foursquare.</p>
<p>When our main activity is launched initially, and the user has properly authorized our app to use its Foursquare data using the flow above, the user will be presented with a map.<br />
When the user clicks on the map, he&#8217;ll be presented with a list of places that we fetched from Foursquare.</p>
<h2>The clickable map</h2>
<p>For those of you who want more info on howto setup an Android project with the MapView component, I suggest you have a look at <a href="http://blog.doityourselfandroid.com/2011/01/18/using-google-maps-in-your-android-app/">Using Google Maps in your Android Application</a>.</p>
<p>We&#8217;re using the following overlay to allow the user to tap on the map :</p>
<pre class="brush: java;">
private class HelloItemizedOverlay extends ItemizedOverlay&lt;OverlayItem&gt;
{

	/**
	 * Calling populate here to avoid a nullpointerexception.
	 *
	 * @param defaultMarker
	 */
	public HelloItemizedOverlay(Drawable defaultMarker) {
		  super(boundCenterBottom(defaultMarker));
		  populate();
	}

	public void addOverlay(OverlayItem overlay) {
	    mOverlays.add(overlay);
	    populate();
	}

	@Override
	protected OverlayItem createItem(int i) {
	  return mOverlays.get(i);
	}

	@Override
	public int size() {
	  return mOverlays.size();
	}

	/**
	 *
	 * Triggered when the user clicks on the map.
	 *
	 */
	@Override
	public boolean onTap(GeoPoint p, MapView mapView) {
		HelloItemizedOverlay itemizedoverlay = (HelloItemizedOverlay) mapView.getOverlays().get(0);
        OverlayItem overlayitem = new OverlayItem(p, &quot;Location at &quot; + &quot;title&quot;,&quot;snippet&quot;);
        itemizedoverlay.addOverlay(overlayitem);
        mapView.invalidate();
		popFoursquareVenueList(p.getLatitudeE6()/1E6,p.getLongitudeE6()/1E6);
		return true;
	}

}
</pre>
<p>As you can see, when tapping on the map, we put a marker on the map through the HelloItemizedOverlay, and pop the FoursquareVenueList Activity.<br />
We launch the venues list screen by passing on the coordinates of the map that the user clicked on.</p>
<pre class="brush: java;">
private void popFoursquareVenueList(double lat,double lng) {
	Intent intent = new Intent(getApplicationContext(),FourSquarePlacesList.class);
	intent.putExtra(Constants.PLACE_LAT_FIELD, lat);
	intent.putExtra(Constants.PLACE_LNG_FIELD,lng);
	startActivity(intent);
}
</pre>
<p>The FoursquareVenuesList activaty shows the Foursquare venues in a list like this</p>
<p style="text-align: center;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_venues_list.png"><img class="aligncenter size-full wp-image-1114" title="foursquare_venues_list" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/foursquare_venues_list.png" alt="" width="336" height="560" /></a></p>
<h2>The FoursquareVenueList</h2>
<p>Our FoursquareVenueList Activity extends ListActivity, as we are going to show the venues in a ListView. The ListActivity provides us with the basic infrastructure<br />
to setup the list, and handle the item selection in the list.</p>
<p>The layout looks like this:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;LinearLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:orientation=&quot;vertical&quot;
    android:background=&quot;#FFFFFF&quot;
    android:layout_width=&quot;fill_parent&quot;
    android:layout_height=&quot;fill_parent&quot;
    android:paddingTop=&quot;10px&quot;&gt;

	&lt;TextView
        android:id=&quot;@+id/intro&quot;
        android:textColor=&quot;#000000&quot;
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:text=&quot;Pick a place&quot;/&gt;

    &lt;ListView
 	android:id=&quot;@id/android:list&quot;
 	android:textColor=&quot;#000000&quot;
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;fill_parent&quot;
        android:layout_weight=&quot;1&quot;
 		android:drawSelectorOnTop=&quot;true&quot;/&gt;

    &lt;TextView
    	android:textColor=&quot;#000000&quot;
        android:id=&quot;@id/android:empty&quot;
        android:layout_width=&quot;fill_parent&quot;
        android:layout_height=&quot;fill_parent&quot;
        android:text=&quot;empty&quot;/&gt;

&lt;/LinearLayout&gt;
</pre>
<p>We retrieve the latitude/longitude that was passed on from the previous screen.</p>
<pre class="brush: java;">
	if (getIntent().getExtras() != null) {
		lat = getIntent().getExtras().getDouble(Constants.PLACE_LAT_FIELD);
		lng = getIntent().getExtras().getDouble(Constants.PLACE_LNG_FIELD);
	}
</pre>
<p>We&#8217;re using the following asynctask to fetch the places and populate the list.</p>
<pre class="brush: java;">
private class PlacesListRefresher extends AsyncTask&lt;Uri, Void, Void&gt; {

	@Override
	protected Void doInBackground(Uri... params) {

		try {
			Log.i(Constants.TAG, &quot;Retrieving places at &quot; + lat + &quot;,&quot; + lng);
			Result&lt;VenuesSearchResult&gt; venues = getFoursquareApi().venuesSearch(
					lat + &quot;,&quot; + lng, null, null, null, null, null, null,
					null, null, null, null);
			CompactVenue[] compactVenues = venues.getResult().getVenues();
			Log.i(Constants.TAG, &quot;found &quot; + compactVenues.length
					+ &quot; places&quot;);
			for (CompactVenue compactVenue : compactVenues) {
				veneusMap.add(compactVenue);
			}
		} catch (Exception ex) {
			Log.e(Constants.TAG, &quot;Error retrieving venues&quot;, ex);
		}
		return null;
	}

	@Override
	protected void onPostExecute(Void result) {
		setListAdapter(new FoursquareTableAdapter(veneusMap));
	}

}
</pre>
<h2>Accessing the foursquare API</h2>
<p>As you can see, we fire up the Foursquare API and do a venuesSearch, by passing on the latitude and longitude we retrieved in the previous step.<br />
We loop over the venues array and store it in a map. All of this is happening in a background thread. When the background thread finished, we setup our listAdapter in order to display the results in the ListView.</p>
<p>The getFoursquareApi() method is implemented like this:</p>
<pre class="brush: java;">
public FoursquareApi getFoursquareApi() {
	if (this.foursquareApi==null) {
		this.prefs = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
		CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);

		AccessTokenResponse accessTokenResponse = credentialStore.read();
		this.foursquareApi = new FoursquareApi(OAuth2ClientCredentials.CLIENT_ID,
				OAuth2ClientCredentials.CLIENT_SECRET,
				OAuth2ClientCredentials.REDIRECT_URI,
				accessTokenResponse.accessToken, new DefaultIOHandler());
	}
	return this.foursquareApi;

}
</pre>
<p>It fetches the accessToken from our CredentialStore, and initialized the FoursquareApi object that we use to fetch the venues.</p>
<h2>Using Google APIs client for Java for the Foursquare API calls</h2>
<p>You may have noticed that for making the actual API calls, we&#8217;re not using the Google APIs client libraries for Java, but instead are relying on a third-party client library. That&#8217;s one model of working, and an appropriate one if a rich third party client library like Foursquare API for Java is available. It integrates very nicely with Google APIs client for Java as we pass on the access token we retrieved from Google APIs client for Java to the Foursquare API for Java. As Google APIs client for Java is really good at handling the OAuth2 stuff, and the Foursquare API for Java is really good at doing the Foursquare stuff, this is a model that works.</p>
<p>This <strong>does not</strong> mean that we can&#8217;t use the Google APIs client libraries for Java to access the Foursquare REST endpoints. In the sample project, I&#8217;ve created a method called <b>performFoursquareApiCallUsingGoogleApiJavaClient</b> that shows 2 ways of using the Google APIs client libraries for Java to access the Foursquare REST endpoints. Let&#8217;s go over them.</p>
<h2>Fetching the response as a String, and transforming it into JSON</h2>
<p>One way of interacting with the Foursquare endpoint is to interpret the response as a String (parseAsString()), and convert it into some standard  JSON structures. That way, you can get a hold of the data in a generic way.</p>
<pre class="brush: java;">
	public void performFoursquareApiCallUsingGoogleApiJavaClient() throws Exception {
		AccessTokenResponse accessTokenResponse = credentialStore.read();
		HttpTransport transport = new NetHttpTransport();
		GenericUrl genericUrl = new GenericUrl(FOURSQUARE_API_ENDPOINT);
		genericUrl.put(&quot;ll&quot;,lat + &quot;,&quot; + lng);
		HttpRequest httpRequest = createApiRequestFactory(transport, accessTokenResponse.accessToken).buildGetRequest(
				genericUrl);
		HttpResponse httpResponse = httpRequest.execute();
		JSONObject object = new JSONObject(httpResponse.parseAsString());
		JSONObject fourSquareResponse = (JSONObject) object.get(&quot;response&quot;);
		JSONArray groups = (JSONArray) fourSquareResponse.get(&quot;groups&quot;);
		JSONObject group = (JSONObject)groups.get(0);
		JSONArray items = (JSONArray)group.get(&quot;items&quot;);
		Log.i(Constants.TAG, &quot;Found venues &quot; + items);
</pre>
<p>The example above shows you how to traverse the JSON structure using standard JSONArray and JSONObject objects.</p>
<h2>Have Google APIs client library for Java transform the response into a java model.</h2>
<p>Another approach is to create your own model classes, and let the Google APIs client for Java to the transformation of the JSON string into your Java model. The example below illustrates just that. Note how we don&#8217;t parse the response as a String, but rather parse the response into a FoursquareResponse.class.</p>
<pre class="brush: java;">
		httpRequest = createApiRequestFactory(transport, accessTokenResponse.accessToken).buildGetRequest(
				genericUrl);
		JsonHttpParser parser = new JsonHttpParser();
	    parser.jsonFactory = new JacksonFactory();
	    httpRequest.addParser(parser);
		httpResponse = httpRequest.execute();
		FoursquareResponse foursquareResponse2 = httpResponse.parseAs(FoursquareResponse.class);
		Venue[] venues = foursquareResponse2.response.groups[0].items;
		Log.i(Constants.TAG, &quot;Found venues &quot; + venues);

	}
</pre>
<p>The FoursquareResponse.class looks like this</p>
<pre class="brush: java;">

public class FoursquareResponse implements Serializable {
	private static final long serialVersionUID = -383365244692781213L;

	@Key
	public Response response;
}
</pre>
<p>The Response class like this:</p>
<pre class="brush: java;">
public class Response  implements Serializable {
	private static final long serialVersionUID = -8744243204974447941L;

	@Key
	public Group[] groups;
}
</pre>
<p>You get the picture&#8230;.. This way, you get to work with a much richer interface. Instead of working with low level generic JSON objects, you now have a rich java based data model that you can use in your app. You no longer need to know the internal JSON structure, you just need to read the java model to get the data you want.</p>
<p>I opted for the third party library because there was one available for Foursquare in Java. If no API was available, I would have gone for this approach.</p>
<p>We&#8217;ve created a FoursquareTableAdapter that acts as a data adapter for the ListView component.</p>
<pre class="brush: java;">
class FoursquareTableAdapter extends ArrayAdapter&lt;CompactVenue&gt; {
	FoursquareTableAdapter(List&lt;CompactVenue&gt; list) {
		super(FoursquareVenueList.this, R.layout.places_list_row, list);
	}

	public View getView(int position, View convertView, ViewGroup parent) {
		ViewHolder holder = null;
		if (convertView == null) {
			convertView = getLayoutInflater().inflate(R.layout.places_list_row, parent, false);
			holder = new ViewHolder();
			holder.txtPlaceName = (TextView) convertView.findViewById(R.id.row_placename);
			holder.txtPlaceAddress = (TextView) convertView.findViewById(R.id.row_placeaddress);
			holder.layout = (RelativeLayout) convertView.findViewById(R.id.row_layout);
			convertView.setTag(holder);
		} else {
			holder = (ViewHolder) convertView.getTag();
		}

		CompactVenue venue = getVenueMapFromAdapter(position);

		try {
			holder.txtPlaceName.setText(venue.getName());
			if (venue.getLocation().getAddress() != null &amp;&amp; venue.getLocation().getAddress().length() &gt; 0) {
				holder.txtPlaceAddress.setText(venue.getLocation().getAddress());
			} else {
				holder.txtPlaceAddress.setText(R.string.no_address_info_found);
			}
		} catch (Exception ex) {
			ex.printStackTrace();
		}

		return (convertView);
	}
}
</pre>
<p>The FoursquareTableAdapter is an ArrayAdapter that needs to be inialized with a list of CompactVenue objects. The getView method is responsible for filling up each row in the ListView component.<br />
We use the ViewHolder pattern to optimize performance and memory management. The ViewHolder pattern avoids calling findViewById() when it is not necessary.</p>
<p>We also setup a AdapterView.OnItemClickListener on the ListView that is triggered when the user selects an item form the list.<br />
As you can see here, we retrieve a ference to the current selected venue, wrap up the data in an intent, and startup our previous activity again, only this time<br />
passing on the additional data related to the venue.</p>
<pre class="brush: java;">
getListView().setOnItemClickListener(
	new AdapterView.OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView&lt;?&gt; parent, View view,
				int position, long id) {

			CompactVenue venue = veneusMap.get((int) id);
			Intent intent = new Intent(getApplicationContext(),FoursquareApiSample.class);
			intent.putExtra(Constants.PLACE_ID_FIELD, venue.getId());
			intent.putExtra(Constants.PLACE_LAT_FIELD, venue.getLocation().getLat());
			intent.putExtra(Constants.PLACE_LNG_FIELD, venue.getLocation().getLng());
			intent.putExtra(Constants.PLACE_NAME_FIELD, venue.getName());
			intent.putExtra(Constants.PLACE_ADDRESS_FIELD, venue.getLocation().getAddress());
			startActivity(intent);
		}

	}
);
</pre>
<p>The initial activity showing the map will pick up the venue data, put a marker on the map where the venue is located, and allow the user to checkin to that venu.</p>
<pre class="brush: java;">
if (getIntent().getExtras()!=null) {
	Double lat = getIntent().getExtras().getDouble(Constants.PLACE_LAT_FIELD);
	Double lng = getIntent().getExtras().getDouble(Constants.PLACE_LNG_FIELD);
	venueAddress = getIntent().getExtras().getString(Constants.PLACE_ADDRESS_FIELD);
	venueName = getIntent().getExtras().getString(Constants.PLACE_NAME_FIELD);
	venueId = getIntent().getExtras().getString(Constants.PLACE_ID_FIELD);
	GeoPoint p = new GeoPoint((int) (lat * 1E6), (int) (lng * 1E6));
	HelloItemizedOverlay venueOverlay = (HelloItemizedOverlay) mapView.getOverlays().get(0);
    OverlayItem overlayitem = new OverlayItem(p, venueName, venueAddress);
    venueOverlay.addOverlay(overlayitem);
    mc.animateTo(p);
    mc.setCenter(p);
    mc.setZoom(16);
    showCheckinSection = true;
    this.checkinSection.setVisibility(View.VISIBLE);
}
</pre>
<p><span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;">You should see the following screen :</span><br />
<span style="font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif; font-size: 13px; line-height: 19px; white-space: normal;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin1.png"><img class="aligncenter size-full wp-image-1115" title="checkin1" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin1.png" alt="" width="336" height="560" /></a><br />
</span></p>
<p>The actual checkin is done using again an AsyncTask, making sure that the actual checkin logic occurs in the background (as it involves performing a REST call to Foursquare,<br />
potentially blocking the UI untill Foursquare comes back with a response).</p>
<pre class="brush: java;">
private class CheckinTask extends AsyncTask&lt;Uri, Void, Void&gt; {

	private String apiStatusMsg;

	@Override
	protected Void doInBackground(Uri...params) {
		try {
			CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
			AccessTokenResponse accessTokenResponse = credentialStore.read();
		    FoursquareApi foursquareApi = new FoursquareApi(OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.CLIENT_SECRET, OAuth2ClientCredentials.REDIRECT_URI,accessTokenResponse.accessToken,new DefaultIOHandler());
			Result&lt;Checkin&gt; result = foursquareApi.checkinsAdd(venueId, null, getString(R.string.checkin_msg), null, null,null,null,null);
			if (result.getMeta().getCode()==200) {
				apiStatusMsg = &quot;Checked in to &quot; + venueName;
			} else {
				apiStatusMsg = result.getMeta().getErrorDetail();
			}
		} catch (FoursquareApiException e) {
			e.printStackTrace();
		}
        return null;
	}

	@Override
	protected void onPreExecute() {
	}

	@Override
	protected void onPostExecute(Void result) {
		Toast.makeText(FoursquareApiSample.this, apiStatusMsg, Toast.LENGTH_LONG).show();
	}

}
</pre>
<p>When the checkin succeeds, you should see a Toast message indicating that the checkin was successful.<br />
<a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin2.png"><img class="aligncenter size-full wp-image-1117" title="checkin2" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin2.png" alt="" width="336" height="560" /></a><br />
You can double-check your Foursquare history to see that the checkin did in fact take place:<br />
<a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin_history.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/09/checkin_history.png" alt="" title="checkin_history" width="497" height="289" class="aligncenter size-full wp-image-1124" /></a></p>
<h2>Conclusion</h2>
<p>As I already showed in my <a href="http://blog.doityourselfandroid.com/2011/08/08/improved-twitter-oauth-android/" target="_blank">Improved Twitter OAuth for Android</a> post, the Google API client library for Java is well suited to interact with non Google APIs. Where the Twitter post showed you how to use the library with an OAuth 1.0a enabled service provider, this post  shows that the Google API client library for Java can also be used to interact with non-Google APIs using Oauth 2.0. It&#8217;s strong collection of base OAuth2 objects make it very easy to interact with any OAuth2 enabled service provider. The library is available for a large number of languages (PHP,Python,Objective-C,..).<br />
You can use parts of the API as you see fit. For example here I decided to use the OAuth 2.0 part, but not use the JSON to Java Model mapping as there was already a good Foursquare library available. For REST APIs support Oauth that don&#8217;t have any java based library available, it&#8217;s well worth the effort to model the API in Java, and let Google APIs Client Library for Java do the transformation for you.<br />
I suggest you check it out at <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a>.</p>
<h2>References</h2>
<ul>
<li><a href="https://code.google.com/p/foursquare-api-java/" target="_blank">foursquare-api-java</a></li>
<li><a href="https://developer.foursquare.com/" target="_blank">Foursquare Developer site</a></li>
<li><a href="https://foursquare.com/oauth/register" target="_blank">Foursquare Application Registration</a></li>
<li><a href="https://developer.foursquare.com/docs/oauth.html" target="_blank">Foursquare OAuth2 documentation</a></li>
<li><a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a></li>
<li><a href="https://developer.foursquare.com/docs/ target=">Foursquare API v2 docs</a></li>
<li><a href="http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/" target="_blank">Oauth 2.0 flow in Android</a></li>
<li><a href="http://blog.doityourselfandroid.com/2011/08/08/improved-twitter-oauth-android/" target="_blank">Improved Twitter OAuth for Android</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/09/05/integrate-foursquare-android-application/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Latify Android Video Review</title>
		<link>http://blog.doityourselfandroid.com/2011/08/29/latify-video-review/</link>
		<comments>http://blog.doityourselfandroid.com/2011/08/29/latify-video-review/#comments</comments>
		<pubDate>Mon, 29 Aug 2011 19:45:38 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Latify]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[GPS]]></category>
		<category><![CDATA[latify]]></category>
		<category><![CDATA[latitude]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=1081</guid>
		<description><![CDATA[Not really a development post, but a video review of Latify (my app for Android). Video review was done by http://hemorrdroids.net. Enjoy&#8230;.]]></description>
			<content:encoded><![CDATA[<p>Not really a development post, but a video review of Latify (my app for Android). Video review was done by <a href="http://hemorrdroids.net" target="_blank">http://hemorrdroids.net</a>. Enjoy&#8230;.</p>
<p><iframe width="500" height="306" src="http://www.youtube.com/embed/rycRohZWijQ?fs=1&#038;wmode=transparent" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/08/29/latify-video-review/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Improved Twitter OAuth for Android</title>
		<link>http://blog.doityourselfandroid.com/2011/08/08/improved-twitter-oauth-android/</link>
		<comments>http://blog.doityourselfandroid.com/2011/08/08/improved-twitter-oauth-android/#comments</comments>
		<pubDate>Mon, 08 Aug 2011 17:16:47 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[google-api-java-client]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[tweet]]></category>
		<category><![CDATA[twitter]]></category>
		<category><![CDATA[twitter4j]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=1048</guid>
		<description><![CDATA[A couple of months ago, I published a post entitled A 30 minute guide to integrating Twitter in your Android application.. The post presented a sample Android application to integrate Twitter. Using the signpost library, the user was able to authorize our application to send tweets on his/her behalf. It seems that everyone is migrating [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tbody>
<tr>
<td>A couple of months ago, I published a post entitled <a href="http://blog.doityourselfandroid.com/2011/02/13/guide-to-integrating-twitter-android-application/" target="_blank">A 30 minute guide to integrating Twitter in your Android application.</a>. The post presented a sample Android application to integrate Twitter. Using the signpost library, the user was able to authorize our application to send tweets on his/her behalf. It seems that everyone is migrating to Oauth 2.0, but Twitter is still stuck at OAuth 1.0. Nevertheless, I still wanted to <a href="https://github.com/ddewaele/AndroidTwitterGoogleApiJavaClient" target="_blank">update the sample</a> we did a couple of months ago for 3 reasons :&nbsp;</p>
<ul>
<li>I wanted to show you how to integrate non-google APIs using the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a>.</li>
<li>I wanted to show you a new approach to the Oauth flow (without popping a browser)</li>
<li>I wanted to  show you how to do OAuth 1.0 using the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a>.</li>
</ul>
</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/twitter-android.jpg"><img class="aligncenter size-full wp-image-722" title="Twitter Android" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/twitter-android.jpg" alt="" width="260" height="190" /></a></td>
</tr>
</tbody>
</table>
</div>
<p><span id="more-1048"></span></p>
<p>I&#8217;ll start by introducing the application (for those who read the previous article, it should look pretty familiar.</p>
<h2>The sample app UI</h2>
<p>Granted, the user interface looks pretty basic, but it gets the job done. We&#8217;ve got</p>
<ul>
<li>a Launch OAuth flow button that will take the user through the OAuth flow.</li>
<li>a Clear credentials button, that will remove any authentication tokens stored in the app.</li>
<li>a Label, showing the status of a Twitter API call.</li>
</ul>
<h2>Unauthorized API access</h2>
<p>When we start the application for the first itme, you&#8217;ll see the following error message :</p>
<p style="text-align: center;">x<br />
<a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/unauthorized.png"><img class="aligncenter size-full wp-image-1054" title="unauthorized" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/unauthorized.png" alt="" width="288" height="480" /></a></p>
<p style="text-align: left;">What you are seeing is the outcome of the Twitter API call. Obviously, in order to perform a Tweet, the user needs to authorize our application to send tweets on his behalf. Failure to do so results in an Authentication error.</p>
<p style="text-align: left;">The API call is executed when this main activity is launched.</p>
<p style="text-align: left;">In order to succesfully send a tweet, the user needs to authorize the request.</p>
<h2>Authorizing the application</h2>
<p style="text-align: left;">When clicking on the Launch OAuth Flow button, we&#8217;ll start the OAuth web based flow. In the previous article, we used Signpost to handle the Oauth flow, and had a pretty complex flow, where we started an activity, launched the browser, started background tasks, and had to deal with onNewIntent calllbacks during the OAuth flow.</p>
<p>On top of that, launching the browser to show the Twitter authorization pages, a scenario where all of a sudden our application lost control and moved control to the browser, is a pretty unnatural flow with a lot of negative side-effects for the user. To name a couple :</p>
<ul>
<li>The user find himself in a browser environment all of a sudden.</li>
<li>It&#8217;s clear he&#8217;s no longer in our application.</li>
<li>What if the users decides to go back, or exit the browser app ?</li>
<li>What if the user was browsing some site in his browser, will that page all of a sudden get replaced by our Twitter authorization page ?</li>
</ul>
<p style="text-align: left;">In the previous sample, we launched a browser like this :</p>
<pre class="brush: java;">final String url = provider.retrieveRequestToken(consumer, Constants.OAUTH_CALLBACK_URL);
Log.i(TAG, &quot;Popping a browser with the authorize URL : &quot; + url);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
context.startActivity(intent);</pre>
<p style="text-align: left;">&nbsp;</p>
<h2>the Android WebView component</h2>
<p style="text-align: left;">In this sample, we&#8217;re not going to pop a full browser, but we&#8217;re going to start a regular Android activity, and use the WebView component to launch our authorization page</p>
<pre class="brush: java;">@Override
protected void onResume() {
	super.onResume();
	WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.setVisibility(View.VISIBLE);
        setContentView(webview);

        final OAuthHmacSigner signer = new OAuthHmacSigner();
        signer.clientSharedSecret = Constants.CONSUMER_SECRET;

	OAuthGetTemporaryToken temporaryToken = new OAuthGetTemporaryToken(Constants.REQUEST_URL);
	temporaryToken.transport = new ApacheHttpTransport();
	temporaryToken.signer = signer;
	temporaryToken.consumerKey = Constants.CONSUMER_KEY;
	temporaryToken.callback = Constants.OAUTH_CALLBACK_URL;

	OAuthCredentialsResponse tempCredentials = temporaryToken.execute();
	signer.tokenSharedSecret = tempCredentials.tokenSecret;

	OAuthAuthorizeTemporaryTokenUrl authorizeUrl = new OAuthAuthorizeTemporaryTokenUrl(Constants.AUTHORIZE_URL);
	authorizeUrl.temporaryToken = tempCredentials.token;
	String authorizationUrl = authorizeUrl.build();

	webview.loadUrl(authorizationUrl);
}</pre>
<p style="text-align: left;">As you can see, a setup a WebView component (taking up the entire activity space), enable javascript (most authorization pages require javascript), and load up the OAuth 1.0 authorization URL in the WebView component.</p>
<p style="text-align: left;">Before we can start building the authorization URL, we first need to setup our OAuth signer object, request a temporary token, and use that temporary token to put in our authorization URL.</p>
<h2>Twitter OAuth constants</h2>
<p style="text-align: left;">All Twitter specific Oauth parameters are defined in a constants file.</p>
<pre class="brush: java;">	public static final String CONSUMER_KEY = &quot;PUT YOUR TWITTER OAUTH CONSUMER KEY HERE&quot;;
	public static final String CONSUMER_SECRET= &quot;PUT YOUR TWITTER OAUTH CONSUMER SECRET HERE&quot;;

	public static final String REQUEST_URL = &quot;http://api.twitter.com/oauth/request_token&quot;;
	public static final String ACCESS_URL = &quot;http://api.twitter.com/oauth/access_token&quot;;
	public static final String AUTHORIZE_URL = &quot;http://api.twitter.com/oauth/authorize&quot;;

	public static final String	OAUTH_CALLBACK_URL		= &quot;http://localhost&quot;;</pre>
<p>What we need are</p>
<ul>
<li>the OAuth consumer key and secret (can be found on the Twitter dev page for your app)</li>
<li>the 3 OAuth endpoints (request,authorize and access)</li>
<li>a callback URL.</li>
</ul>
<p style="text-align: left;">When the authorization URL is launched in the Webview, you should see the following screen (when already logged into Twitter). When not logged in, a page will be shown allowing you to enter your Twitter credentials before moving to this page. Included on the page is some information related to your application (as you&#8217;ve defined them on the Twitter dev page), and an authorize button.</p>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweet_sent.png"><br />
</a></p>
<p style="text-align: center;">x<br />
<a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize2.png"><img class="aligncenter size-full wp-image-1049" title="authorize2" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize2.png" alt="" width="288" height="480" /></a></p>
<p style="text-align: left;">When the user hits the authorize button, Twitter will perform a redirect using our callback URL (set to http://localhost)</p>
<p style="text-align: center;">x<br />
<a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize4.png"><img class="aligncenter size-full wp-image-1051" title="authorize4" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize4.png" alt="" width="288" height="480" /></a></p>
<h2>Intercepting the callback</h2>
<p style="text-align: left;">And here&#8217;s where the magic happens. As Twitter redirects to the callback URL, it&#8217;s up to our app to <strong>intercept this redirect</strong>, pick up the <strong>2 OAuth tokens</strong> from that callback URL (<strong>oauth token</strong> and <strong>oauth verifier</strong>). This authorization (and verifier) token is what we need in order to get an actual OAuth access token that is required to perform the Twitter API call.</p>
<p style="text-align: left;">Luckily for us, the WebView component allows us to register a <strong>WebViewClient</strong>, that has an important hook that we&#8217;ll implement, the <strong>onPageStarted</strong> method.</p>
<p style="text-align: left;">This method is called each time a page is loaded into the WebView. As we&#8217;re particulary interested in our callback URI, we&#8217;ll only implement our logic when the URL in the WebView matches our Callback URL. When this is the case, we extract the <strong>oauth_token</strong> en <strong>oauth_verifier</strong>.</p>
<p style="text-align: left;">With the <strong>oauth_token</strong> en <strong>oauth_verifier</strong>, we can contact Twitter and exchange them for an actual OAuth access token.</p>
<p>As you can see from the code below, we extract both tokens from the callback URL.<br />
We construct an <strong>OAuthGetAccessToken</strong> object, set the required properties (transport, temp authorization token, verifier token, signer and consumer key) and call it&#8217;s execute method to <strong>retrieve the actual access token</strong>. The access token is embedded in the <strong>OAuthCredentialsResponse</strong> object.</p>
<pre class="brush: java;">String requestToken  = extractParamFromUrl(url,&quot;oauth_token&quot;);
String verifier= extractParamFromUrl(url,&quot;oauth_verifier&quot;);

signer.clientSharedSecret = Constants.CONSUMER_SECRET;

OAuthGetAccessToken accessToken = new OAuthGetAccessToken(Constants.ACCESS_URL);
accessToken.transport = new ApacheHttpTransport();
accessToken.temporaryToken = requestToken;
accessToken.signer = signer;
accessToken.consumerKey = Constants.CONSUMER_KEY;
accessToken.verifier = verifier;

OAuthCredentialsResponse credentials = accessToken.execute();</pre>
<p>What we need to do now is store the OAuth access token (and secret) in the shared preferences of our app. I&#8217;ve created a simple SharedPreferencesCredentialStore that is capable of reading / writing the 2 tokens from / to the shared preferences.</p>
<pre class="brush: java;">CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
credentialStore.write(new String[] {credentials.token,credentials.tokenSecret});</pre>
<p style="text-align: left;">&nbsp;</p>
<p style="text-align: left;">Obviously, we don&#8217;t have anythiung running on localhost, so in order to avoid the user getting confronted with an <strong>HTTP 404 Not Found</strong> error in his WebView, we hide the WebView (by setting the visibility to gone).</p>
<pre class="brush: java;">view.setVisibility(View.INVISIBLE);
startActivity(new Intent(OAuthAccessTokenActivity.this,AndroidTwitterGoogleApiJavaClientActivity.class));</pre>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweets.png"><br />
</a></p>
<h2>Executing the API</h2>
<p>Upon returning to the main activity, with our OAuth access tokens safely stored in the shared preferences, all that&#8217;s left to do know is <strong>execute the API call</strong>. This is done through the following utlity method.</p>
<pre class="brush: java;">public static void sendTweet(SharedPreferences prefs,String msg) throws Exception {
		String[] tokens = new SharedPreferencesCredentialStore(prefs).read();
		AccessToken a = new AccessToken(tokens[0],tokens[1]);
		Twitter twitter = new TwitterFactory().getInstance();
		twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
		twitter.setOAuthAccessToken(a);
		twitter.updateStatus(msg);
}</pre>
<p>We retrieve the tokens from the shared preferences, use them to construct a <strong>Twitter AccessToken</strong> (<strong>Twitter4J</strong> component), and use the Twitter object to send our Tweet. Our main activity will confirm that the tweet has been sent.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweet_sent.png"><img class="aligncenter" title="tweet_sent" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweet_sent.png" alt="" width="288" height="480" /></a></p>
<p>To double check, you can always check your Twitter page as well :</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweets.png"><img class="aligncenter" title="tweets" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/tweets.png" alt="" width="541" height="258" /></a></p>
<h2>Conclusions</h2>
<p>I tried to show you a couple of things in this article :</p>
<p><strong>A simplified way of dealing with the Oauth flow</strong><br />
By using a WebView component, we can have more control over the Oauth flow, as it&#8217;s kept within the Android Activity lifecycle, without starting external programs. You can opt to run it fullscreen, or embedded in an Activity, providing some additional context to the user.<br />
<strong> </strong></p>
<p><strong>Using non-Google APIs in conjuction with the google api java client</strong><br />
So far, we&#8217;ve only used Google APIs when using the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a>. Here we&#8217;ve shown that the OAuth flow was completely handled by the library, right untill the point where we retrieved the access token. After that, control was given to Twitter4J, a Java library for the Twitter API compatible with Android.</p>
<h2>References</h2>
<ul>
<li><a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a></li>
<li><a href="https://dev.twitter.com/docs/auth/oauth/faq" target="_blank">Twitter OAuth FAQ</a></li>
<li><a title="OAuth Signpost library" href="http://code.google.com/p/oauth-signpost/" target="_blank">signpost library</a></li>
<li><a title="Twitter4J library" href="http://twitter4j.org/en/index.html" target="_blank">Twitter4J library</a></li>
<li><a href="https://github.com/ddewaele/AndroidTwitterGoogleApiJavaClient" target="_blank">Sample Android app using Twitter / OAuth 1.0</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/08/08/improved-twitter-oauth-android/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>Oauth 2.0 flow in Android</title>
		<link>http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/</link>
		<comments>http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/#comments</comments>
		<pubDate>Sat, 06 Aug 2011 23:10:48 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[OAuth]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[latitude]]></category>
		<category><![CDATA[oauth]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=1025</guid>
		<description><![CDATA[In this article, I&#8217;m going to show you how you can implement an OAuth 2.0 flow in Android. We&#8217;ll be using&#160; the Google Latitude API as a sample Google API (one that has recently received Oauth 2.0 support) the Google APIs Client Library for Java to help us out with the OAuth 2.0 flow the [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tbody>
<tr>
<td>In this article, I&#8217;m going to show you how you can implement an <strong>OAuth 2.0</strong> flow in <strong>Android</strong>.<br />
We&#8217;ll be using&nbsp;</p>
<ul>
<li>the <a href="http://code.google.com/apis/latitude/" target="_blank">Google Latitude API </a> as a sample Google API (one that has recently received Oauth 2.0 support)</li>
<li>the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a> to help us out with the OAuth 2.0 flow</li>
<li>the <a href="http://code.google.com/p/google-api-java-client/wiki/APILibraries#Google_Latitude_API" target="_blank">Latitude client library</a> to interact with the Latitude API.</li>
</ul>
<p>In the <a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient" target="_blank">sample application</a>, we&#8217;re going to execute 1 authorized API call to the Latitude API. The call will return the current location of the user.</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/latitude-oauth2.png"><img class="aligncenter size-full wp-image-1039" title="latitude-oauth2" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/latitude-oauth2.png" alt="" width="306" height="175" /></a></td>
</tr>
</tbody>
</table>
</div>
<h2><span id="more-1025"></span></h2>
<h2>The sample application</h2>
<p>In the <a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient" target="_blank">sample application</a>, all dependencies are included in the lib folder, so you should be able to checkout everything from Git, import it in your Eclipse IDE, change your Oauth2 properties in <a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient/blob/master/src/com/ecs/android/sample/oauth2/OAuth2ClientCredentials.java">the OAuth2ClientCredentials class</a>, and run the project on your emulator or phone.</p>
<p>The project structure should look like this after a succesful checkout / build :</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/project_setup.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/project_setup-285x300.png" alt="" title="project_setup" width="285" height="300" class="aligncenter size-medium wp-image-1077" /></a><br />
The project depends on the following libraries :</p>
<ul>
<li>lib/commons-codec-1.3.jar</li>
<li>lib/commons-logging-1.1.1.jar</li>
<li>lib/google-api-client-1.4.1-beta.jar</li>
<li>lib/google-api-client-googleapis-1.4.1-beta.jar</li>
<li>lib/google-api-services-latitude-v1-1.1.0-beta.jar</li>
<li>lib/gson-1.6.jar</li>
<li>lib/guava-r09.jar</li>
<li>lib/httpclient-4.0.3.jar</li>
<li>lib/httpcore-4.0.1.jar</li>
<li>lib/jackson-core-asl-1.6.7.jar</li>
</ul>
<h2>Google API client for Java</h2>
<p><a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a> makes it very easy to interact with various Google APIs. The library has <a href="http://code.google.com/p/google-api-java-client/wiki/APILibraries" target="_blank">a set of generated client libraries</a> that hide a lot of the complexities when interacting with Google APIs.<br />
As an example, to get the current location of the user using the Latitude API, all it takes is the following 3 lines of code.</p>
<pre class="brush: java;">
Latitude latitude = new Latitude(transport, accessProtectedResource, jsonFactory);
latitude.apiKey=OAuth2ClientCredentials.API_KEY;
LatitudeCurrentlocationResourceJson currentLocation = latitude.currentLocation.get().execute();
</pre>
<p>What the code above does is the following</p>
<ul>
<li>Initialize a Latitude service definition object, the main gateway to the Latitude API. The object is initiazed with an HTTP Transport, an HTTP request initializer and a JSON factory.</li>
<li>We specify an API key on  the Latitude service defintion object, so we can track the API usage in the Google APIs console.</li>
<li>We execute a GET request on the currentLocation endpoint.</li>
</ul>
<p>In order to initialize the Latitude service definition,</p>
<ul>
<li>we specify an HTTP transport, as the Latitude API like all Google APIs is a REST based API, where all communication is done over HTTP.</li>
<li>we specify an HTTP request initializer, as we need to ensure that the API calls are properly authorized. (meaning that the proper authorization headers get filled in with our OAutn 2.0 token).</li>
<li>we specify a JSON Factory object, so that the responses coming back from the API can be serialized into a clean java based model.</li>
</ul>
<p>So in short, as a developer, there&#8217;s no need to write plumbing code to create HTTP request objects, parse responses, making sure everything is properly signed&#8230;. all of that plumbing is handled by the Google API client for Java library, and the Latitude generate client library.</p>
<p>However, before we can actually start making these calls, we need to make sure we have an OAuth 2.0 access token. If we attempt to call the API in a non-secured way, we&#8217;ll get the following exception.</p>
<pre class="brush: java;">
com.google.api.client.http.HttpResponseException: 401 Unauthorized
     at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:380)
     at com.google.api.services.latitude.Latitude$RemoteRequest.execute(Latitude.java:550)
     at com.google.api.services.latitude.Latitude$CurrentLocation$Get.executeUnparsed(Latitude.java:222)
     at com.google.api.services.latitude.Latitude$CurrentLocation$Get.execute(Latitude.java:207)
     at com.ecs.android.sample.oauth2.AndroidOauthGoogleApiJavaClient.getCurrentLocation(AndroidOauthGoogleApiJavaClient.java:107)
     at com.ecs.android.sample.oauth2.AndroidOauthGoogleApiJavaClient.performApiCall(AndroidOauthGoogleApiJavaClient.java:80)
</pre>
<h2>Preparing your app for OAuth 2.0</h2>
<p>Before you can run the application, you&#8217;ll need to get a hold of an OAuth client ID, and an API key for Google Latitude. Both things can be retrieved from the <a href="http://code.google.com/apis/console" target="_blank">Google API console</a>. The Google API console allows you to define one or more projects. Create a project, and make sure that for &#8220;Latitude API&#8221;, the status switch is flipped to the &#8220;ON&#8221; position.</p>
<div class="separator" style="clear: both; text-align: center;"><a style="margin-left: 1em; margin-right: 1em;" href="http://3.bp.blogspot.com/-uSGINxmF6qs/TjwJxGuYL4I/AAAAAAAACOY/MSSejQ-ckIU/s1600/latitude_enabled.PNG"><img src="http://3.bp.blogspot.com/-uSGINxmF6qs/TjwJxGuYL4I/AAAAAAAACOY/MSSejQ-ckIU/s400/latitude_enabled.PNG" border="0" alt="" width="400" height="383" /></a></div>
<p>Next, click on &#8220;API Access&#8221;. You should see the following screen :</p>
<div class="separator" style="clear: both; text-align: center;"><a style="margin-left: 1em; margin-right: 1em;" href="http://4.bp.blogspot.com/-uRY4mHSo6h8/TjwHxscX4yI/AAAAAAAACNw/fIpHbupKp0M/s1600/console1.PNG"><img src="http://4.bp.blogspot.com/-uRY4mHSo6h8/TjwHxscX4yI/AAAAAAAACNw/fIpHbupKp0M/s400/console1.PNG" border="0" alt="" width="400" height="292" /></a></div>
<p>Click on &#8220;Create an OAuth 2.0 Client ID&#8230;&#8221;. Choose a product name, and optionally load up an image and click &#8220;Next&#8221;.  (the product name and image will be shown to the user when your application is requesting him to authorize access).</p>
<div class="separator" style="clear: both; text-align: center;"><a style="margin-left: 1em; margin-right: 1em;" href="http://3.bp.blogspot.com/-GQQYeOXCPs8/TjwHyi4mVEI/AAAAAAAACOA/OspgIvzQ0pA/s1600/console3.PNG"><img src="http://3.bp.blogspot.com/-GQQYeOXCPs8/TjwHyi4mVEI/AAAAAAAACOA/OspgIvzQ0pA/s400/console3.PNG" border="0" alt="" width="400" height="296" /></a></div>
<p>Make sure you select &#8220;Installed application&#8221; and click &#8220;Create client ID&#8221;.</p>
<div class="separator" style="clear: both; text-align: center;"><a style="margin-left: 1em; margin-right: 1em;" href="http://1.bp.blogspot.com/-khlAHCf_uaY/TjwHysjoYcI/AAAAAAAACOI/I7L6zJ2DV_A/s1600/console-installed-app.PNG"><img src="http://1.bp.blogspot.com/-khlAHCf_uaY/TjwHysjoYcI/AAAAAAAACOI/I7L6zJ2DV_A/s400/console-installed-app.PNG" border="0" alt="" width="400" height="222" /></a></div>
<p>You should see the following summary</p>
<div class="separator" style="clear: both; text-align: center;"><a style="margin-left: 1em; margin-right: 1em;" href="http://4.bp.blogspot.com/-0OqrNhEgMBk/TjwYladI65I/AAAAAAAACO4/c8UWJHtx4ns/s1600/console-summary.PNG"><img src="http://4.bp.blogspot.com/-0OqrNhEgMBk/TjwYladI65I/AAAAAAAACO4/c8UWJHtx4ns/s400/console-summary.PNG" border="0" alt="" width="389" height="400" /></a></div>
<p>This summary contains 2 important items</p>
<ul>
<li>The OAuth Client ID / Secret</li>
<li>The API key</li>
</ul>
<p>You need the Oauth Client ID to setup your Oauth 2.0 communication. The API key is used to track the Latitude API usage in the console when clicking on the <strong>Reports</strong> link.<br />
Before running the application, make sure you specify the Oauth 2.0 client ID, client secret and API key in <a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient/blob/master/src/com/ecs/android/sample/oauth2/OAuth2ClientCredentials.java">the OAuth2ClientCredentials class</a></p>
<h2>The OAuth 2.0 flow in Android</h2>
<p>The first thing we need to before we can make a call to the Latitude API is to obtain an OAuth 2.0 access token. This token is obtained through a series of HTTP interactions between the application and the service provider (Google in this case). The first step is to present the user with an authorization screen, allowing him to authorize our application to access his Latitude API.</p>
<h2>The authorization web page</h2>
<p>This authorizationUrl can be generated using the GoogleAuthorizationRequestUrl object, provided by the Google API client for Java.<br />
The GoogleAuthorizationRequestUrl  is a Google extension to the OAuth 2.0 (draft 10) URL builder for an authorization web page to allow the end user to authorize the application to access their protected resources.</p>
<pre class="brush: java;">
	 String authorizationUrl = new GoogleAuthorizationRequestUrl(OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.OAUTH_CALLBACK_URL, OAuth2ClientCredentials.SCOPE).build();
</pre>
<p>What&#8217;s important to note here is that we need to provide our OAuth 2.0 client ID (that we can found in the APIs console), a callback URL (after the user has authorized the request, Google will issue a redirect to this URL), and the<br />
autorization scope.</p>
<p>The Latitude API provides the following <a href="http://code.google.com/apis/latitude/v1/using_rest.html#auth" target="_blank">OAuth 2.0 based scopes</a> :</p>
<p><strong>https://www.googleapis.com/auth/latitude.current.city </strong><br />
Access to current location at city granularity.<br />
<strong>https://www.googleapis.com/auth/latitude.current.best </strong><br />
Access to best-available current location.<br />
<strong>https://www.googleapis.com/auth/latitude.all.city </strong><br />
Access to current location and location history at city granularity.<br />
<strong>https://www.googleapis.com/auth/latitude.all.best</strong><br />
Access to best-available current and past locations.</p>
<p>The generated URL that looks like this:</p>
<p>https://accounts.google.com/o/oauth2/auth?client_id=1021221231376.apps.googleusercontent.com&#038;redirect_uri=http://localhost&#038;response_type=code&#038;scope=https://www.googleapis.com/auth/latitude.all.best</p>
<p>The page looks like this:</p>
<p style="text-align: center;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize_screen2.png"><img class="aligncenter size-full wp-image-1044" title="OAuth 2.0 authorization screen" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/08/authorize_screen2.png" alt="OAuth 2.0 authorization screen" width="288" height="480" /></a></p>
<p>Notice how the image and product name is shown on the authorization page.</p>
<p>In our Android sample application, we&#8217;ll load up this URL in a WebView. The reason why I&#8217;ve opted to use a WebView is because we need a hook somewhere to intercept the page when the user authorizes the request. Google OAuth 2.0 has some limitations regarding the redirect URIs. In a previous article, where I showed you how to implement the OAuth 1.0 flow in Android, we used a custom scheme in our Oauth redirect URL (xoauth://callback). With OAuth 2.0 this is no longer possible. In our case, we&#8217;re using http://localhost as a callback, and we&#8217;ll use Webview to intercept this page, so that we can retrieve the code.</p>
<p>There are other advantages of using a Webview. For example, the Webview doesn&#8217;t have an address bar, so the user cannot navigate away from the page. Also, the Webview doesn&#8217;t interfere with your browser app, something you will have when you pop the browser app from your Android application.</p>
<p>We start by creating a WebView component, and putting it as the main content of the activity.</p>
<pre class="brush: java;">
		WebView webview = new WebView(this);
        webview.getSettings().setJavaScriptEnabled(true);
        webview.setVisibility(View.VISIBLE);
        setContentView(webview);
</pre>
<p>We create a WebViewClient, needed to have a hook when the user has authorized the request, and we need to intercept the code.<br />
In this code, we check if the URL loaded into the webview is our redirect URL (simple startswith check). If this is the case, there can be 2 options :</p>
<p>The user authorized the request, meaning a code request parameter will be present in the URL. If this is the case, we retrieve the code from the URL, and create a GoogleAuthorizationCodeGrant object.<br />
We pass on our transport, a JSON factory, our OAuth 2.0 client ID and client secret, our code and our callback URL. When we execute the GoogleAuthorizationCodeGrant, we get a AccessTokenResponse that contains our OAuth 2.0 access token and refresh token.</p>
<p>We store the token response in our shared preferences, hide the webview (hack to ensure the user doesn&#8217;t see the redirect URL being loaded in the webview, as we only need it to fetch the code, and not to display the URL), and start our main activity again. (In the main activity, we perform the Latitude API call, only this this time we&#8217;ll have a valid access token.</p>
<pre class="brush: java;">
        /* WebViewClient must be set BEFORE calling loadUrl! */
        webview.setWebViewClient(new WebViewClient() {

        	@Override
            public void onPageFinished(WebView view, String url)  {

            	if (url.startsWith(OAuth2ClientCredentials.OAUTH_CALLBACK_URL)) {
            		try {

            			if (url.indexOf(&quot;code=&quot;)!=-1) {

	            			String code = extractCodeFromUrl(url);

				  		      AccessTokenResponse accessTokenResponse = new GoogleAuthorizationCodeGrant(new NetHttpTransport(),
										      new JacksonFactory(),
										      OAuth2ClientCredentials.CLIENT_ID,
										      OAuth2ClientCredentials.CLIENT_SECRET,
										      code,
										      OAuth2ClientCredentials.OAUTH_CALLBACK_URL).execute();

				  		      CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
				  		      credentialStore.write(accessTokenResponse);
				  		      view.setVisibility(View.INVISIBLE);
				  		      startActivity(new Intent(PrepareRequestTokenActivity.this,AndroidOauthGoogleApiJavaClient.class));
            			} else if (url.indexOf(&quot;error=&quot;)!=-1) {
            				new SharedPreferencesCredentialStore(prefs).clearCredentials();
            				startActivity(new Intent(PrepareRequestTokenActivity.this,AndroidOauthGoogleApiJavaClient.class));
            			}

					} catch (IOException e) {
						e.printStackTrace();
					}

            	}
                System.out.println(&quot;onPageFinished : &quot; + url);

            }
        });
</pre>
<p>The following code simply loads up the authorizationUrl into the webview.</p>
<pre class="brush: java;">
        String authorizationUrl = new GoogleAuthorizationRequestUrl(OAuth2ClientCredentials.CLIENT_ID, OAuth2ClientCredentials.OAUTH_CALLBACK_URL, OAuth2ClientCredentials.SCOPE).build();
        webview.loadUrl(authorizationUrl);
</pre>
<h2>Access / Refresh Tokens</h2>
<p>The sample application contains <a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient/blob/master/src/com/ecs/android/sample/oauth2/store/SharedPreferencesCredentialStore.java" target="_blank">a simple SharedPreferencesCredentialStore class</a> that we&#8217;ll use to store the Oauth 2.0 tokens, and retrieve them when we want to make an API call. Once we have the OAuth 2.0 tokens in our shared preferences, there&#8217;s no need to pop the Webview again, as the user has already authorized the request.</p>
<h2>Executing the API call</h2>
<p>The actual code to perform the secured API call can be found here.</p>
<pre class="brush: java;">
	private void performApiCall() {
		try {
			JsonFactory jsonFactory = new JacksonFactory();
			HttpTransport transport = new NetHttpTransport();

			CredentialStore credentialStore = new SharedPreferencesCredentialStore(prefs);
			AccessTokenResponse accessTokenResponse = credentialStore.read();

			GoogleAccessProtectedResource accessProtectedResource = new GoogleAccessProtectedResource(accessTokenResponse.accessToken,
			        transport,
			        jsonFactory,
			        OAuth2ClientCredentials.CLIENT_ID,
			        OAuth2ClientCredentials.CLIENT_SECRET,
			        accessTokenResponse.refreshToken);

		    final Latitude latitude = new Latitude(transport, accessProtectedResource, jsonFactory);
		    latitude.apiKey=OAuth2ClientCredentials.API_KEY;

			LatitudeCurrentlocationResourceJson currentLocation = latitude.currentLocation.get().execute();
			String locationAsString = convertLocationToString(currentLocation);
			textView.setText(locationAsString);
		} catch (Exception ex) {
			ex.printStackTrace();
			textView.setText(&quot;Error occured : &quot; + ex.getMessage());
		}
	}
</pre>
<ul>
<li>We start by creating a JSON Factory and an HTTP transport.</li>
<li>We retrieve our accessTokenResponse from the credentialStore (were put there when the user authorized access through the WebView).</li>
<li>We create our Latitude service definition object</li>
<li>We execute a GET request on the currentLocation, to retrieve a LatitudeCurrentlocationResourceJson object.</li>
<li>We output the current location on the screen.</li>
</ul>
<h2>Conclusion</h2>
<p>I was surprised to see that there was little documentation available on how to properly implement OAuth 2.0 on an Android platform. I have the feeling that the method being outlined here is currently the only way to do it properly. During the last Google I/O, there was <a href="http://www.google.com/events/io/2011/sessions/best-practices-for-accessing-google-apis-on-android.html" target="_blank">a session that covered OAuth 2.0 integration with the Android AccountManager</a>, meaning that you can authorize a user through the AccountManager. That should be more tightly coupled with the Android system, and you&#8217;re not forced to go through the Oauth 2.0 web based flow like we did here. Unfortunately, this didn&#8217;t seem to work for the LAtitude API. IT is possible to get it up and running with the Google Buzz and Google Tasks API, but it also doesn&#8217;t really make a great user experience. It&#8217;s also not documented at all, and unclear if Google sees this as the preferred way of using OAuth 2.0 on an Android platform. The talk also mentioned that they are not quite ready with it.<br />
So, to conclude, we&#8217;ve implemented the Oauth 2.0 webflow on an Android platform. Thanks to the Google API client for Java, very little code was required to setup the OAuth 2.0 dance, and using the WebView, we&#8217;ve ensured that we had a decent user experience, despite the fact that we needed to load up the Google authorization page. This approach can be used for any Google API, and although the <a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a> is very Google API centric, it can be used with other service providers as well.</p>
<h2>References</h2>
<ul>
<li><a href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a></li>
<li><a href="http://code.google.com/apis/latitude/" target="_blank">Google Latitude API </a></li>
<li><a href="http://code.google.com/apis/console" target="_blank">Google API console</a></li>
<li><a href="http://code.google.com/apis/accounts/docs/OAuth2.html" target="_blank">Google OAuth2</a></li>
<li><a href="http://www.eclipse.org/m2e/" target="_blank">Maven2 plugin for Eclipse</a></li>
<li><a href="https://github.com/ddewaele/AndroidOauth2GoogleApiJavaClient" target="_blank">Sample Android app using OAuth 2.0</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/08/06/oauth-2-0-flow-android/feed/</wfw:commentRss>
		<slash:comments>34</slash:comments>
		</item>
		<item>
		<title>Developing Android Home Screen Widgets</title>
		<link>http://blog.doityourselfandroid.com/2011/05/24/developing-android-home-screenwidgets/</link>
		<comments>http://blog.doityourselfandroid.com/2011/05/24/developing-android-home-screenwidgets/#comments</comments>
		<pubDate>Tue, 24 May 2011 19:58:26 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[UI Handling]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[broadcastreceiver]]></category>
		<category><![CDATA[intent]]></category>
		<category><![CDATA[widget]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=941</guid>
		<description><![CDATA[In this article, I&#8217;ll be showing you how to create a widget for the Android homescreen. Widgets can be useful to provide condensed information, without necessarily having to open your application. In addition to showing information, a widget can also be used to trigger certain actions related to your application. Instead of forcing the user [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tr>
<td>
In this article, I&#8217;ll be showing you how to create a widget for the Android homescreen. Widgets can be useful to provide condensed information, without necessarily having to open your application. In addition to showing information, a widget can also be used to trigger certain actions related to your application. Instead of forcing the user to open up your application and navigating to a certain screen to perform an action, a widget can provide the user with a quick shortcut to that action. You can also dynamically change the layout of your widget (ex: when the user presses a button, the button can be highlighted, or a piece of text can altered). This article is accompanied by <a href="https://github.com/ddewaele/AndroidWidgetSample" target="_blank">a sample android application</a> that includes the widgets we&#8217;ll be discussing here.
</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/AndroidLogoWidget.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/AndroidLogoWidget.png" alt="" title="AndroidLogoWidget" width="200" height="200" class="aligncenter size-full wp-image-983" /></a></p>
<td></tr>
</table>
</div>
<p><span id="more-941"></span></p>
<h2>Designing the widget</h2>
<p>An Android Widget can have different sizes. As can be seen in the screenshot below, the homescreen is divided into several squares, where each widget fits graphically with other widgets and with the other elements (like application shortcuts) of the Android Home screen.</p>
<p style="text-align: center;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/home_screen_raster.png"><img class="aligncenter size-full wp-image-961" title="home_screen_raster" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/home_screen_raster.png" alt="" width="290" height="482" /></a></p>
<p>The home screen contains 16 such squares (4&#215;4), and has a width of 320dp and a height of 400dp.</p>
<h2>Supported Widget sizes</h2>
<p>Depending on the screen orientation, your widget will have different dimensions. What does remain consistent is the number of squares the widget will occupy.<br />
There are six standard widget sizes. Three sizes related to the Home screen grid of 4 x 4 (portrait), the other 3 relate to the Home screen grid of  4 x 4 (landscape) cells.<br />
These dimensions correspond to the bounding boxes for the widget we&#8217;ll see in the next section.</p>
<p><b>portrait</b></p>
<p>4 x 1	squares, dimension 320 x 100<br />
3 x 3	squares, dimension 240 x 300<br />
2 x 2	squares, dimension 160 x 200</p>
<p><b>landscape</b></p>
<p>4 x 1	squares, dimension 424 x 74<br />
3 x 3	squares, dimension 318 x 222<br />
2 x 2	squares, dimension 212 x 148</p>
<p>In Android terminology, a Widget is made up of the following components</p>
<ul>
<li>A bounding box</li>
<li>A frame</li>
<li>The widget&#8217;s graphical controls and other elements.</li>
</ul>
<h2>The bounding box</h2>
<p>We&#8217;ll start by creating an image canvas for a 4&#215;1 widget. This needs to be 320&#215;100.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/photoshop_size_widget_4_1.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/photoshop_size_widget_4_1.png" alt="" title="photoshop_size_widget_4_1" width="415" height="365" class="aligncenter size-full wp-image-975" /></a></p>
<p>The bounding box is the full canvas you have at your disposal. We won&#8217;t be occupying all of that space, as we need to take into account the padding. Start by defining the frame that will form the boundaries of your image:</p>
<h2>The frame</h2>
<p>We need to ensure that sufficient padding (empty space) is available around the widget, as we don&#8217;t want it to take up too much space when placed alongside other widgets. As such, our Widget should be contained within a frame that we&#8217;ll define inside the bounding box, leaving some space on the top, bottom, left and right hand side of the bounding box.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box.png" alt="" title="bounding_box" width="385" height="153" class="aligncenter size-full wp-image-954" /></a></p>
<p>The actual content of the widgets shouldn&#8217;t draw to the edge of these dimensions, but fit inside a frame withing the bounding box, as described above.</p>
<p>We draw a rectangle inside the frame, and contract the selection to round the edges a bit.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/contract_selection.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/contract_selection.png" alt="" title="contract_selection" width="474" height="350" class="aligncenter size-full wp-image-974" /></a></p>
<p>In order to have a consistent look &#038; feel, you should apply the following blending options to your image: </p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/photoshop_layers.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/photoshop_layers.png" alt="" title="photoshop_layers" width="273" height="264" class="aligncenter size-full wp-image-964" /></a></p>
<h2>The widget&#8217;s graphical controls and other elements.</h2>
<p>As we&#8217;re going to add icons and text to our widget by putting Android Views on a Layout file, these shouldn&#8217;t be included in our final image. However, to get a visual idea on how the widget will look like, it might be interesting to put these controls onto your image. In Photoshop, just put them in seperate layers that you can exclude before saving the final PNG file.</p>
<p>Your image should look something like this:</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box_finished2.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box_finished2.png" alt="" title="bounding_box_finished2" width="332" height="122" class="aligncenter size-full wp-image-956" /></a></p>
<p>Save your widget artwork (without the controls) using the appropriate bounding box size in PNG-24 format on a transparent background and in 8-bit color.</p>
<p>Your image should look something like this:</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box_finished1.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/bounding_box_finished1.png" alt="" title="bounding_box_finished" width="339" height="124" class="aligncenter size-full wp-image-978" /></a></p>
<h2>Putting the widget on the screen.</h2>
<p>Now that we&#8217;ve got the graphics out of the way, it&#8217;s time to start coding&#8230;<br />
A Widget is basically a broadcast receiver, capable of listening for specific intents. One intent that the Widget is particulary interested in is the android.appwidget.action.APPWIDGET_UPDATE intent.</p>
<p>Now that we have designed our widget, we can add it to our application. In order to do that we need to execute the following steps:</p>
<h2>Define the widget in the manifest</h2>
<p>We start by defining our widget like this in the application Manifest.</p>
<pre class="brush: xml;">
        &lt;receiver android:name=&quot;.SampleWidgetProvider41_1&quot; android:label=&quot;@string/app_widget_4_1&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.appwidget.action.APPWIDGET_UPDATE&quot; /&gt;
            &lt;/intent-filter&gt;
            &lt;meta-data android:name=&quot;android.appwidget.provider&quot; android:resource=&quot;@xml/widget_provider_4_1&quot; /&gt;
        &lt;/receiver&gt;
</pre>
<p>The definition shows us the following :</p>
<ul>
<li>the widget is a broadcast receiver</li>
<li>the widget has an intent-filter, meaning it will listen for certain events</li>
<li>the widget that can be given a label. The label is shown in the list of widgets when the user wants to add a widget to the homescreen.</li>
<li>meta data is provided, providing a pointer to an XML resource, used to further define our widget.</li>
<p>We&#8217;ll provide a label in our strings.xml that will be used in the list of widgets.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;
    &lt;string name=&quot;hello&quot;&gt;Hello World, AndroidWidgetSample!&lt;/string&gt;
    &lt;string name=&quot;app_name&quot;&gt;AndroidWidgetSample&lt;/string&gt;
    &lt;string name=&quot;app_widget_4_1&quot;&gt;Our Widget 4x1&lt;/string&gt;
&lt;/resources&gt;
</pre>
<h2>Appwidget proviuder xml definition</h2>
<p>Next we need to create an appwidget provider definition. We specify a minimum height and width for the widget, as well as an update interval, and a pointer to our initial layout.</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;appwidget-provider xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:minWidth=&quot;72dip&quot;
    android:minHeight=&quot;72dip&quot;
    android:updatePeriodMillis=&quot;86400000&quot;
    android:initialLayout=&quot;@layout/latify_widget_1_1_100_100&quot;
/&gt;
</pre>
<p>For calculating the minWidth and minHeight, we need to some math.<br />
Because the Home screen&#8217;s layout orientation (and thus, the cell sizes) can change, as a rule of thumb, you should assume the worst-case cell size of 74 pixels for the height and width of a cell<br />
So, for a 1&#215;1 widget, by applying the formula (number of cells * 74) &#8211; 2, we arrive at a minWidth=72dip and minHeight=72dip. </p>
<p>The android:updatePeriodMillis defines the interval when the widget onUpdate method will be called. There is a minimum for this (so we cannot set this to whatever we want to have frequent updates on the widget). </p>
<p>It is documented somewhere but I wasn&#8217;t able to find it. In order to have more frequent updates on the Widget, you&#8217;ll need to implement an AlarmManager to send events to the Widget.</p>
<p>The initial layout is the actual layout file that our widget will use, leading us to the next section. </p>
<h2>Defining the layout</h2>
<p>The layout file is basically the same layout structure as you would use for a normal activity, however, you need to take certain space constraints into account. Android support different sizes when it comes to home screen widgets.</p>
<p>We&#8217;ll start with a very simple layout, that just uses our widget as a background image</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/widget&quot;
    android:layout_width=&quot;320dp&quot;
    android:layout_height=&quot;100dp&quot;
    android:focusable=&quot;true&quot;
    android:background=&quot;@drawable/widget4_1&quot;&gt;
&lt;/RelativeLayout&gt;
</pre>
<p>Notice how we also set the width and height to 320dp x 100dp as we&#8217;re dealing with a 4&#215;1 widget.</p>
<p>We&#8217;ll now add our icon and some text to the widget. Here&#8217;s the complete layout of the widget:</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;RelativeLayout xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
    android:id=&quot;@+id/widget&quot;
    android:layout_width=&quot;320dp&quot;
    android:layout_height=&quot;100dp&quot;
    android:focusable=&quot;true&quot;
    style=&quot;@style/WidgetBackground_4_1&quot;&gt;

        &lt;ImageView
        android:id=&quot;@+id/icon&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_marginTop=&quot;15dip&quot;
        android:layout_marginLeft=&quot;15dip&quot;
        android:layout_marginRight=&quot;10dip&quot;
        android:layout_marginBottom=&quot;0dip&quot;
        android:src=&quot;@drawable/icon&quot; /&gt;

    &lt;TextView
        android:id=&quot;@+id/word_title&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_toRightOf=&quot;@id/icon&quot;
        android:layout_marginTop=&quot;25dip&quot;
        android:layout_marginLeft=&quot;0dip&quot;
        android:layout_marginRight=&quot;10dip&quot;
        android:layout_marginBottom=&quot;0dip&quot;

        android:text=&quot;Our Widget Title&quot;
        style=&quot;@style/WidgetTitle&quot; /&gt;      

    &lt;TextView
        android:id=&quot;@+id/word_text&quot;
        android:layout_width=&quot;wrap_content&quot;
        android:layout_height=&quot;wrap_content&quot;
        android:layout_below=&quot;@id/word_title&quot;
        android:layout_toRightOf=&quot;@id/icon&quot;
        android:layout_marginTop=&quot;5dip&quot;
        android:layout_marginLeft=&quot;0dip&quot;
        android:layout_marginRight=&quot;10dip&quot;
        android:layout_marginBottom=&quot;0dip&quot;
        android:text=&quot;Our Widget Text comes here.&quot;
        style=&quot;@style/WidgetText&quot; /&gt;           

&lt;/RelativeLayout&gt;
</pre>
<p>You can use the Eclipse Graphical Layout to determine the correct margins, and get an idea on how the widget will look like.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/widget_eclipse_layout.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/widget_eclipse_layout.png" alt="" title="widget_eclipse_layout" width="607" height="410" class="aligncenter size-full wp-image-960" /></a></p>
<p>Also notice how we&#8217;ve applied a style for the layout. We&#8217;ll put stuff like background images, fonts into a styles.xml. The complete style definition for the widget looks like this :</p>
<pre class="brush: xml;">
&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
&lt;resources&gt;

	&lt;style name=&quot;WidgetBackground_4_1&quot;&gt;
        &lt;item name=&quot;android:background&quot;&gt;@drawable/widget_4_1&lt;/item&gt;
    &lt;/style&gt;

	&lt;style name=&quot;WidgetTitle&quot;&gt;
        &lt;item name=&quot;android:textSize&quot;&gt;18sp&lt;/item&gt;
        &lt;item name=&quot;android:textStyle&quot;&gt;bold&lt;/item&gt;
        &lt;item name=&quot;android:textColor&quot;&gt;@android:color/white&lt;/item&gt;
    &lt;/style&gt;

    &lt;style name=&quot;WidgetText&quot;&gt;
        &lt;item name=&quot;android:textSize&quot;&gt;12sp&lt;/item&gt;
        &lt;item name=&quot;android:textColor&quot;&gt;@android:color/white&lt;/item&gt;
    &lt;/style&gt;

&lt;/resources&gt;
</pre>
<h2>The AppWidgetProvider</h2>
<p>As with any element we define in the manifest (activities,services,broadcastreceivers), the actual implementation of the widget can be found in a java class, extending AppWidgetProvider.<br />
For now, create the SampleWidgetProvider4_1 like this:</p>
<pre class="brush: java;">
public class SampleWidgetProvider4_1 extends AppWidgetProvider {

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		// implementation will follow
	}
}
</pre>
<h2>Project structure</h2>
<p>Your project structure should look like this :</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/eclipse_project_layout.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/eclipse_project_layout.png" alt="" title="eclipse_project_layout" width="315" height="415" class="aligncenter size-full wp-image-957" /></a></p>
<p>To summarize so far, the project should contain :</p>
<ul>
<li>Widget defined in manifest (receiver element)</li>
<li>Widget provider xml definition in xml/widget_provider_4_1.xml</li>
<li>Widget layout file in layout/widget_layout_4_1.xml</li>
<li>Widget layout styles in values/styles.xml</li>
<li>Widget labels in values/strings.xml</li>
<li>Widget image files (backgrounds &#038; controls) in drawable</li>
<li>Widget AppWidgetProvider class in your source folder</li>
</ul>
<p>With these tasks out of the way, we&#8217;re able to display our Widget on the homescreen. Nothing else going on at the moment, so it&#8217;s time to start adding some widget behavior.<br />
The sample application contains 2 widgets (a 4&#215;1 widget and a 2&#215;2 widget). This is how they look like:</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/sample_widgets_layout.png"><img src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/sample_widgets_layout.png" alt="" title="sample_widgets_layout" width="360" height="600" class="aligncenter size-full wp-image-981" /></a></p>
<p>As you can see, they fit nicely on the home screen alongside the other icons.</p>
<h2>Widget Behavior</h2>
<p>Obviously, displaying a widget is one thing, making it act upon certain actions is another thing. </p>
<h2>Clicking on the widget</h2>
<p>The first thing we&#8217;ll do is make our Widget aware of the fact that the user has clicked on it. What typically happens in this type of scenario is that the main application is started.</p>
<p>In order to do that, we need to put the following code in our Widget onUpdate method:</p>
<pre class="brush: java;">
          // When we click the widget, we want to open our main activity.
          Intent launchActivity = new Intent(context,AndroidWidgetSample.class);
          PendingIntent pendingIntent = PendingIntent.getActivity(context,0, launchActivity, 0);
          remoteViews.setOnClickPendingIntent(R.id.widget, pendingIntent2);

          ComponentName thisWidget = new ComponentName(context, SampleWidgetProvider4_1.class);
          AppWidgetManager manager = AppWidgetManager.getInstance(context);
          manager.updateAppWidget(thisWidget, remoteViews);
</pre>
<p>As you can see, we set an OnClickPendingIntent on our widget. The Pending Intent will launch an Activity, in our case, the only activity in our sample, being the AndroidWidgetSample activity.<br />
The setOnClickPendingIntent is targeted to our entire widget (R.id.widget), and not to a specific control. This means that if we click on an area in our widget that doesn&#8217;t cover any other clickable controls, this activity will be launched. Note also that we need to call the updateAppWidget on the AppWidgetManager in order for it to respond to the onClick.</p>
<h2>Clicking on a specific control on the widget</h2>
<p>An activity can also contain certain controls that the user may want to manipulate. A widget might contain a play/stop button, or another component that you would like to specifically target. In our sample, we only have an icon and a piece of text, but we&#8217;ll make sure that a specific action is being triggered when clicking on the icon.</p>
<p>When the icon is clicked on the widget, we broadcast an intent containing the ACTION_WIDGET_UPDATE_FROM_WIDGET action.</p>
<pre class="brush: java;">
		  Intent intent = new Intent(context, SampleWidgetProvider4_1.class);
		  intent.setAction(Constants.ACTION_WIDGET_UPDATE_FROM_WIDGET);
		  intent.putExtra(Constants.INTENT_EXTRA_WIDGET_TEXT,&quot;Icon clicked on Widget&quot;);

          PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
          remoteViews.setOnClickPendingIntent(R.id.icon,actionPendingIntent);
</pre>
<p>Similar code to the one we saw before. Note here that the setOnClickPendingIntent is targeting the icon on our widget, so this intent will only be broadcast if we hit the icon on the widget.</p>
<p>In the manifest, the widget is configured with an intent filter to match this action. By doing this, we can intercept this intent in the onReceive method of the Widget (remember that the AppWidgetProvider is nothing more than a fancy BroadcastReceiver.</p>
<pre class="brush: xml;">
        &lt;receiver android:name=&quot;.SampleWidgetProvider4_1&quot; android:label=&quot;@string/app_widget_4_1&quot;&gt;
            &lt;intent-filter&gt;
                &lt;action android:name=&quot;android.appwidget.action.APPWIDGET_UPDATE&quot; /&gt;
                &lt;action android:name=&quot;ACTION.WIDGET.UPDATE.FROM.ACTIVITY&quot;/&gt;
                &lt;action android:name=&quot;ACTION_WIDGET_UPDATE_FROM_ALARM&quot;/&gt;
                &lt;action android:name=&quot;ACTION_WIDGET_UPDATE_FROM_WIDGET&quot;/&gt;
            &lt;/intent-filter&gt;
            &lt;meta-data android:name=&quot;android.appwidget.provider&quot; android:resource=&quot;@xml/widget_provider_4_1&quot; /&gt;
        &lt;/receiver&gt;
</pre>
<p>Note how I added some other actions as well, as this allows us to differentiate between different messages being sent to our widget. 		  </p>
<h2>Allowing Activities to update the Widget</h2>
<p>In order to update the Widget from our main activity, we&#8217;ve placed a button on the main layout, that does the following:</p>
<pre class="brush: java;">
		btnSendText = (Button) findViewById(R.id.btn_send_text);

        btnSendText.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
            	sendTextToWidget(AndroidWidgetSample.this);
            }
        });

    private void sendTextToWidget(Context context) {
		Intent uiIntent = new Intent(Constants.ACTION_WIDGET_UPDATE_FROM_ACTIVITY);
		SimpleDateFormat sdf = new SimpleDateFormat(&quot;hh:mm:ss&quot;);
		uiIntent.putExtra(Constants.INTENT_EXTRA_WIDGET_TEXT,&quot;Button clicked on Activity at &quot; + sdf.format(new Date()));
		context.sendBroadcast(uiIntent2);
    }
</pre>
<p>As you can see, the button does nothing more that broadcast an intent that will be picked up by our Widget. (same thing as with the icon click in the widget itself).	</p>
<h2>The Widget onReceive method</h2>
<p>All these actions are processed by the Widget through its onReceive method. Here, we can get a hold of the remoteView, and in our case, update the TextView using the setTextViewText method on the Widget. Keep in mind that a Widgets layout is not accessed in the same way as an Activities layout. We cannot execute a findViewById to get a reference to TextViews or Buttons. We always need to pass by the removeView.</p>
<pre class="brush: java;">
	@Override
	public void onReceive(Context context, Intent intent) {
		Log.i(Constants.TAG, &quot;onReceive called with &quot; + intent.getAction());
		RemoteViews remoteViews = new RemoteViews(context.getPackageName (), R.layout.widget_layout_4_1);
		if (intent.getAction().equals(Constants.ACTION_WIDGET_UPDATE_FROM_ACTIVITY)) {
			String widgetText = intent.getExtras().getString(Constants.INTENT_EXTRA_WIDGET_TEXT);
			remoteViews.setTextViewText(R.id.word_text, widgetText);
        } else if (intent.getAction().equals(Constants.ACTION_WIDGET_UPDATE_FROM_ALARM)) {
        	String widgetText = intent.getExtras().getString(Constants.INTENT_EXTRA_WIDGET_TEXT);
        	SimpleDateFormat sdf = new SimpleDateFormat(&quot;hh:mm:ss&quot;);
			remoteViews.setTextViewText(R.id.word_text, widgetText + &quot; at &quot; + sdf.format(new Date()) );
        } else if (intent.getAction().equals(Constants.ACTION_WIDGET_UPDATE_FROM_WIDGET)) {
			String widgetText = null;
			if (intent.getExtras()!= null) {
				widgetText = intent.getExtras().getString(Constants.INTENT_EXTRA_WIDGET_TEXT);
			} else {
				widgetText = &quot;Extras was null&quot;;
			}
        	SimpleDateFormat sdf = new SimpleDateFormat(&quot;hh:mm:ss&quot;);
			remoteViews.setTextViewText(R.id.word_text, widgetText + &quot; at &quot; + sdf.format(new Date()) );
        } else {
        	super.onReceive(context, intent);
        }
		ComponentName cn = new ComponentName(context, SampleWidgetProvider4_1.class);
		AppWidgetManager.getInstance(context).updateAppWidget(cn, remoteViews);

	}
</pre>
<p>If we want to highlight the icon when it has been clicked for example, we use the following code </p>
<pre class="brush: java;">
remoteViews.setImageViewResource(R.id.icon, R.drawable.icon_red);
</pre>
<p>This will simply put another drawable on the icon layout element, allowing for an image toggle effect.</p>
<h2>Conclusions</h2>
<p>Widgets can provide added value to your application by giving the user certain shortcuts, or giving them the opportunity to see vital information regarding your app by just looking at the home screen. When developing widgets, you do need to take into account certain constraints. You&#8217;ll need to adhere to certain size requirements, and you also need to be aware of the fact that Widgets are not the same as activities. The way you interact with them from a development perspective is different than what you&#8217;re used to when working with activities.</p>
<h2>References</h2>
<ul>
<li><a href="http://developer.android.com/guide/topics/appwidgets/index.html" target="_blank">Android Developers site &#8211; App Widgets</a></li>
<li><a href="http://developer.android.com/guide/practices/ui_guidelines/widget_design.html" target="_blank">Android Developers site &#8211; App Widgets &#8211; Design guidelines</a></li>
<li><a href="http://android-developers.blogspot.com/2009/04/introducing-home-screen-widgets-and.html" target="_blank">Android Developers blog &#8211; Home screen widgets</a></li>
<li><a href="https://github.com/ddewaele/AndroidWidgetSample" target="_blank">Sample code</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/05/24/developing-android-home-screenwidgets/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		</item>
		<item>
		<title>New way to create test users in Facebook</title>
		<link>http://blog.doityourselfandroid.com/2011/05/07/create-test-users-facebook/</link>
		<comments>http://blog.doityourselfandroid.com/2011/05/07/create-test-users-facebook/#comments</comments>
		<pubDate>Sat, 07 May 2011 19:58:47 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[Facebook SDK]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=915</guid>
		<description><![CDATA[Introduction As mentioned in the Facebook developer docs, test users can only be created using a call to the Graph API. As described in my previous Facebook article, a dedicated webpage was available at the time to create test users, however, that page has been brought offline.&#160; You can create a test user associated with [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<div class="borderless">
<table>
<tbody>
<tr>
<td>As mentioned in the <a href="http://developers.facebook.com/docs/test_users/" target="_blank">Facebook developer docs</a>, test users can only be created using a call to the Graph API.<br />
As described in my <a title="A 30 minute guide to integrating Facebook in your Android application" href="http://blog.doityourselfandroid.com/2011/02/28/30-minute-guide-integrating-facebook-android-application/" target="_blank">previous Facebook article</a>, a dedicated webpage was available at the time to create test users, however, that page has been brought offline.&nbsp;</p>
<p>You can create a test user associated with a particular app using the Graph API with your app access token.</p>
<pre class="brush: plain;">

https://graph.facebook.com/APP_ID/accounts/test-users?

  installed=true
  &amp;permissions=read_stream
  &amp;method=post
  &amp;access_token=APP_ACCESS_TOKEN
</pre>
</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookandroidlogo.jpg"><img class="aligncenter size-full wp-image-746" title="facebookandroidlogo" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookandroidlogo.jpg" alt="" width="224" height="159" /></a></td>
</tr>
</tbody>
</table>
</div>
<p>However, before we&#8217;ll be able call this API, we first need to retrieve an Access Token for our application.</p>
<p><span id="more-915"></span></p>
<h2>Application Access Token</h2>
<p>Before you get started, you might want to startup a text editor to copy paste some of these URLs and values (application ID, application secret, access token) as you&#8217;ll need to construct a lot of URLS that include these values.</p>
<p>In order to get an Access Token for our application, we need to know our Application Secret.</p>
<p>The first thing we&#8217;ll need is our <strong>Facebook Application ID</strong>. The Application ID is a unique identifier that you received while creating your application.<br />
We&#8217; can use the URL below to retrieve our Application Secret. Fill in your Application ID in the following URL to goto your Facebook App page and retrieve the Application Secret.</p>
<p>http://www.facebook.com/developers/editapp.php?app_id=<strong>YOUR_APP_ID</strong></p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/FaceBookEditAppPage1.png"><img class="aligncenter size-full wp-image-936" title="Facebook Edit Application" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/05/FaceBookEditAppPage1.png" alt="" width="970" height="285" /></a></p>
<p>Now that we have the Application ID and the Application Secret, we can retrieve an access token for our application. In order to do that, we need to call the following URL with our Application ID and Application Secret.</p>
<pre class="brush: plain;">

https://graph.facebook.com/oauth/access_token?

	client_id=YOUR_APP_ID
	&amp;client_secret=YOUR_APP_SECRET
	&amp;grant_type=client_credentials
</pre>
<p>You&#8217;ll receive the following response:</p>
<pre class="brush: plain;">
access_token=109688035775165|hZe8qX8el6Qlp0xMyoAb5giYRls
</pre>
<h2>Creating the test user</h2>
<p>Now that we have our access token, we can do the task at hand, and use the Graph API to call our test-user.</p>
<pre class="brush: plain;">

https://graph.facebook.com/APP_ID/accounts/test-users?

  installed=true
  &amp;permissions=read_stream
  &amp;method=post
  &amp;access_token=APP_ACCESS_TOKEN
</pre>
<p>With everything filled in, your request should look resemble something like this:</p>
<p>https://graph.facebook.com/109636235495125/accounts/test-users?installed=true&#038;permissions=read_stream&#038;method=post&#038;access_token=109636235495125|qZe8yX8eL6zlp0xMGoAj5girRlS</p>
<p>If all went well, you should get a response similar to this:</p>
<pre class="brush: plain;">
{
   &quot;id&quot;: &quot;10000123432213&quot;,
   &quot;access_token&quot;: &quot;109636235495125|2.DFDGayE7X1s9ft_N7k94_E__.3600.1304802000.0-100002332671439|HhwACDVFeNhQ_UV0tQY0mUzkvLs&quot;,
   &quot;login_url&quot;: &quot;https://www.facebook.com/platform/test_account_login.php?user_id=10000123432213&amp;n=R3feV4O7YrlIb0n&quot;,
   &quot;email&quot;: &quot;some_one\u0040tfbnw.net&quot;,
   &quot;password&quot;: &quot;3123123123133&quot;
}
</pre>
<p>This basically means your test user has been created, and you can login to Facebook with this account. Use the email address (some_one@tfbnw.net) to login, and the password provided in the response.</p>
<p>You can change the password to a more convenient value for testing.</p>
<h2>References</h2>
<ul>
<li><a href="http://developers.facebook.com/docs/test_users/" target="_blank">Facebook Test Users</a></li>
<li><a href="http://developers.facebook.com/roadmap/#tools" target="_blank">Facebook Tools Roadmap</a></li>
<li><a href="http://developers.facebook.com/docs/authentication/#applogin" target="_blank">Facebook OAuth Application Login</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/05/07/create-test-users-facebook/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>OAuth in Android using the Google APIs Client Library for Java</title>
		<link>http://blog.doityourselfandroid.com/2011/04/12/oauth-android-google-apis-client-library-java/</link>
		<comments>http://blog.doityourselfandroid.com/2011/04/12/oauth-android-google-apis-client-library-java/#comments</comments>
		<pubDate>Tue, 12 Apr 2011 17:23:54 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[OAuth Signpost]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[google-api-java-client]]></category>
		<category><![CDATA[oauth]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=839</guid>
		<description><![CDATA[Today we&#8217;ll be looking at the Google APIs Client Library for Java.  The API is provided by Google, and is a flexible, efficient, and powerful Java client library for accessing any HTTP-based API&#8217;s on the web. According to Google, it is the recommended library for accessing Google API&#8217;s based on REST or JSON-RPC. One of the nice [...]]]></description>
			<content:encoded><![CDATA[<div class="borderless">
<table>
<tbody>
<tr>
<td>Today we&#8217;ll be looking at the <a id="project_summary_link" href="http://code.google.com/p/google-api-java-client/" target="_blank">Google APIs Client Library for Java</a>.  The API is provided by Google, and is a flexible, efficient, and powerful Java client library for accessing any HTTP-based API&#8217;s on the web. According to Google, it is the recommended library for accessing Google API&#8217;s based on REST or JSON-RPC. One of the nice things about this library is that it fully supports the Android environment out of the box. So we&#8217;ll focus on those features in this article.</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2010/11/oauth-android-logo.png"><img class="aligncenter size-full wp-image-323" title="oauth-android-logo" src="http://blog.doityourselfandroid.com/wp-content/uploads/2010/11/oauth-android-logo.png" alt="oauth-android-logo" width="200" height="125" /></a></td>
</tr>
</tbody>
</table>
</div>
<p>To avoid confusion, Google offers the following APIs (the first one being the topic of this post, and compatible with the Android platform) :</p>
<ul>
<li>Google APIs Client Library for Java (<a href="http://code.google.com/p/google-api-java-client/" target="_blank">google-api-java-client</a>)</li>
<li>Google Data Java Client Library (<a href="http://code.google.com/p/gdata-java-client/" target="_blank">gdata-java-client</a>)</li>
</ul>
<p>Unfortunately, there are no samples available that perform the OAuth dance in Android using this library, so I thought I&#8217;d write one myself. The code for this article can be found in the <a href="https://github.com/ddewaele/AndroidOauthGoogleApiJavaClient" target="_bank">AndroidOauthGoogleApiJavaClient repository</a><br />
<span id="more-839"></span></p>
<p>The first thing we need to do is download the library. You can use the link above to download the library as a JAR file.</p>
<p>The library supports the following authentication mechanisms</p>
<ul>
<li><a href="http://code.google.com/p/google-api-java-client/wiki/OAuth" target="_blank">OAuth 1.0a</a></li>
<li>OAuth 2 draft 10 (<a rel="nofollow" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.2.0-alpha/com/google/api/client/auth/oauth2/package-summary.html" target="_blank">JavaDoc</a>, <a rel="nofollow" href="http://tools.ietf.org/html/draft-ietf-oauth-v2-10">specification</a></li>
<li><a href="http://code.google.com/p/google-api-java-client/wiki/AndroidAccountManager" target="_blank">Android AccountManager</a></li>
<li>Legacy Google methods
<ul>
<li><a href="http://code.google.com/p/google-api-java-client/wiki/ClientLogin" target="_blank">ClientLogin</a></li>
<li>AuthSub (<a rel="nofollow" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.2.0-alpha/com/google/api/client/googleapis/auth/authsub/package-summary.html" target="_blank">JavaDoc</a>, <a rel="nofollow" href="http://code.google.com/apis/accounts/docs/AuthSub.html" target="_blank">documentation</a>)</li>
</ul>
</li>
</ul>
<p>We&#8217;ll start by looking at the buzz-json-oauth-sample project, and see if we can port it to Android. The sample is a standalone java application that uses OAuth to let the user authorize the application to show his/her Buzz posts. It follows the standard OAuth flow. As this is not a web-application, the sample needs a way to capture the OAuth tokens after the user has granted access. It does so by starting  an embedded Jetty server to host a callback-URL, needed to capture the oauth access token.</p>
<p>In short, when we launch the application, the following happens :</p>
<ul>
<li>Setup the JSON/HTTP transport</li>
<li>Authorize the user using OAuth</li>
<li>
<ul>
<li>The application launches a browser to initiate the OAuth dance</li>
<li>After the user has authorized access, a callback is done to a local jetty</li>
<li>The landing page on the local jetty allows us to capture the oauth access token</li>
</ul>
</li>
<li>Perform authorized API calls to Google Buzz</li>
</ul>
<p>Our Android based implementation will follow the same steps, but without the local jetty callback offcourse. With Android we can use the intent mechanism to capture the oauth access token, so there&#8217;s no need to start a local HTTP server.</p>
<h4>Setting up the transport</h4>
<p>The Google API Client library for Java abstracts the HTTP transport through an  <a title="HTTP Transport" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.3.1-alpha/com/google/api/client/http/HttpTransport.html" target="_blank">com.google.api.client.http.HttpTransport</a> object. As noted in the documentation, the recommended concrete implementation HTTP transport library to use depends on what environment you are running in. As we&#8217;re writing an Android application here, we&#8217;ll be using the com.google.api.client.apache.ApacheHttpTransport.</p>
<p>We&#8217;ll define our Transport in a Util class</p>
<pre class="brush: java;">
	static HttpTransport newTransport() {
		HttpTransport result = new ApacheHttpTransport();
		GoogleUtils.useMethodOverride(result);
		GoogleHeaders headers = new GoogleHeaders();
		headers.setApplicationName(&quot;Google-BuzzSample/1.0&quot;);
		result.defaultHeaders = headers;
		return result;
	}
</pre>
<p>Next, we need to add an HTTP response content parser to the transport, so that we can parse the response coming the transport.</p>
<pre class="brush: java;">
	private static void setUpTransport() {
		JsonCParser parser = new JsonCParser();
		parser.jsonFactory = JSON_FACTORY;
		TRANSPORT.addParser(parser);
	}
</pre>
<h4>Signing requests</h4>
<p>OAuth is all about retrieving tokens using signed requests. By obtaining an OAuth access token at the final step of the OAuth flow, the application can do authorized API calls on behalf of the user. As the OAuth specification mandates that all requests are properly signed, the signing process is very important in OAuth.</p>
<p>The <a title="OAuth signer object" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.3.1-alpha/com/google/api/client/auth/oauth/OAuthHmacSigner.html" target="_blank">OAuthHmacSigner </a>object is the object responsible for signing requests, and as such is very important in the OAuth flow, as it is required to sign all requests so that they can pass as authorized requests.<br />
The OAuthHmacSigner is initialized like this :</p>
<pre class="brush: java;">
			signer = new OAuthHmacSigner();
			signer.clientSharedSecret = Constants.CONSUMER_SECRET;
</pre>
<p>At the start of the OAuth flow, when the user hasn&#8217;t authorized access yet, the signer object contains</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>clientsharedsecret</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>tokensharedsecret</td>
<td><code>EMPTY</code></td>
</tr>
</tbody>
</table>
<p>Notice how the tokensharedsecret is not available in the start of the OAuth dance. This value will be filed in after we&#8217;ve fetched the Request Token.</p>
<h4>Request Token</h4>
<p>Our Android activity uses the following code to launch the OAuth flow :</p>
<pre class="brush: java;">
		// Launch the OAuth flow to get an access token required to do authorized API calls.
		// When the OAuth flow finishes, we redirect to this Activity to perform the API call.
		launchOauth.setOnClickListener(new View.OnClickListener() {
			public void onClick(View v) {
				startActivity(new Intent().setClass(v.getContext(),
						PrepareRequestTokenActivity.class));
			}
		});
</pre>
<p>As you can see, a seperate activity (PrepareRequestTokenActivity) is used to fetch the actual request token. This activity does nothing more then initializing our Signer object, and starting an asyncTask called OAuthRequestTokenTask.</p>
<pre class="brush: java;">
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
    	try {
			signer = new OAuthHmacSigner();
			signer.clientSharedSecret = Constants.CONSUMER_SECRET;
    	} catch (Exception e) {
    		Log.e(TAG, &quot;Error creating consumer / provider&quot;,e);
		}
        Log.i(TAG, &quot;Starting task to retrieve request token.&quot;);
		new OAuthRequestTokenTask(this,signer).execute();
	}
</pre>
<p>We start the OAuth dance by fetching a<strong> Request Token</strong>. This is done in the OAuthRequestTokenTask by creating a <a title="GoogleOAuthGetTemporaryToken" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.3.1-alpha/com/google/api/client/googleapis/auth/oauth/GoogleOAuthGetTemporaryToken.html" target="_blank">GoogleOAuthGetTemporaryToken</a>. This object will allow us to fetch our initial token, the <strong>Request Token</strong>.</p>
<p>The GoogleOAuthGetTemporaryToken represents a generic Google OAuth 1.0a URL to request a temporary credentials token (also known as the &#8220;request token&#8221;) from the Google Authorization server.</p>
<pre class="brush: java;">
			GoogleOAuthGetTemporaryToken temporaryToken = new GoogleOAuthGetTemporaryToken();
			temporaryToken.transport = Util.AUTH_TRANSPORT;

			temporaryToken.signer = signer;
			temporaryToken.consumerKey = Constants.CONSUMER_KEY;
			temporaryToken.scope = Constants.SCOPE;
			temporaryToken.displayName = Util.APP_DESCRIPTION;
			temporaryToken.callback = Constants.OAUTH_CALLBACK_URL;
			OAuthCredentialsResponse tempCredentials = temporaryToken.execute();
</pre>
<p>The GoogleOAuthGetTemporaryToken object contains</p>
<table>
<tbody>
<tr>
<th>Object</th>
<th>Value</th>
</tr>
<tr>
<td>Our signer object</td>
<td><code>com.google.api.client.auth.oauth.OAuthHmacSigner</code></td>
</tr>
<tr>
<td>Consumer Key</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>Scope</td>
<td><code>https://www.googleapis.com/auth/buzz</code></td>
</tr>
<tr>
<td>Displayname</td>
<td><code>Buzz API Java Client Sample</code></td>
</tr>
<tr>
<td>Callback URL</td>
<td><code>x-oauthflow://callback</code></td>
</tr>
</tbody>
</table>
<p>The GoogleOAuthGetTemporaryToken toString() method looks like this :</p>
<p><code>https://www.google.com/accounts/OAuthGetRequestToken?scope=https://www.googleapis.com/auth/buzz&amp;xoauth_displayname=Buzz%20API%20Java%20Client%20Sample</code></p>
<p>In order to retrieve a request token, we call the GoogleOAuthGetTemporaryToken execute() method, like this :</p>
<pre class="brush: java;">
OAuthCredentialsResponse tempCredentials = temporaryToken.execute();
</pre>
<p>By calling the execute() method, Google verifies that the requesting application has been registered with Google or is using an approved signature (in the case of installed applications). The temporary token acquired with this request is found in OAuthCredentialsResponse This temporary token is used in GoogleOAuthAuthorizeTemporaryTokenUrl to direct the end user to a Google Accounts web page to allow the end user to authorize the temporary token (see next step &#8211; Authorize Token).</p>
<p>The exeucte() method returns a <strong>com.google.api.client.auth.oauth.OAuthCredentialsResponse</strong>, containing our request token, and token secret.</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>token</td>
<td><code>4/hFOwXawX4WNVVcfPgYSWlidypOAL</code></td>
</tr>
<tr>
<td>tokensecret</td>
<td><code>skaOU3r8uhovUSuTyFhsscLV</code></td>
</tr>
</tbody>
</table>
<p>These 2 values are very important. We&#8217;ll to asign :</p>
<ul>
<li>the <strong>tokenSecret </strong> (shared-secret for use with &#8220;HMAC-SHA1&#8243; signature algorithm) onto the signer object we defined earlier.</li>
<li>the <strong>token</strong> to our OAuthAuthorizeTemporaryTokenUrl object that we&#8217;ll create now.</li>
</ul>
<p>So after having retrieved the request token, we can assign the tokenSecret to our signer object. Our signer object now contains this :</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>clientsharedsecret</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>tokensharedsecret</td>
<td><code>skaOU3r8uhovUSuTyFhsscLV</code></td>
</tr>
</tbody>
</table>
<h4>Authorize Token</h4>
<p>Next step in the OAuth dance is to retrieve the authorize token. In order to do that, we create a <a title="GoogleOAuthAuthorizeTemporaryTokenUrl" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.3.1-alpha/com/google/api/client/googleapis/auth/oauth/GoogleOAuthAuthorizeTemporaryTokenUrl.html" target="_blank">OAuthAuthorizeTemporaryTokenUrl</a>. This object is an OAuth 1.0a URL builder for an authorization web page to allow the end user to authorize the temporary token.</p>
<p>This object contains the following properties.</p>
<pre class="brush: java;">
			OAuthAuthorizeTemporaryTokenUrl authorizeUrl = new OAuthAuthorizeTemporaryTokenUrl(Constants.AUTHORIZE_URL);
			authorizeUrl.set(&quot;scope&quot;, temporaryToken.scope);
			authorizeUrl.set(&quot;domain&quot;, Constants.CONSUMER_KEY);

			authorizeUrl.set(&quot;xoauth_displayname&quot;, Util.APP_DESCRIPTION);
			authorizeUrl.temporaryToken = tempToken = tempCredentials.token;
</pre>
<p>The <strong>scope </strong>and the <strong>domain </strong>are mandatory fields we need to set on the <strong>OAuthAuthorizeTemporaryTokenUrl </strong>object. API specific values need to be set on this object. For example, the Google Latitude API supports the location=&#8221;all&#8221; and granulariy=&#8221;best&#8221; fields on the authorization endpoint. As such, the can be set like this:</p>
<pre class="brush: java;">
authorizeUrl.put(&quot;location&quot;, &quot;all&quot;);
authorizeUrl.put(&quot;granularity&quot;, &quot;best&quot;);
</pre>
<p>But as we&#8217;re using the Google Buzz API here,  you can see, we set the following properties :</p>
<table>
<tbody>
<tr>
<th>Object</th>
<th>Value</th>
</tr>
<tr>
<td>Domain</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>Scope</td>
<td><code>https://www.googleapis.com/auth/buzz</code></td>
</tr>
<tr>
<td>xoauth_displayname</td>
<td><code>Buzz API Java Client Sample</code></td>
</tr>
<tr>
<td>temporaryToken</td>
<td><code>4/hFOwXawX4WNVVcfPgYSWlidypOAL</code></td>
</tr>
</tbody>
</table>
<p>The OAuthAuthorizeTemporaryTokenUrl toString looks like this :</p>
<p><code></p>
<p>https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?scope=https://www.googleapis.com/auth/buzz&#038;domain=anonymous&#038;xoauth_displayname=Buzz%20API%20Java%20Client%20Sample</p>
<p></code></p>
<p>To retrieve the actual Authorization URL, we call the <strong>authorizeUrl.build() </strong>method. This gives us the actual Authorization URL we&#8217;ll need to show the user in a browser.</p>
<p><code></p>
<p>https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?oauth_token=4/hFOwXawX4WNVVcfPgYSWlidypOAL&#038;scope=https://www.googleapis.com/auth/buzz&#038;domain=anonymous&#038;xoauth_displayname=Buzz%20API%20Java%20Client%20Sample</p>
<p></code></p>
<p>In our Android application, we&#8217;ll use this URL to pop a browser, as at this point user interaction is required in order for him/her to authorize the request.<br />
This is done using the following code :</p>
<pre class="brush: java;">
			Log.i(TAG, &quot;Popping a browser with the authorize URL : &quot; + url);
			Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url)).setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_FROM_BACKGROUND);
			context.startActivity(intent);
</pre>
<p>After the user has granted access, he has authorized our temporary token. After this authorization, we can capturing the following 2 important fields</p>
<ul>
<li>oauth_verifier</li>
<li>oauth_token</li>
</ul>
<p>These parameters are embedded in the URL after the user has granted access. In Android, capturing these parameters is done via the callback URL we specified in the beginning. This callback URL is the URL that is shown in the browser after the user has authorized the request. In our Android application, we have defined an activity with an intent-filter, listening for that callback URL.</p>
<pre class="brush: xml;">
		&lt;activity android:name=&quot;.oauth.PrepareRequestTokenActivity&quot; android:launchMode=&quot;singleTask&quot;&gt;&gt;
			&lt;intent-filter&gt;
				&lt;action android:name=&quot;android.intent.action.VIEW&quot; /&gt;
				&lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
				&lt;category android:name=&quot;android.intent.category.BROWSABLE&quot; /&gt;
				&lt;data android:scheme=&quot;x-oauthflow&quot; android:host=&quot;callback&quot; /&gt;
			&lt;/intent-filter&gt;
		&lt;/activity&gt;
</pre>
<p>This means that when our callback URL (x-oauthflow://callback) is shown in the browser, our Activity kicks in, and its onNewIntent method is called. In this method, we capture the oauth_token and oauth_verifier like his :</p>
<pre class="brush: java;">
	/**
	 * Called when the OAuthRequestTokenTask finishes (user has authorized the request token).
	 * The callback URL will be intercepted here so we can fetch the token and token secret.
	 */
	@Override
	public void onNewIntent(Intent intent) {
		super.onNewIntent(intent);
		SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
		final Uri uri = intent.getData();
		if (uri != null &amp;&amp; uri.getScheme().equals(Constants.OAUTH_CALLBACK_SCHEME)) {
			Log.i(TAG, &quot;Callback received : &quot; + uri);
			new RetrieveAccessTokenTask(this,signer,prefs).execute(uri);
			finish();
		}
	}
</pre>
<p>As you can see, we capture the URL, and pass it on to our RetrieveAccessTokenTask, where we can actually fetch our access token.</p>
<h4>Access token</h4>
<p>Capturing the 2 fields (oauth_verifier and oauth_token) is done in the RetrieveAccessTokenTask. We retrieve the 2 parameters from the URL</p>
<p>[sourcode language="java"]<br />
String requestToken = uri.getQueryParameter(&#8220;oauth_token&#8221;);<br />
String verifier = uri.getQueryParameter(&#8220;oauth_verifier&#8221;);<br />
[/sourcecode]</p>
<p>In order to retrieve the actual access token that we&#8217;ll need to perform the authorized API calls, we need an <a title="GoogleOAuthGetAccessToken" href="http://javadoc.google-api-java-client.googlecode.com/hg/1.3.1-alpha/com/google/api/client/googleapis/auth/oauth/GoogleOAuthGetAccessToken.html" target="_blank">GoogleOAuthGetAccessToken </a>object that contains both the oauth_token and oauth_verifier.</p>
<pre class="brush: java;">
		GoogleOAuthGetAccessToken accessToken = new GoogleOAuthGetAccessToken();
		accessToken.transport = Util.AUTH_TRANSPORT;
		accessToken.temporaryToken = requestToken;
		accessToken.signer = signer;
		accessToken.consumerKey = Constants.CONSUMER_KEY;
		accessToken.verifier = verifier;
</pre>
<p>The GoogleOAuthGetAccessToken object contains</p>
<table>
<tbody>
<tr>
<th>Object</th>
<th>Value</th>
</tr>
<tr>
<td>temporaryToken</td>
<td><code>4/hFOwXawX4WNVVcfPgYSWlidypOAL</code></td>
</tr>
<tr>
<td>Our signer object</td>
<td><code>com.google.api.client.auth.oauth.OAuthHmacSigner</code></td>
</tr>
<tr>
<td>Consumer Key</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>Verifier</td>
<td><code>jAsUb68lGmDO8P1sivfgGLz6</code></td>
</tr>
</tbody>
</table>
<p>In order to get the actual access token (token and tokenSecret), we execute the following call to retrieve a OAuthCredentialsResponse object :</p>
<pre class="brush: java;">
credentials = accessToken.execute();
</pre>
<p>The OAuthCredentialsResponse returned here contains</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>token</td>
<td><code>1/PeJEgwmhgAbQyNTB3knWg5k1ABPBgT7DGC6ZNvkcvMQ</code></td>
</tr>
<tr>
<td>tokensharedsecret</td>
<td><code>/m+kCfGms8xI/Zm88oy5OGMC</code></td>
</tr>
</tbody>
</table>
<p>We store the credentials in our Android Shared Preferences, so that we don&#8217;t need to force the user to authorize the request again.</p>
<pre class="brush: java;">
		 final Editor edit = prefs.edit();
		 edit.putString(Constants.PREF_KEY_OAUTH_TOKEN, credentials.token);
		 edit.putString(Constants.PREF_KEY_OAUTH_TOKEN_SECRET, credentials.tokenSecret);
		 edit.commit();
</pre>
<h4>Making API calls</h4>
<p>In order to make an authorized API call, we&#8217;ll do the following</p>
<ul>
<li>Retrieve the access token and token secret from our shared preferences</li>
<li>Create a signer object, containing our token secret</li>
<li>Create an authorizer object, containing our signer and access token</li>
<li>Tell the authorizer to sign our requests</li>
</ul>
<p>These steps can be seen in the code snippet below :</p>
<pre class="brush: java;">
		String token = prefs.getString(Constants.PREF_KEY_OAUTH_TOKEN, &quot;&quot;);
		String secret = prefs.getString(Constants.PREF_KEY_OAUTH_TOKEN_SECRET, &quot;&quot;);

		OAuthHmacSigner signer = new OAuthHmacSigner();
		signer.clientSharedSecret = Constants.CONSUMER_SECRET;
		signer.tokenSharedSecret = secret;
		OAuthParameters authorizer = new OAuthParameters();
		authorizer.consumerKey = Constants.CONSUMER_KEY;
		authorizer.signer = signer;
		authorizer.token = token;
		authorizer.signRequestsUsingAuthorizationHeader(Util.TRANSPORT);
</pre>
<p>The signer contains :</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>clientsharedsecret</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>tokensharedsecret</td>
<td><code>/m+kCfGms8xI/Zm88oy5OGMC</code></td>
</tr>
</tbody>
</table>
<p>The authorizer contains :</p>
<table>
<tbody>
<tr>
<th>Key</th>
<th>Value</th>
</tr>
<tr>
<td>consumerKey</td>
<td><code>anonymous</code></td>
</tr>
<tr>
<td>Our signer object</td>
<td><code>com.google.api.client.auth.oauth.OAuthHmacSigner</code></td>
</tr>
<tr>
<td>token</td>
<td><code>1/PeJEgwmhgAbQyNTB3knWg5k1ABPBgT7DGC6ZNvkcvMQ</code></td>
</tr>
</tbody>
</table>
<p>The actual API calls are done through the Google Buzz model provided by the sample apps, contained in the <strong>com.google.api.client.sample.buzz.model</strong>.</p>
<p>For example, retrieving a list of Buzz posts is done through the BuzzActivityFeed object:</p>
<pre class="brush: java;">
BuzzActivityFeed feed = BuzzActivityFeed.list();
</pre>
<p>The list is implemented by executing a GET request through the transport (meaning it&#8217;s properly signed), and parsing the respone using the JSON parser to return it as a BuzzActivityFeed item.</p>
<pre class="brush: java;">
  public static BuzzActivityFeed list() throws IOException {
    HttpRequest request = Util.TRANSPORT.buildGetRequest();
    request.url = BuzzUrl.forMyActivityFeed();
    return request.execute().parseAs(BuzzActivityFeed.class);
  }
</pre>
<h4>References</h4>
<ul>
<li><a href="http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/" target="_blank">Implementing the OAuth flow in Android using Signpost</a></li>
<li><a href="http://blog.doityourselfandroid.com/2010/11/07/google-oauth-overview/" target="_blank">OAuth Overview</a></li>
<li><a href="http://blog.doityourselfandroid.com/2010/11/08/hands-on-oauth-with-the-playground/" target="_blank">Hands on OAuth with the playground</a></li>
<li><a href="http://hueniverse.com/oauth/" target="_blank">Hueniverse OAuth 1.0</a></li>
<li><a href="http://oauth.net/core/1.0a/#anchor15" target="_blank">OAuth Core 1.0 Revision A</a></li>
<li><a href="http://tools.ietf.org/html/rfc5849">OAuth RFC5849</a></li>
<li><a href="http://oauth.net/code/" target="_blank">OAuth code libraries</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/04/12/oauth-android-google-apis-client-library-java/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Latify v2.0 screenshots</title>
		<link>http://blog.doityourselfandroid.com/2011/04/06/latify-screenshots/</link>
		<comments>http://blog.doityourselfandroid.com/2011/04/06/latify-screenshots/#comments</comments>
		<pubDate>Wed, 06 Apr 2011 18:53:29 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Latify]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=795</guid>
		<description><![CDATA[Latify v2.0 has been released on the Android Market. Introduced location polling profiles and a new screen layout, optimizing screen real estate usage. Thought I&#8217;d share some screenshots:]]></description>
			<content:encoded><![CDATA[<p><a title="Latify on the Android Market" href="https://market.android.com/details?id=com.ecs.latify" target="_blank">Latify v2.0 has been released on the Android Market</a>. Introduced location polling profiles and a new screen layout, optimizing screen real estate usage.</p>
<p>Thought I&#8217;d share some screenshots:</p>

<div class="ngg-galleryoverview" id="ngg-gallery-1-795">


	
	<!-- Thumbnails -->
		
	<div id="ngg-image-1" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/history_map_viewer.png" title=" " class="shutterset_set_1" >
								<img title="history_map_viewer" alt="history_map_viewer" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_history_map_viewer.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-2" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/main_screen_green.png" title=" " class="shutterset_set_1" >
								<img title="main_screen_green" alt="main_screen_green" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_main_screen_green.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-3" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/main_screen_grey2.png" title=" " class="shutterset_set_1" >
								<img title="main_screen_grey2" alt="main_screen_grey2" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_main_screen_grey2.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-4" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/main_screen_red.png" title=" " class="shutterset_set_1" >
								<img title="main_screen_red" alt="main_screen_red" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_main_screen_red.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-5" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/main_screen_yellow.png" title=" " class="shutterset_set_1" >
								<img title="main_screen_yellow" alt="main_screen_yellow" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_main_screen_yellow.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-6" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/prefs_screen.png" title=" " class="shutterset_set_1" >
								<img title="prefs_screen" alt="prefs_screen" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_prefs_screen.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-7" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/profile_screen.png" title=" " class="shutterset_set_1" >
								<img title="profile_screen" alt="profile_screen" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_profile_screen.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-8" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/profile_screen_help.png" title=" " class="shutterset_set_1" >
								<img title="profile_screen_help" alt="profile_screen_help" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_profile_screen_help.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-9" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/screen_realstate.png" title=" " class="shutterset_set_1" >
								<img title="screen_realstate" alt="screen_realstate" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_screen_realstate.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-10" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/screen_realstate2.png" title=" " class="shutterset_set_1" >
								<img title="screen_realstate2" alt="screen_realstate2" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_screen_realstate2.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 		
	<div id="ngg-image-11" class="ngg-gallery-thumbnail-box"  >
		<div class="ngg-gallery-thumbnail" >
			<a href="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/select_view.png" title=" " class="shutterset_set_1" >
								<img title="select_view" alt="select_view" src="http://blog.doityourselfandroid.com/wp-content/gallery/testgallery1/thumbs/thumbs_select_view.png" width="120" height="200" />
							</a>
		</div>
	</div>
	
		
 	 	
	<!-- Pagination -->
 	<div class='ngg-clear'></div>
 	
</div>


]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/04/06/latify-screenshots/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A 30 minute guide to integrating Facebook in your Android application</title>
		<link>http://blog.doityourselfandroid.com/2011/02/28/30-minute-guide-integrating-facebook-android-application/</link>
		<comments>http://blog.doityourselfandroid.com/2011/02/28/30-minute-guide-integrating-facebook-android-application/#comments</comments>
		<pubDate>Mon, 28 Feb 2011 20:33:56 +0000</pubDate>
		<dc:creator>ddewaele</dc:creator>
				<category><![CDATA[Facebook SDK]]></category>
		<category><![CDATA[android]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[oauth]]></category>
		<category><![CDATA[sdk]]></category>

		<guid isPermaLink="false">http://blog.doityourselfandroid.com/?p=730</guid>
		<description><![CDATA[Introduction The goal of this article is to get Facebook integration up &#38; running from your Android app in 30 minutes. The guide will show you how to setup a Faceook test account register a Facebook application authenticate the user in your Android application. have the user update his Facebook wall from your Android application. [...]]]></description>
			<content:encoded><![CDATA[<h2>Introduction</h2>
<div class="borderless">
<table>
<tbody>
<tr>
<td>The goal of this article is to get Facebook integration up &amp; running from your Android app in 30 minutes. The guide will show you how to</p>
<ul>
<li>setup a Faceook test account</li>
<li>register a Facebook application</li>
<li>authenticate the user in your Android application.</li>
<li>have the user update his Facebook wall from your Android application.</li>
</ul>
<p>This guide is accompanied  by a sample application that&#8217;s available in Github in the<a title="AndroidFacebookSample Github repository" href="https://github.com/ddewaele/AndroidFacebookSample" target="_blank"> AndroidFacebookSample repository</a>. To import this project in Eclipse, I suggest using the EGit plugin that can be installed via the Main P2 Repository located at http://download.eclipse.org/egit/updates.</td>
<td><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookandroidlogo.jpg"><img class="aligncenter size-full wp-image-746" title="facebookandroidlogo" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookandroidlogo.jpg" alt="" width="224" height="159" /></a></td>
</tr>
</tbody>
</table>
</div>
<p>Before running this project, make sure you change the <strong>com.ecs.android.facebook.Sample.AndroidFacebookSample</strong> file to include your Facebook API key (see subsequent section).<br />
Once you have sample application up &amp; running, you can copy the relevant classes into your projects to have Facebook up &amp; running from your Android application.</p>
<p>First things first &#8230; In order to integrate with Facebook, you need 2 things :</p>
<ul>
<li>A Facebook test account, used in our Android application to login to Facebook and make status updates.</li>
<li>A Facebook application, used to inform the user in your Android application that this application is requesting you to login to Facebook.</li>
</ul>
<p><span id="more-730"></span></p>
<h2>Facebook Test Account</h2>
<p>We&#8217;ll start by creating a test account that we&#8217;ll use in our Android application. Signup for a new user account at Facebook. If you already have an account, sign up for a new account using your existing name but specify a different email address. Once the account has been created, we&#8217;ll convert it into a Facebook test account.</p>
<p><strong>Note : The following step should not be done on your real facebook account. Converting an existing Facebook account into a test account is irreversible, so please ensure that you do the following step with your newly created &#8220;dummy&#8221; account.</strong></p>
<p>When logged into Facebook, goto the <a title="Facebook Become Test Account" href="http://www.facebook.com/developers/become_test_account.php" target="_blank">Facebook Become Test Account</a> page  to convert your newly created account into a Facebook test account. Again, do not execute these steps on your &#8220;real&#8221; user account.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebook-test-account.png"><img class="aligncenter size-full wp-image-734" title="facebook test account" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebook-test-account.png" alt="" width="436" height="212" /></a></p>
<p>After confirming that you want to convert your account into a test account, you should see the following message :</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebook-test-account-confirmation.png"><img class="aligncenter size-full wp-image-735" title="facebook test account confirmation" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebook-test-account-confirmation.png" alt="" width="410" height="74" /></a></p>
<h2>Facebook Application</h2>
<p>Next step is to create a Facebook application. Integration with facebook is based on OAuth 2.0 and requires your to register a Facebook application. Visit the <a title="Facebook Developers Authentication" href="http://developers.facebook.com/docs/authentication/" target="_blank">Facebook Developers Authentication</a> page for more information on its OAuth 2.0 implementation.</p>
<p>The Facebook application that we&#8217;ll create will have it&#8217;s own Application ID that we&#8217;ll use in our Android application.</p>
<p>Creating an application cannot be done on the Facebook test account, so you&#8217;ll need to have a proper Facebook account in order to create the application. Using your &#8220;real&#8221; Facebook account, goto the <a title="Facebook Create Application" href="http://www.facebook.com/developers/createapp.php" target="_blank">Facebook Create Application</a> page  and create your application.</p>
<p style="text-align: center;"><span style="color: #0000ee; -webkit-text-decorations-in-effect: underline;"><img class="aligncenter size-full wp-image-732" style="display: block; margin-left: auto; margin-right: auto; border: 0px initial initial;" title="Facebook Create Application" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookCreateApp.png" alt="" width="547" height="205" /></span></p>
<div>Give it a name, and complete the registration. You should land on a page like this :</div>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookCreateApp.png"></a><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookAppCreated.png"><img class="aligncenter size-full wp-image-733" title="facebookAppCreated" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/facebookAppCreated.png" alt="" width="543" height="391" /></a><br />
So far so good, everything is setup on the Facebook front, now it&#8217;s time to start coding our Android application.</p>
<p>On the Android front, we&#8217;ll use the Facebook Android SDK located at Github : <a href="https://github.com/facebook/facebook-android-sdk">https://github.com/facebook/facebook-android-sdk</a><br />
The Facebook Android SDK is licensed under the Apache License and is completely open source.</p>
<p style="text-align: left;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FaceBookAndroidSDKGitHub.png"><img class="aligncenter size-full wp-image-736" title="Facebook Android SDK GitHub" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FaceBookAndroidSDKGitHub.png" alt="" width="671" height="214" /></a>The project contains several samples in the <strong>examples</strong> folder, but the core SDK is located in the <strong>facebook</strong> folder. The sample application included in the facebook sdk repository provides the user the ability to post a message on the wall using a custom dialog, allowing the user to enter some text. The goal of the sample application that we&#8217;ll be creating here is to send an automated message to the wall, without any human interaction. Our application will generate a piece of text and post it on the wall without showing a dialog to the user. The user simply presses a button, and the generated message will appear on his/her wall.</p>
<p>But to get started, we&#8217;ll begin by importing the facebook project (containing the actual facebook sdk) into Eclipse. Once this is done, you should have the following Eclipse Project in your workspace :</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/AndroidSdkEclipseProject.png"><img class="aligncenter size-full wp-image-737" title="Facebook Android SDK Eclipse Project" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/AndroidSdkEclipseProject.png" alt="" width="339" height="275" /></a></p>
<p>As this is the <strong>library project</strong> that our sample application will use to do the actual  Facebook integration, we&#8217;ll  need to create a reference in our own project to this Facebook Android SDK project. This is done by going to our project properties, select Android on the left, go to the library section and click Add.</p>
<p style="text-align: center;"><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Properties.png"><img class="aligncenter size-full wp-image-738" title="Android Project Properties" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Properties.png" alt="" width="561" height="473" /></a></p>
<p>On the following screen, you can select the Facebook Android SDK library project</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Selection.png"><img class="aligncenter size-full wp-image-740" title="Project Selection" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Selection.png" alt="" width="398" height="437" /></a>When selected, it will be made available to your own project.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Selection-2.png"><img class="aligncenter size-full wp-image-739" title="Project Selection" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Project-Selection-2.png" alt="" width="579" height="203" /></a>As you can see in the Eclipse Package explorer, our sample project now also contains a reference to the Facebook Android SDK project</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Android-Project-Layout.png"><img class="aligncenter size-full wp-image-741" title="Android Project Layout" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/Android-Project-Layout.png" alt="" width="436" height="364" /></a></p>
<p>The Facebook SDK project revolves around a central <strong>com.facebook.android.Facebook.Facebook </strong>class, allowing you to perform various calls to Facebook.  It provides basic login/logoff functionality (by leveraging single sign on capabilities if you have the official facebook app installed), handles the OAuth integration, and provides you with a generic API to perform requests to the various Facebook APIs.</p>
<p>In our own sample application, we&#8217;ll encapsulate all the Facebook interactions in a FacebookConnector object. The object is constructed like this</p>
<pre class="brush: java;">
	public FacebookConnector(String appId,Activity activity,Context context,String[] permissions) {
		this.facebook = new Facebook(appId);

		SessionStore.restore(facebook, context);
        SessionEvents.addAuthListener(mSessionListener);
        SessionEvents.addLogoutListener(mSessionListener);

		this.context=context;
		this.permissions=permissions;
		this.mHandler = new Handler();
		this.activity=activity;
	}
</pre>
<p>As you can, under the hook, our FacebookConnector class uses the Facebook class provided by the Facebook SDK project.</p>
<p>Our FacebookConnector will provide a more coarse-grained API than the Facebook class. The Facebook class is designed in a very generic way, allowing you to do a lot of different calls to Facebook. This design results in a fairly fine-grained API, where some knowledge is expected from the application using this API. For example, you&#8217;ll need to know the specific endpoints for post a message on a wall, or to retrieve a user profile. In addition to that, you&#8217;ll also need to know what parameters you need to send for each request.</p>
<p>Our FacebookConnector exposes a coarse-grained method called <strong>postMessageOnWall</strong> that&#8217;s the main logic behind our Post button. The only thing we need to provide is the actual message we want to post. The FacebookConnector will do the necessary plumbing towards the more generic Facebook class.</p>
<p>The <strong>postMessageOnWall</strong> method checks if we have a valid Facebook session (meaning we have authenticated properly against Facebook). If this is the case, it setups up the necessary parameters, and does a call through the Facebook class to post a message on the wall. (using the <strong>me/feed</strong> endpoint)</p>
<pre class="brush: java;">
	public void postMessageOnWall(String msg) {
		if (facebook.isSessionValid()) {
		    Bundle parameters = new Bundle();
		    parameters.putString(&quot;message&quot;, msg);
		    try {
				String response = facebook.request(&quot;me/feed&quot;, parameters,&quot;POST&quot;);
				System.out.println(response);
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {
			login();
		}
	}
</pre>
<p>But we&#8217;ll start by explaining what happens if the user doesn&#8217;t have a valid Facebook session.</p>
<p>If the user hasn&#8217;t authenticated to Facebook yet we need to perform a login. The login() is defined like this :</p>
<pre class="brush: java;">
	public void login() {
        if (!facebook.isSessionValid()) {
            facebook.authorize(this.activity, this.permissions,Facebook.FORCE_DIALOG_AUTH,new LoginDialogListener());
        }
    }
</pre>
<p>The login method is implemented in such a way that when we don&#8217;t have a logged in user, we call the facebook.authorize to start the Facebook OAuth flow. Although the Facebook SDK has a single-sign-on option, allowing you to leverage your existing facebook session you may have with the official Facebook Android application, we&#8217;ll add the Facebook.FORCE_DIALOG_AUTH parameter to have the Facebook SDK pop the login dialog.</p>
<p>The first thing that will happen when executing this method, is that the Facebook login dialog will be shown. Notice how the login dialog mentions the Facebook app we created earlier. By passing on our Application ID to the Facebook object, the user is now informed that the TestAndroidIntegration application is initiating the Facebook login. The user can decide at this point if he wants to login to his Facebook account.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookLoginAndroid.png"><img class="aligncenter size-full wp-image-748" title="Facebook Login Android" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookLoginAndroid.png" alt="" width="331" height="491" /></a></p>
<p>When the user does a login, he&#8217;ll be presented with yet another dialog. Keep in mind that at this point, although the user is logged in, he didn&#8217;t give any permissions yet for this application to post messages on his wall. This particular dialog will now request the user for certain permission.</p>
<p>It basically allows the user to authorize the TestAndroidIntegration application to access basic information and Post to my Wall.  Accessing basic information is the default permission that is given when a user logs in this way. Here, an additional permission is requested (Post to my Wall).</p>
<p>In order to post something on the wall, the <strong>publish_stream</strong> permission is required, hence we pass this on to our FacebookConnector :</p>
<pre class="brush: java;">

	private static final String FACEBOOK_APPID = &quot;PUT YOUR FACEBOOK APPID HERE&quot;;
	private static final String FACEBOOK_PERMISSION = &quot;publish_stream&quot;;

	facebookConnector = new FacebookConnector(FACEBOOK_APPID, this, getApplicationContext(), new String[] {FACEBOOK_PERMISSION});
</pre>
<p>Note : ensure that you provide a proper Facebook APPID here.</p>
<p><a href="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookAuthorizeAndroid.png"><img class="aligncenter size-full wp-image-749" title="Facebook Authorize Android" src="http://blog.doityourselfandroid.com/wp-content/uploads/2011/02/FacebookAuthorizeAndroid.png" alt="" width="323" height="486" /></a></p>
<p>When the user allows this request for permission (authorization), the Facebook API can begin executing requests on behalf of the user (like posting something on his wall).</p>
<h2>Posting a message on the Facebook wall</h2>
<p>In order to post a message on the wall, we basically construct a message (Bundle) that we pass on to the facebook request method. We use the &#8220;me/feed&#8221;  ID on the <a title="Facebook Graph API" href="http://developers.facebook.com/docs/reference/api/" target="_blank">Facebook Graph API</a> to indicate that we&#8217;ll be posting something to the Profile feed (Wall in Facebook terminlogy).</p>
<pre class="brush: java;">

	private FacebookConnector facebookConnector;

	private void postMessageInThread() {
		Thread t = new Thread() {
			public void run() {

		    	try {
		    		facebookConnector.postMessageOnWall(getFacebookMsg());
					mFacebookHandler.post(mUpdateFacebookNotification);
				} catch (Exception ex) {
					Log.e(TAG, &quot;Error sending msg&quot;,ex);
				}
		    }
		};
		t.start();
	}
</pre>
<p>The postMethodOnWall() method is called from our main Activity in a background thread. Although we don&#8217;t want to interrupt the main UI thread while posting the message (hence the background thread), we do want to send a notification to the user that his message was posted. We use a handler for this in order to show a Toast message on the main UI thread once the background processing has been done.</p>
<pre class="brush: java;">

	private FacebookConnector facebookConnector;

    final Runnable mUpdateFacebookNotification = new Runnable() {
        public void run() {
        	Toast.makeText(getBaseContext(), &quot;Facebook updated !&quot;, Toast.LENGTH_LONG).show();
        }
    };
</pre>
<p>An importing thing to note is that when the user clicks the Post Message button, besides logging just logging in, we also want to send the message to the Facebook wall. Performing the login, immediately followed by an action (in this case sending a message) can be done by adding a AuthenticationListener (SessionEvents.AuthListener) to the SessionEvents.</p>
<p>The following code (wrapper method) illustrates this :</p>
<ul>
<li>in case of logged in user simply post the message in the background thread.</li>
<li>in case of an anonymous user, we wait for the authentication to succeed, and then continue on to posting the message in the background thread.</li>
</ul>
<pre class="brush: java;">
	public void postMessage() {
		if (facebookConnector.getFacebook().isSessionValid()) {
			postMessageInThread();
		} else {
			SessionEvents.AuthListener listener = new SessionEvents.AuthListener() {

				@Override
				public void onAuthSucceed() {
					postMessageInThread();
				}

				@Override
				public void onAuthFail(String error) {

				}
			};
			SessionEvents.addAuthListener(listener);
			facebookConnector.login();
		}
	}
</pre>
<p>The clearCredentials() method is responsible for logoff functionality. All credentials are cleared from the system, and each interaction with Facebook will again trigger a login().</p>
<pre class="brush: java;">
	private void clearCredentials() {
		try {
			facebookConnector.getFacebook().logout(getApplicationContext());
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
</pre>
<h2>Conclusion</h2>
<p>The Android Facebook SDK provides an easy way to integrate Facebook into your Android application. It provides single sign on capabilities, preventing the user from having to login again if a session was already established with Facebook. Also, the OAuth 2.0 implementation that Facebook offers enables a much simpler authentication / authorization mechanism that with traditional OAuth based providers. After having setup the test account to do your testing, you should be up &amp; running with facebook in your application in no time.</p>
<h2>References</h2>
<ul>
<li><a title="Implementing the OAuth flow in Android" href="http://blog.doityourselfandroid.com/2010/11/10/oauth-flow-in-android-app/" target="_blank">Implementing the OAuth flow in Android </a></li>
<li><a title="A 30 minute guide to integrating Twitter in your Android application" href="http://blog.doityourselfandroid.com/2011/02/13/guide-to-integrating-twitter-android-application/" target="_blank">A 30 minute guide to integrating Twitter in your Android application</a></li>
<li><a title="AndroidFacebookSample Github repository" href="https://github.com/ddewaele/AndroidFacebookSample" target="_blank"> AndroidFacebookSample GitHub repository</a></li>
<li><a title="Facebook SDK GitHub repository" href="http://code.google.com/p/oauth-signpost/" target="_blank">Facebook SDK GitHub repository</a></li>
<li><a title="Facebook OAuth implementation" href="http://developers.facebook.com/docs/authentication/" target="_blank">Facebook OAuth implementation</a></li>
<li><a title="Facebook Graph API documentation" href="http://developers.facebook.com/docs/reference/api" target="_blank">Facebook Graph API documentation</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.doityourselfandroid.com/2011/02/28/30-minute-guide-integrating-facebook-android-application/feed/</wfw:commentRss>
		<slash:comments>89</slash:comments>
		</item>
	</channel>
</rss>
