<?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>Et-Setera &#187; Mobile</title>
	<atom:link href="http://www.setera.org/category/mobile/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.setera.org</link>
	<description>Ramblings of a geek</description>
	<lastBuildDate>Wed, 28 Dec 2011 01:28:10 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Deadlocked</title>
		<link>http://www.setera.org/2011/12/27/deadlocked/</link>
		<comments>http://www.setera.org/2011/12/27/deadlocked/#comments</comments>
		<pubDate>Wed, 28 Dec 2011 01:26:58 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=628</guid>
		<description><![CDATA[I recently started spending more time on my Android Clock Widget Project. I&#8217;ve implemented some much needed caching of the SVG definitions, speeding performance of clock rendering substantially. In addition, I&#8217;ve been working on building a nice graphical clock selector. Unfortunately, this selector is causing me lots of frustration due to a race condition that [...]]]></description>
			<content:encoded><![CDATA[<p>I recently started spending more time on my <a href="http://www.setera.org/2011/09/04/clock-widget-project/">Android Clock Widget Project</a>.  I&#8217;ve implemented some much needed caching of the SVG definitions, speeding performance of clock rendering substantially.  In addition, I&#8217;ve been working on building a nice graphical clock selector.  Unfortunately, this selector is causing me lots of frustration due to a race condition that keeps deadlocking the application&#8217;s UI thread.<br />
<span id="more-628"></span></p>
<p>Parsing and rendering the various SVG layers that make up each clock is a relatively expensive operation.  Locking up the user interface while doing these operations is bad design and leads the user to believe that the application may not working correctly.  What I&#8217;m attempting to do seems pretty simple on the surface.  The following screen capture shows the (partially working) goal:</p>
<p><a href="http://www.setera.org/wp-content/uploads/2011/12/clocks.png"><img src="http://www.setera.org/wp-content/uploads/2011/12/clocks.png" alt="Clock Skin Selector" title="Clock Skin Selector" width="328" height="488" class="aligncenter size-full wp-image-629" /></a></p>
<p>The selector consists of two columns, an image of the clock on the left and the name of the clock on the right.  Using the standard ListActivity support, the goal is to show an indeterminate progress image in the left column until the layers have been loaded and rendered.  At that point, the animated progress image is hidden and the clock image is displayed.  </p>
<p>The implementation is simple in concept.  The list adapter subclasses the standard BaseAdapter implementation to provide an implementation of the <em>getView</em> method.  The <em>getView</em> method delegates loading of the clock&#8217;s image to an asynchronous task, keeping the user interface alive.  When the asynchronous task completes, it signals the adapter by calling <em>notifyDataSetChanged</em>.  The next call to <em>getView</em> will hide the progress animation and display the rendered image.</p>
<p>While this is mostly working, I&#8217;m hitting a random deadlock condition that locks up the UI thread, usually resulting in an &#8220;Application Not Responding&#8221; (ANR) error message to the user.  All of my attempts to diagnose and resolve this issue have ended with nothing but frustration.  So far, I&#8217;ve tried all of the &#8220;standard&#8221; approaches to diagnose this:</p>
<ul>
<li>Analyzed the traces.txt file generated by the ANR.  <br/> Unfortunately, the process never shows up in the log file.</li>
<li>Force-generated a traces.txt file using <em>kill SIGQUIT pid</em> while the application was still running.  <br/>Again, the process doesn&#8217;t seem to show up.  Instead, I see &#8220;W/dalvikvm(19144): threadid=4: spin on suspend #1 threadid=9 (pcf=0)&#8221; whenever attempting this.</li>
<li>Attempted to use the standard Eclipse debugger to suspend the UI thread once it is locked up.  <br/>No big surprise that it did not work.</li>
<li>Added lots of Log output trying to pinpoint the hang.  <br/>At least from that logging, it doesn&#8217;t <b>appear</b> to be a hang anywhere directly in my code.</li>
<li>I even tried to use method tracing to see if I could figure anything out.</li>
</ul>
<p>At this point, I&#8217;ve run out of good ideas on how to track down and fix this problem on my own.  I&#8217;ve gone ahead and joined the Google android-developers group and asked for ideas on solving this.  I&#8217;m still waiting for my question to clear moderation to see if anyone else can offer any insights.  If anyone reading this has any ideas, I&#8217;d love to hear them.  Until then, this project is officially deadlocked.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/12/27/deadlocked/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Relinking Android Market Applications</title>
		<link>http://www.setera.org/2011/11/02/relinking-android-market-applications/</link>
		<comments>http://www.setera.org/2011/11/02/relinking-android-market-applications/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 23:00:59 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=595</guid>
		<description><![CDATA[When I initially set up my Samsung Captivate, I used my work email as the primary email address for the device. This caused my Android Market applications to be associated with my work email. When Google started allowing multiple accounts, I added my personal GMail account to the device and managed to get a confusing [...]]]></description>
			<content:encoded><![CDATA[<p>When I initially set up my Samsung Captivate, I used my work email as the primary email address for the device.   This caused my Android Market applications to be associated with my work email.  When Google started allowing multiple accounts, I added my personal GMail account to the device and managed to get a confusing mix of installed applications associated with each account.  After being frustrated with this for a while, I decided I needed to fix this.</p>
<p><span id="more-595"></span><br />
The internet offered no examples of how I might go about doing this, so I went spelunking on my own.  For those that may need to do something similar, I decided to capture the steps I used to relink my Android Market applications with a single GMail address.  Before I go any further, let me offer some warnings:</p>
<p><b></p>
<ul>
<li style="background-color: #FF0000; color: #FFFFFF;">I AM NOT LIABLE IF YOU BREAK YOUR PHONE BY TRYING THIS. <br/> IF YOU DON&#8217;T KNOW WHAT YOU ARE DOING, DO NOT ATTEMPT THESE CHANGES.</li>
<li style="background-color: #FF0000; color: #FFFFFF;">My steps include a few things to hopefully avoid major breakage, however I&#8217;d urge caution.  Be careful.</li>
<li style="background-color: #FF0000; color: #FFFFFF;">Your device must be rooted in order to make the necessary changes.</li>
<li style="background-color: #FF0000; color: #FFFFFF;">These steps only work for free applications.  Paid applications are associated to a particular Google account using DRM.</li>
<li style="background-color: #FF0000; color: #FFFFFF;">CONSIDER YOURSELF WARNED</li>
</ul>
<p></b></p>
<p><b>November 13, 2011 Update</b></p>
<p><i>While this appears to work in the short term, I&#8217;m noticing applications slowly migrating back to the original accounts.  I&#8217;m not entirely sure where those values are being stored or how to fix this permanently.</i></p>
<h2>The Market Assets Database</h2>
<p>As of this writing, Android Market (implemented by the com.android.vending package) stores the linkage between an Android application package and the associated Android Market account in the file:</p>
<pre name="code" class="shell">
/data/data/com.android.vending/databases/market_assets.db
</pre>
<p>The <i>ASSETS</i> table within that SQLITE database contains the mappings as seen in this screenshot.</p>
<p><a href="http://www.setera.org/wp-content/uploads/2011/10/Screenshot-at-2011-10-29-124410.png"><img src="http://www.setera.org/wp-content/uploads/2011/10/Screenshot-at-2011-10-29-124410.png" alt="Market Assets DB" title="Market Assets DB" width="767" height="236" class="aligncenter size-full wp-image-596" /></a></p>
<p>Relinking applications is a matter of properly updating this table.  The prerequisites for this process are:</p>
<ul>
<li>Rooted device</li>
<li>Android Debug Tools (adb) installed and working</li>
</ul>
<h2>Relinking Process</h2>
<p>Start by making sure that Market application has been stopped:</p>
<ol>
<li>Navigate to Settings -> Applications -> Manage Applications</li>
<li>Locate and select the Market application in the list</li>
<li>Press the <i>Force Stop</i> button</li>
</ol>
<p>Make sure that your device is attached with USB Debugging enabled:</p>
<pre name="code" class="shell">
$ -> adb devices
List of devices attached
3231174E43AA00EC	device
</pre>
<p>Open a shell on the device and navigate to the database directory:</p>
<pre name="code" class="shell">
$ -> adb shell
# cd /data/data/com.android.vending/databases
# ls -l
-rw-rw----    1 app_57   app_57       34816 Oct 29 11:55 market_assets.db
</pre>
<p>Backup the current file:</p>
<pre name="code" class="shell">
# cp market_assets.db market_assets.db.save
# ls -l
-rw-rw----    1 app_57   app_57       34816 Oct 29 11:55 market_assets.db
-rw-rw----    1 root     root         31744 Oct 29 11:44 market_assets.db.save
</pre>
<p>Update the database file:</p>
<pre name="code" class="shell">
# sqlite3 market_asset.db
sqlite> update ASSETS set ACCOUNT = 'new.email@gmail.com'
   ...> where ACCOUNT = 'old.email@gmail.com';
sqlite> .exit
# exit
</pre>
<p>At this point, reboot your phone.  If all went correctly, your free applications should now be associated with <i>new.email@gmail.com</i>.</p>
<h2>Updating Paid Applications</h2>
<p>As I mentioned earlier, this process can&#8217;t be used to relink paid applications due to DRM that is tied to your account.  If you want to do this, most application developers will offer a refund if you purchase on a new account and send them the order details for both the old and new accounts.  Once you&#8217;ve purchased on the new account, you can uninstall for the old account and reinstall from the new.  This is a lot of effort, but can help if you need to switch market accounts.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/11/02/relinking-android-market-applications/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Clock Widget Project</title>
		<link>http://www.setera.org/2011/09/04/clock-widget-project/</link>
		<comments>http://www.setera.org/2011/09/04/clock-widget-project/#comments</comments>
		<pubDate>Sun, 04 Sep 2011 23:55:11 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Clock]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=562</guid>
		<description><![CDATA[In my last post about inertia I mentioned that I had started to take a look at Android App Widgets. I&#8217;ve long had the idea that it would be interesting to create a widget capable of consuming themes for MacSlow&#8217;s Cairo Clock project. This very cool analog clock uses a set of SVG graphics to [...]]]></description>
			<content:encoded><![CDATA[<p>In my last post about <a href="http://www.setera.org/2011/07/30/inertia/">inertia</a> I mentioned that I had started to take a look at Android App Widgets.  I&#8217;ve long had the idea that it would be interesting to create a widget capable of consuming themes for <a href="http://macslow.net/?page_id=23">MacSlow&#8217;s Cairo Clock</a> project.  This very cool analog clock uses a set of SVG graphics to theme the clock in such a way that it can be scaled to various sizes.  While I&#8217;m not there quite yet, the ultimate goal is that the widget is capable of rendering all of the themes found at <a href="http://gnome-look.org/index.php?xcontentmode=186">gnome-look.org</a>.<br />
<span id="more-562"></span></p>
<p>This screen capture from the emulator shows multiple live instances of the widget running simultaneously with many different themes.  I would not suggest that anyone actually do this do the amount of memory required, however it shows the power of the themes.</p>
<div id="attachment_566" class="wp-caption aligncenter" style="width: 388px"><a href="http://www.setera.org/wp-content/uploads/2011/09/Screenshot.png"><img src="http://www.setera.org/wp-content/uploads/2011/09/Screenshot.png" alt="" title="Clock Themes" width="378" height="552" class="size-full wp-image-566" /></a><p class="wp-caption-text">Android analog clock displaying many themes simultaneously.</p></div>
<h2>Implementation Notes</h2>
<p>Getting to this point has been an interesting process, as the Android widget support definitely makes this type of widget somewhat difficult to build.</p>
<h3>AndEngine SVG Support</h3>
<p>I&#8217;ve had this idea for quite some time.  What helped me move forward was the addition of <a href="http://www.andengine.org/blog/category/andenginesvgtextureregionextension/">SVG support to AndEngine.</a>  Thanks to Nicolas Gramlich yet again for his excellent engine.  I&#8217;ve found a few glitches along the way that I&#8217;ve started to submit patches to the project to correct, but as always his code works amazingly well.</p>
<h3>Per-Minute Updates</h3>
<p>As I mentioned in <a href="http://www.setera.org/2011/07/30/inertia/">my inertia post</a>, the standard Android widgets model is really more of a &#8220;pull&#8221; model versus a &#8220;push&#8221; model.  The widget provider definition file (in XML) specifies the frequency that the Android framework will call the widget&#8217;s update functionality:</p>
<pre name="code" class="xml">
    android:updatePeriodMillis="1800000"
</pre>
<p>However, no matter what is specified for this value, Android limits the update frequency to no more than once every 30 minutes to avoid the battery drain associated with executing code too often.  Thus, it is necessary to push changes to the widget based on our own schedule to make sure the clock is updated every minute.</p>
<p>My initial implementation used Java&#8217;s Timer and TimerTask to do these updates.  Looking at the framework&#8217;s analog clock implementation, I discovered Android&#8217;s time-related broadcast messages:</p>
<ul>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_TICK">Intent.ACTION_TIME_TICK</a></li>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_CHANGED">Intent.ACTION_TIME_CHANGED</a></li>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIMEZONE_CHANGED">Intent.ACTION_TIMEZONE_CHANGED</a></li>
</ul>
<p>Using these broadcast messages is a vast improvement over maintaining my own timer threads for this functionality.  However, since a widget is nothing more than a fancy broadcast receiver, it is necessary to spin up a separate service to register a broadcast receiver for these messages.  On reception of one of these messages, each clock instance is updated to match the current time.  This update generates a properly sized bitmap that is pushed to the widget instance:</p>
<pre name="code" class="java">
		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
		views.setImageViewBitmap(R.id.imageview, bitmap);
		appWidgetManager.updateAppWidget(instanceIdentifier, views);
</pre>
<p>It&#8217;s important to note that there is also an <i>updateAppWidget</i> method call that accepts an instance of <i>android.content.ComponentName</i>.  Using this method will update all instances for the specified provider with the bitmap.  It took a bit to figure out why all of my clock instances were showing the same theme until I realized it was due to using the wrong method.</p>
<h3>Improving Battery Performance</h3>
<p>Given that this widget is controlling updates rather than allowing the framework to do the job, my primary concern is in terms of performance.  Android devices are notorious for poor battery life, however it does seem that it is primarily due to background applications.  I&#8217;ve done a couple of things thus far to attempt to minimize battery usage.</p>
<h4>No Seconds Hand</h4>
<p>At least at the moment, the widget removes the seconds hand to avoid pushing more updates to the screen than necessary.  Assuming that Android wants to limit updates to once every 30 minutes, the widget is already pushing updates 30 times more often than the framework would like.  Multiplying that yet again by 60 seconds seems like a bit too much.  In the future, I may consider allowing the user to enable the seconds hands with proper warnings attached.</p>
<h4>Manage Broadcast Receiver Messages</h4>
<p>An unfortunate side effect of the way that widgets work is that it does not appear to be possible for a widget to determine if it is actually being displayed.  If a widget is placed on screen 1, but the user is currently viewing screen 2, there is really no reason to update the widget.  With that said, the implementation can still be smart about updates.  The service alters the messages it listens for based on the status of the screen:</p>
<ul>
<li>Screen Off</li>
<ul>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_USER_PRESENT">Intent.ACTION_USER_PRESENT</a></li>
</ul>
<li>Screen On</li>
<ul>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_SCREEN_OFF">Intent.ACTION_SCREEN_OFF</a></li>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_TICK">Intent.ACTION_TIME_TICK</a></li>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIME_CHANGED">Intent.ACTION_TIME_CHANGED</a></li>
<li><a href="http://developer.android.com/reference/android/content/Intent.html#ACTION_TIMEZONE_CHANGED">Intent.ACTION_TIMEZONE_CHANGED</a></li>
</ul>
</ul>
<p>After the user has cleared the lock screen (ACTION_USER_PRESENT), the widget registers to hear time updates as well as the screen turning off.  Once the screen turns off, the widget stops listening for time updates and switches to listening for user presence.  This lowers the update frequency for the widgets when there is no chance that they will actually be visible to the user.</p>
<h2>What&#8217;s Next?</h2>
<p>This project has a chance of being something that I can complete and that others might be interested in actually <i>using</i>.  I&#8217;m considering whether I want to submit this to the Android Market when it is a bit further along.  If I do, I will have to decide whether or not I would charge for it which implies a certain level of required support.  Either way, I&#8217;m not at the point of releasing any significant amount of source code until I decide what to do with this project.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/09/04/clock-widget-project/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Inertia</title>
		<link>http://www.setera.org/2011/07/30/inertia/</link>
		<comments>http://www.setera.org/2011/07/30/inertia/#comments</comments>
		<pubDate>Sun, 31 Jul 2011 00:23:30 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=541</guid>
		<description><![CDATA[Inertia is the resistance of any physical object to a change in its state of motion or rest, or the tendency of an object to resist any change in its motion. For me, this also describes my tendencies toward side projects like my Pingus project. When I last worked on Pingus a couple of months [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>Inertia is the resistance of any physical object to a change in its state of motion or rest, or the tendency of an object to resist any change in its motion.</p></blockquote>
<p>For me, this also describes my tendencies toward side projects like my <a href="http://www.setera.org/2011/06/26/we-are-experiencing-technical-difficulties/">Pingus project</a>.  When I last worked on Pingus a couple of months ago, I updated the underlying <a href="http://andengine.org">AndEngine</a> libraries and found a ton of breaking changes.  I put Pingus on the shelf until I had more time to look at the breakage and how to solve it.  The AndEngine changes are pretty significant and I&#8217;m going to need to rethink portions of Pingus in order to get things running correctly again.  </p>
<p><span id="more-541"></span></p>
<p>Now my personal inertia is kicking in and causing me to put off this rework for a while.  To me, this is the biggest difference between work and hobby projects&#8230; I don&#8217;t <b>have</b> to work on hobby projects if I don&#8217;t want to.  Thus, Pingus is &#8220;on a break&#8221; for a while until I find the energy to bring it up to date relative to the underlying game engine. </p>
<p>In the meantime, I decided I wanted to spend a bit of time taking a look at Android&#8217;s <a href="http://developer.android.com/guide/topics/appwidgets/index.html">App Widget</a> support.  Until I started digging into the documentation and examples, I had always assumed that a widget was provided a Canvas to draw directly on to the home screen.  To me this seemed like it would have been the easiest way for developers to develop widgets.  </p>
<p>It turns out that Android AppWidgets don&#8217;t work that way at all.  AppWidgets are built on top of <a href="http://developer.android.com/reference/android/widget/RemoteViews.html">Remote Views</a>.  According to the Android documentation, Remote Views are</p>
<blockquote><p>A class that describes a view hierarchy that can be displayed in another process. The hierarchy is inflated from a layout resource file, and this class provides some basic operations for modifying the content of the inflated hierarchy.</p></blockquote>
<p>A Remote View is created in one process and passed into the process that owns the Android home screen.  It is actually a <a href="http://developer.android.com/reference/android/os/Parcelable.html">Parcelable</a> object, however due to class loading issues, there is only a very small number of Views and Widgets that are allowed to be passed across the process boundary.  For anything that involves relatively complex graphical rendering, the only real way to drive the widget&#8217;s contents is by specifying a very simple widget layout:</p>
<pre name="code" class="xml">
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent">

    <ImageView
    	android:id="@+id/imageview"
	    android:layout_width="fill_parent"
	    android:layout_height="wrap_content"
		android:src="@drawable/icon" />

</LinearLayout>
</pre>
<p>and then sending bitmaps to the image view:</p>
<pre name="code" class="java">
	private void updateWidget(Context context, AppWidgetManager appWidgetManager) {
		Bitmap bitmap = Bitmap.createBitmap(100, 100, Config.ARGB_8888);
		Canvas canvas = new Canvas(bitmap);

		this.drawable.draw(canvas);

		RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
		views.setImageViewBitmap(R.id.imageview, bitmap);

		ComponentName componentName = new ComponentName(context, MyAppWidgetProvider.class);
		appWidgetManager.updateAppWidget(componentName, views);
	}
</pre>
<p>While this seems like a high overhead way to handle updates to the widget contents, I have to assume that the Android developers had a good reason for doing things like this.  I can only hope that there are some tricks being done in the Android implementation that lower the cost of this operation.  Given that I&#8217;ve just managed to get this to work at all, I imagine there are is a lot of room for improvement in my use of this API.  However, I found it confusing enough to figure out how to do and thought others might benefit from my pain.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/07/30/inertia/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Supporting Extra Large Screens in Android</title>
		<link>http://www.setera.org/2011/05/11/supporting-extra-large-screens-in-android/</link>
		<comments>http://www.setera.org/2011/05/11/supporting-extra-large-screens-in-android/#comments</comments>
		<pubDate>Thu, 12 May 2011 00:00:20 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=500</guid>
		<description><![CDATA[In my last Android Pingus post I mentioned that I was interested in getting Pingus running full screen on my Motorola Xoom. It was clear from Android Market applications that it was possible to run applications across a wide range of Android versions with full screen support for extra large screens, but it was not [...]]]></description>
			<content:encoded><![CDATA[<p>In my last <a href="http://www.setera.org/2011/05/07/pingus-on-android-%E2%80%93-%E2%80%9Cdestroyable-terrain%E2%80%9D-3/">Android Pingus post</a> I mentioned that I was interested in getting Pingus running full screen on my Motorola Xoom.  It was clear from Android Market applications that it was possible to run applications across a wide range of Android versions with full screen support for extra large screens, but it was not entirely obvious to me how to actually accomplish that.</p>
<p>In reading the <a href="http://developer.android.com/guide/topics/manifest/supports-screens-element.html">Android <b>supports-screen</b> documentation</a>, it is clear that it is necessary to set the <b>xlargeScreens</b> attribute to <b>true</b>.  However, the <b>xlargeScreens</b> attribute is not supported below API level 9.  Trying to shoehorn that attribute into my project that was attempting to support back to API level 5, resulted in the following error.<br />
<span id="more-500"></span></p>
<div id="attachment_504" class="wp-caption aligncenter" style="width: 938px"><a href="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensfail.png"><img src="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensfail.png" alt="" title="XLargeScreens Fail" width="928" height="415" class="size-full wp-image-504" /></a><p class="wp-caption-text">XLargeScreens Attribute Failure</p></div>
<p>With a bit of finagling, I was able to get things working.  In order to allow the <b>xlargeScreens</b> attribute, it is necessary to specify a target SDK version of at least 9.</p>
<div id="attachment_507" class="wp-caption aligncenter" style="width: 729px"><a href="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensworking.png"><img src="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensworking.png" alt="" title="XLargeScreens Working" width="719" height="462" class="size-full wp-image-507" /></a><p class="wp-caption-text">XLargeScreens Working</p></div>
<p>This screenshot shows how the minimum SDK version can be set below version 9 and the target version is set to 9, allowing the <b>xlargeScreens</b> attribute to be specified.  In addition, it is necessary to change the Android version level in the project properties.</p>
<div id="attachment_509" class="wp-caption aligncenter" style="width: 638px"><a href="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensprops.png"><img src="http://www.setera.org/wp-content/uploads/2011/05/xlargescreensprops.png" alt="" title="XLargeScreens Properties" width="628" height="518" class="size-full wp-image-509" /></a><p class="wp-caption-text">XLargeScreens Properties</p></div>
<p>With the project properties set to use API level 9 there does not appear to be any automated way to restrict access to API that was older than version 9.  Because of this, I do worry about choosing Android API&#8217;s that will not work at the <i>minimum</i> SDK and will fail on-device.  My plan at this point is to switch back to building primarily for low end and switch once in a while to try on my Xoom.  If I were a bit more serious, I would probably handle this automatically as part of a build script.</p>
<p>I do wish that Google had handled things differently in regard to how this works.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/05/11/supporting-extra-large-screens-in-android/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pingus on Android – “Destroyable Terrain” #3</title>
		<link>http://www.setera.org/2011/05/07/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-3/</link>
		<comments>http://www.setera.org/2011/05/07/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-3/#comments</comments>
		<pubDate>Sun, 08 May 2011 01:39:42 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=479</guid>
		<description><![CDATA[Despite traveling soccer season heating up, I have managed to make some real progress on destroyable terrain since hitting a wall in my last post. Ground tiles are now implemented and working quite well. In this first video, you can see the individual tiles being marked as the digger works its way through the ground. [...]]]></description>
			<content:encoded><![CDATA[<p>Despite traveling soccer season heating up, I have managed to make some real progress on destroyable terrain <a href="http://www.setera.org/2011/03/27/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-2/">since hitting a wall in my last post.</a>  Ground tiles are now implemented and working quite well.  In this first video, you can see the individual tiles being marked as the digger works its way through the ground.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/TKe2g-Nx9o0?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/TKe2g-Nx9o0?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p><span id="more-479"></span></p>
<p>Once it was clear that the correct tiles were being found and that the image alteration was working, the next step was to calculate the correct alterations to match the digger&#8217;s location as shown as red in this video.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/IQkni8UgUzU?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IQkni8UgUzU?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>Finally, terrain destruction was completed by clearing those same image pixels to transparent resulting in the following.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/Z-KKPJWGKaU?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/Z-KKPJWGKaU?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<h2>Clearing to Transparent</h2>
<p>Clearing the image pixels to transparent turned out to be a bit trickier than I had guessed it would be.  The default paint <a href="http://developer.android.com/reference/android/graphics/Paint.html#setXfermode(android.graphics.Xfermode)">&#8220;transfer mode&#8221;</a> is such that painting with a transparent color results in no changes to the image.  In order to erase the image to transparency, the transfer mode needs to be changed like the following:</p>
<pre name="code" class="java">
		// Set up a paint that can be used to clear pixels from a ground tile
		Paint paint = new Paint();
		paint.setColor(Color.TRANSPARENT);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
		paint.setStrokeWidth(1);
</pre>
<p>With the paint set to CLEAR mode, the Android graphics functions can then be used to alter the image pixels.</p>
<h2>New Things Uncovered</h2>
<p>I recently picked up a Motorola Xoom that I have also thrown AndPingus on to.  It showed me that there are a couple of pretty interesting issues with the current implementation:</p>
<ul>
<li>Proper Speed Scaling<br/>The digger handler doesn&#8217;t properly account for clock speed and digging happens way too fast on something as fast as the Xoom.</li>
<li>Extra Large Screens<br/>Recent Android versions introduced extra large screen support.  Unfortunately, AndPingus isn&#8217;t correctly utilizing the screen size yet.  I&#8217;m still trying to understand how to properly handle older devices at the same time as the extra large screen size.</li>
</ul>
<h2>Planned Source Release</h2>
<p>I&#8217;ve decided that I&#8217;m going to go ahead and release a couple of utility pieces of the AndPingus source code as open source for others to take advantage of.  My plan is to make available the following pieces:</p>
<ul>
<li>QuadTree<br/>I created a QuadTree implementation for searching the sprites.  At the moment, because of the ground tiles, that code is not being used.  However, it seems like it may useful to others.</li>
<li>Drawable Texture Support<br/>This is the underlying implementation of the destroyable terrain implementation in AndPingus.</li>
</ul>
<p>As I mentioned before, I&#8217;m getting busy with soccer coaching these days, so I can&#8217;t offer a specific timeframe for the release.  Before I can make that happen, I need to decide on appropriate licensing and hosting options.  In addition, I need to do at least a bit of cleanup before unleashing it to others.  Stay tuned to this blog for more information when it becomes available.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/05/07/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-3/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Pingus on Android – “Destroyable Terrain” #2</title>
		<link>http://www.setera.org/2011/03/27/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-2/</link>
		<comments>http://www.setera.org/2011/03/27/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-2/#comments</comments>
		<pubDate>Sun, 27 Mar 2011 21:32:08 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=431</guid>
		<description><![CDATA[When we last met I had begun working on the ability for the Pingus character to destroy the terrain. At that point, I had managed to get the images updated for the sprites that made up the image, but since those images were shared all of the sprites that shared the image were being affected. [...]]]></description>
			<content:encoded><![CDATA[<p>When we <a href="../../../../2011/03/05/pingus-on-android-destroyable-terrain-1">last met</a> I had begun working on the ability for the Pingus character to destroy the terrain.  At that point, I had managed to get the images updated for the sprites that made up the image, but since those images were shared all of the sprites that shared the image were being affected.<br />
<span id="more-431"></span></p>
<p>I added support to separate the sprite images when a sprite needed to be altered, but it took me a while to realize I was forgetting to set the correct position for the newly created sprite.  This resulted in this confusing result.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/cQTSG325xMo?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/cQTSG325xMo?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>Once I realized that the issue was due to incorrect image/sprite generation, I had a much better result.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/B_IeC-LCdDo?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/B_IeC-LCdDo?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>It became clear very quickly that my current approach for ground sprites was not going to work very well.  Using the same images scaled and rotated in various ways makes it very difficult to find the correct sprite and, as you can see from the red X&#8217;s, it also means that many sprite images may need to be altered in the course of digging out a particular chunk of terrain.</p>
<h2>Ground Tiles</h2>
<p>To improve this such that the sprites would be more aligned and easier to deal with, I&#8217;m switching to using pre-generated ground tiles.  The tooling that currently generates the collision map has been extended to generate a set of square ground tiles.  Starting with an image that contains all of the ground sprites:</p>
<div id="attachment_436" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.setera.org/wp-content/uploads/2011/03/ground1.png"><img src="http://www.setera.org/wp-content/uploads/2011/03/ground1-300x150.png" alt="" title="Full Ground Image" width="300" height="150" class="size-medium wp-image-436" /></a><p class="wp-caption-text">Full Ground Image</p></div>
<p>This image can be cropped down to include only the non-transparent area:</p>
<div id="attachment_437" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.setera.org/wp-content/uploads/2011/03/ground2.png"><img src="http://www.setera.org/wp-content/uploads/2011/03/ground2-300x118.png" alt="" title="Cropped Ground Image" width="300" height="118" class="size-medium wp-image-437" /></a><p class="wp-caption-text">Cropped Ground Image</p></div>
<p>Finally, it is broken down into individual tiles:</p>
<div id="attachment_438" class="wp-caption aligncenter" style="width: 310px"><a href="http://www.setera.org/wp-content/uploads/2011/03/ground3.png"><img src="http://www.setera.org/wp-content/uploads/2011/03/ground3-300x118.png" alt="" title="Ground Tiles" width="300" height="118" class="size-medium wp-image-438" /></a><p class="wp-caption-text">Ground Tiles</p></div>
<p>Each non-transparent tile is stored individually.  A new ground tile map object tracks the images and transparent tiles.  At the moment, the tiles are being generated as 128&#215;128 pixel images, which plays well with the OpenGL requirement that textures must be sized as a power of 2.  Dependent on the maximum texture size, multiple ground tiles may be laid out within the texture with a minimum wasted space.  The trick will be to pick an appropriate size to balance the various costs involved in loading and manipulating the sprite textures when destruction occurs.</p>
<p>While I had hoped to actually show this work via video in this post, I&#8217;ve run up against a bit of a roadblock.  While fixing one problem, I&#8217;ve introduced another issue that I can&#8217;t seem to resolve.  At this point it is better for me to walk away from this project for a few days and come back with a fresh set of eyes.  With any hope, my next entry will show a final working destroyable terrain implementation.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/03/27/pingus-on-android-%e2%80%93-%e2%80%9cdestroyable-terrain%e2%80%9d-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pingus on Android &#8211; &#8220;Destroyable Terrain&#8221; #1</title>
		<link>http://www.setera.org/2011/03/05/pingus-on-android-destroyable-terrain-1/</link>
		<comments>http://www.setera.org/2011/03/05/pingus-on-android-destroyable-terrain-1/#comments</comments>
		<pubDate>Sun, 06 Mar 2011 00:58:10 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=409</guid>
		<description><![CDATA[They say that slow and steady wins the race. In the case of this project, the only thing I have going for me is the slow part. Nicolas Gramlich, author of the AndEngine library on which this is based, referred to this part of the project as &#8220;destroyable terrain&#8221;. I really like that phrase, so [...]]]></description>
			<content:encoded><![CDATA[<p>They say that slow and steady wins the race.  In the case of this project, the only thing I have going for me is the slow part.  Nicolas Gramlich, author of the <a href="http://www.andengine.org/">AndEngine library</a> on which this is based, referred to this part of the project as &#8220;destroyable terrain&#8221;.  I really like that phrase, so I think I will continue to use it here.</p>
<p>In <a href="http://www.setera.org/2011/02/19/pingus-on-android-early-digger-support/">Early Digger Support</a> I covered the initial digger support.  At that point I had managed to update the <a href="http://www.setera.org/2011/01/16/pingus-on-android-more-collision-detection/">in-memory collision map</a>, but updating the actual textures driving AndEngine was proving to be a bit more difficult.  I&#8217;m still not there, but I think I&#8217;m moving in a positive direction.  The following video shows the current state of things.  The textures are being updated with a full red fill to make it clear that they have been hit.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/-8GmL4jHq_I?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/-8GmL4jHq_I?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>So, why is everything turning red?   Well, that turns out to be the next item that will need to be dealt with&#8230; shared textures.  To save memory, many of the sprites share common textures and texture regions.  Thus, in the current implementation, changing the underlying texture information affects all sprites that share that information.  This is something I knew would have to be dealt with eventually, so it appears that eventually is <em>now</em>.</p>
<p><span id="more-409"></span></p>
<h2>Quad Trees</h2>
<p>When I initially started playing with altering the texture data, I was worried about performance.  My first attempt to locate the sprites to be altered used the standard AndEngine functionality to query collisions using the &#8220;collidesWith&#8221; method for shapes.  This proved to be really expensive for gross-level collision detection.  My performance tests using the built in Android tools for capturing trace data showed that much of the cost of the terrain destruction was accountable to simply finding the sprite to be altered.</p>
<p>I had heard previously about the use of <a href="http://en.wikipedia.org/wiki/Octree">Octrees</a> in 3D to help do quick searches on the boundaries of objects.  In the 2D world, <a href="http://en.wikipedia.org/wiki/Quadtree">Quadtrees</a> are used instead.  I was surprised not to find an actual Quadtree implementation on the web, but was able to piece together a nice generic implementation based on lots of research.  With the Quadtree, I was able to get closer to reasonable performance, as you can see in the video capture.  My hope is that using a Quadtree and doing the necessary cloning to split sprite textures will lead to a reasonably performant destroyable terrain implementation, but that is still yet to be seen.</p>
<h2>Java Generics Aside</h2>
<p>My Quadtree implementation initially was built to accept a single object type.  It seemed more useful to use Java Generics to make the Quadtree more generally useful.  I was hung up by one thing though.  I wanted to be able to allow the Quadtree to accept objects with a certain interface declaration.  Basically, I wanted this:</p>
<pre name="code" class="java">
public class Quadtree&lt;T implements IBoundedObject&gt; {
</pre>
<p>Where IBoundedObject is simply defined as:</p>
<pre name="code" class="java">
public interface IBoundedObject {
	Rect getBounds();
}
</pre>
<p>However, the <em><code>implements</code></em> extension is not supported by the generics syntax.  This had me confused for a while until I realized that it is possible to do what I wanted to do, but needed to specify <em><code>extends</code></em>:</p>
<pre name="code" class="java">
public class Quadtree&lt;T extends IBoundedObject&gt; {
</pre>
<p>I&#8217;m sure there is some perfectly good technical reason for doing things this way, but personally I find the lack of consistency confusing and unnecessary.</p>
<h2>Next Time</h2>
<p>With any luck, I will be able to show a reasonably performant implementation of destroyable terrain by pulling the various pieces together.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/03/05/pingus-on-android-destroyable-terrain-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pingus on Android &#8211; Early Digger Support</title>
		<link>http://www.setera.org/2011/02/19/pingus-on-android-early-digger-support/</link>
		<comments>http://www.setera.org/2011/02/19/pingus-on-android-early-digger-support/#comments</comments>
		<pubDate>Sat, 19 Feb 2011 20:28:42 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[AndEngine]]></category>
		<category><![CDATA[AndPingus]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Mobile]]></category>
		<category><![CDATA[Software Development]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=401</guid>
		<description><![CDATA[Work and life have conspired to keep me from making a lot of progress on my Android on Pingus project. I had hoped to get further before posting here again, but instead decided to go ahead and post a minor update. In my last post I covered my early collision detection implementation. The next step [...]]]></description>
			<content:encoded><![CDATA[<p>Work and life have conspired to keep me from making a lot of progress on my Android on Pingus project.  I had hoped to get further before posting here again, but instead decided to go ahead and post a minor update.  In my <a href="http://www.setera.org/2011/01/16/pingus-on-android-more-collision-detection/">last post</a> I covered my early collision detection implementation.</p>
<p>The next step was to start implementing some behaviors for the Pingus.  The <em>digger</em> behavior seemed a good place to start.  In order to implement the digger, it is necessary to actually alter the collision map generated by the tool.  In the end, this part was pretty easy to handle.  The results are captured in the video capture.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/JXHjl-FJ5us?hl=en&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/JXHjl-FJ5us?hl=en&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>While it was relatively easy to carve out a path through the in-memory collision map, updating the actual graphics is proving to be much more difficult.  AndEngine implements 2D graphics using 3D/OpenGL.  This implies that in order to update the graphics, the underlying texture images need to be updated.  I&#8217;m in the process of building AndEngine support for altering the underlying texture images.  At the moment, this appears to be slow and may need to be abandoned.  Just like while I worked on the collision map, the lack of guarantee for clipping and Z buffer on Android devices further complicate the situation.</p>
<p>While there are times that I wonder if using AndEngine for this project is makes it more difficult, I&#8217;m not quite ready to give it up.  More to come&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/02/19/pingus-on-android-early-digger-support/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android Camera Preview Sizing</title>
		<link>http://www.setera.org/2011/02/01/android-camera-preview-sizing/</link>
		<comments>http://www.setera.org/2011/02/01/android-camera-preview-sizing/#comments</comments>
		<pubDate>Wed, 02 Feb 2011 02:50:20 +0000</pubDate>
		<dc:creator>Craig Setera</dc:creator>
				<category><![CDATA[Android]]></category>

		<guid isPermaLink="false">http://www.setera.org/?p=385</guid>
		<description><![CDATA[A quick &#8220;from the trenches&#8221; post. Recently I&#8217;ve been digging in to the Android camera a bit. The Android SDK samples have an example of how to wire up a live preview from the camera on the device directly to a Surface view. Unfortunately, this fails miserably on my Samsung Captivate with a repeating error [...]]]></description>
			<content:encoded><![CDATA[<p>A quick &#8220;from the trenches&#8221; post.  Recently I&#8217;ve been digging in to the Android camera a bit.  The Android SDK samples have an example of how to wire up a live preview from the camera on the device directly to a Surface view.  Unfortunately, this fails miserably on my Samsung Captivate with a repeating error similar to the following.</p>
<pre>
07-04 12:23:45.101: ERROR/copybit(2230): Error in VIDIOC_STREAMON
07-04 12:23:45.101: ERROR/copybit(2230): Fail : v4l2_stream_on()
07-04 12:23:45.106: ERROR/copybit(2230): stretch_copybit::sec_stretch fail : ret=-5
</pre>
<p>This had me stymied for a bit until I took a look at the awesome <a href="http://code.google.com/p/zxing/">zxing (Zebra Crossing) project</a> where I stumbled on to a solution for this problem.  (All credit goes to their developers).  The code in their <a href="http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/camera/CameraManager.java">CameraManager class</a> and <a href="http://code.google.com/p/zxing/source/browse/trunk/android/src/com/google/zxing/client/android/camera/CameraConfigurationManager.java">CameraConfigurationManager class</a> goes through a number of gyrations to pick an appropriate preview size.  Using that code allows the Captivate to properly render a live preview.</p>
<p>Thanks to the zxing crew for this little tidbit, as I&#8217;m not sure I would have figured this one out on my own.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.setera.org/2011/02/01/android-camera-preview-sizing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

