Saturday, August 28, 2010

How Do You Know Which Android API To Develop Against

If you are building any Android Applications you already know that you must declare a http://schemas.android.com/apk/res/android:uses-sdk@android:minSdkVersion in your application, like this in XML:

    <uses-sdk android:minSdkVersion="3" />

But how do you know which version to use?  Heck, how do you even know what version your current application code supports?

Google says to just keep backing it off until you find a bug:

Selecting a platform version and API Level

When you are developing your application, you will need to choose the platform version against which you will compile the application. In general, you should compile your application against the lowest possible version of the platform that your application can support.

You can determine the lowest possible platform version by compiling the application against successively lower build targets. After you determine the lowest version, you should create an AVD using the corresponding platform version (and API Level) and fully test your application. Make sure to declare a android:minSdkVersion attribute in the application's manifest and set its value to the API Level of the platform version.



Google also maintains a very, very useful resource here that shows the current state of the Android ecosystem (or as some people call it, fragmentation!)

Basically the idea is, declare an absolute bare minimum in your Android manifest so you can penetrate the market as much as possible.

I am using minSdkVersion = 3, but I can see 4 being another logical choice.  If you are minSdkVersion=7 you must have a really good reason -- like you are using some API7 and above only features. 

Otherwise, you are just missing out on customers.

FILL_PARENT was renamed to MATCH_PARENT will cause String types not allowed (at 'layout_height' with value 'match_parent')

Having "Error: String types not allowed (at 'layout_height' with value 'match_parent').    Android AAPT Problem" in Eclipse?

Check what API Level you are using.

FILL_PARENT was renamed to MATCH_PARENT in API Level 8 (Android 2.2)

I personal think "FILL_PARENT" makes more sense, but I was using them both thinking they did different things.  Probably best to just use "FILL_PARENT" for everything for now. 

API 8 is pretty new.

Thursday, August 26, 2010

Lets Talk about TabHosts and ActivityResult, finish() and so on

If you are using TabHosts and Activities in your application, you should read http://stackoverflow.com/questions/2497205/how-to-return-a-result-startactivityforresult-from-a-tabhost-activity

The is a quick stackoverflow question that everyone should read if you intend to use TabHosts and Activities.  If you have Activities returning results and Intents from inside the tab, or tab group, you will need to use the methods discussed.

There is even a nice paste of some Android 1.6 source code that helps explain finish().  It is really impressive how light the Android framework really is.

- Cory

Tuesday, August 17, 2010

TextView and NewLine in Java

One way to save on the number of nodes in your UI is to use the '\n' newline in TextView as show in this page.

http://stackoverflow.com/questions/2840608/how-do-i-add-a-newline-to-a-textview-in-android
Here is a nice Visual Guide to Android 2.0 UI Widgets. An IBM hosted page about working with XML in Android.

Here are some partially answered questions about SQLite database paths. Regarding SQLite database paths and Android, here is a very widely read page about Using your own SQLite database in Android applications.

I really like the Intent and Intent Filters system in Android 2.0

Some applications people are creating are crazy impressive and amazingly complex. LIke OSMDroid! Before you publish, you have to Sign Your Android Applications and you had better Test your Application on an Android Device before you put it on the Market! Whatever you publish, don't publish NotePadv2.

I tried to use Android Google Map View but my experience with the v2 and v3 JavaScript Google Map API has poisoned me. I struggle.

Getting Eclipse to ignore your SVN folders (you are using SVN I hope) is a good idea and is critical to do before you try to publish to the Market. How Do I get Eclipse to Ignore my .SVN Folders?

TableLayouts are fun, but they are even more fun when you can add rows to them! Adding Dynamic Rows to an Android TableLayout. Oh man, Icon Design scares me. I can load Bitmaps with the best of them, but I can't make them to save my life. I guess my applications will always sport that "I hate my users" stock icon look from the Google Android Free Icon Basics and Icon Packs.

Android Run-Down, Tuesday August 17th

I have been building the Google Android applications using Eclipse, ADT and my HTC Sprint EVO phone. Started by installing the Android SDK Starter Package.

While working on a number of application projects, I have created a few public domain sample projects, like AndroidDemoViewTrain, which is hosted on CodePlex and contains a number of coded, commented and clarified (I hope!) Google samples.

Once I was done with basic TextView and Button demos, I moved onto more complex tasks -- the so called Common Tasks in Android list. You can tell from Google that Android is pretty new -- a lot of unanswered questions on the boards -- maybe just a reflection of the community or whatever, but the information on solving Android issues and error messages is scant compared to C# or Apache. Also, I found a lot of bad information out there as well -- lots of posts full of bad assumptions or incorrect statements, so take what you read back to the Google documentation and test laboratories.

One of the first things that I needed to do was include two database tables in a single Android application database. I will blog about that later, it was harder to find the real-deal info than you might imagine. Got it done though.

Next thing I needed to do was populate a Spinner with an SQLite database query. If you have two tables in your database, one of those tables is probably a "Type" table and you need drop downs to select types.

Populating an Android Spinner Control from Database is pretty similar to populating an Android Spinner Control from XML. This dcPages story has a good write up of the database process here at Android Tutorial: Populating Spinners - Populate Spinner using Database Query

Then I discovered that you have to be very careful trying to feed Int or Long java primitives to the Android API because it assumes that they're keys for special resource collections. Instead of passing in TextView.setText(i) you need to use TextView.setText(Integer.toString(int i))

Now, all that was well and good -- I was populating Spinner controls and using setText() on integers to put database state onto the screen. Then I realized that Spinner controls were no good for me if I could not figure out what had been selected and then I was off again -- reading about Retrieving Selected Spinner Values on Android -- an important question if you are going to spend time populating them from the database. I blogged about that part earlier here, at How to Know What is Selected in Android Spinner.

Once I started calling lots of additional Android Activities and exploring the advanced features of the Android Application Manifest file, I became aware of a strong need to reach a full understanding of Intents and Intent Filters. To that end, I read a series of lectures by Victor Matos (PPT of Google Docs, basically) here at CSUOhio.edu: http://grail.cba.csuohio.edu/~matos/notes/cis-493/lecture-notes/Android-Chapter12-Intents-1.pdf

Also, another good page on Using Intents to Transfer Data between Android 2.0 Activities. Very similar information to this page about Passing Bundles Around Activities but still good reading.

Soon after that I needed to create Dialog Boxes in Android and therefore, I went back to Google for more searching and ended up playing with Scrollable CellMaps instead. SurfaceHolder is a hell of a class, my friends! Then I started back on Displaying Alert Dialog in Android. Any type of alerting is bound to contain concerns about modality so here is Modal Dialogs in Android for your reading pleasure.

After getting the advanced use of system events (Intents, Activities and Intent Filters) I moved onto the Handling of UI Events in Android. A critical topic for any serious developer, Android events are managed very differently than the three-type event engine (jQuery, WCF and BI) I am familiar with.

Event Listeners
An event listener is an interface in the View class that contains a single callback method. These methods will be called by the Android framework when the View to which the listener has been registered is triggered by user interaction with the item in the UI.

Event Handlers
If you're building a custom component from View, then you'll be able to define several callback methods used as default event handlers. In the document on Building Custom Components, you'll learn see some of the common callbacks used for event handling.


After that I started adding some visual styles of my applications and read the Icon Design Guidelines for Android 2.0 which, I admit, did put the fear into me. I'm looking for a graphic artist now. However, that somewhat daunting trip down pixel lane did clear up a number of pressing concerns I had with my application's resources and the file structure in Eclipse.

First was -- "In Android Eclipse, what are all these mdpi and hdpi folders for? Which one do I use and what does it mean?" Well the answer can be found here where Google outlines The Android 2.0 UI Guide's Best Practices for Supported Screens. Here are the physical examples of the device screens and how they sort out by Density and diagonal: Range of Android Screens Supported by the OS.

Still too complicated? Yah, I know. How about this link? What Size Do I Make My Icons and What Folder Do I Use in Android 2.0 with Eclipse? Another one is How do I make Android Icon Packs and get Free Android Icons? I hope you have mad Photoshop CS3 skills that I don't posses if you are thinking about creating Icons.

Then, soon after that, I discovered TableLayouts. A few days later, I read this guy's blog post Android Nuts and Bolts IV where he also discovered TableLayouts. He might like them a little too much, but the blog is good.

Once you have tables, you will need Menus! http://developer.android.com/guide/topics/ui/menus.html

This guy's question claims that he has a bug with TextView, but when I read it saw how his "bug" is actually exactly how it needs to work and what valuable feature "Hint" is: Android 2.0 TextView Automatically Adjusts Width when Configured.

I started using a SeekBar. Nice UI: http://developer.android.com/reference/android/widget/SeekBar.OnSeekBarChangeListener.html

Once I had the SeekBar in place I started looking at the rest of the controls and reading a few Android 2.0 GUI Examples blogs helped me get a visual idea of what they all look like. Another Android 2.0 GUI Example Blog with TextView and TableLayout. Did I mention TableLayout is really very valuable? Android has a great TableLayout control, once you learn how to make it work. It is not CALS-Model SGML / XHTML tables, but it works on your phone.

I started looking at Android 2.0 UI Themes but only found this incomplete Android 101 blog entry about defining XML themes.

READ THE ANDROID DEVELOPER BLOG
Was that aggressive enough? Reading the blog taught me a lot -- and today I learned about Back Button, Hard Keys and Long Press in Android 2.0 UI.

Rotating Bitmap with Bitmap.createBitmap and Matrix objects -- you will find the details in someone's code on this page: http://www.anddev.org/resize_and_rotate_image_-_example-t621.html

How do I center text horizontally and vertical in a TextView in Android?


Very soon after that I was adding additional tables to my DbAdapter class and once you have 4 or five tables, you need to have JOIN! SQLite Join Syntax

Saturday, August 14, 2010

Another Good Blog About Android Views and ViewGrous

http://mobiforge.com/designing/story/understanding-user-interface-android-part-1-layouts

After I have made about 50 Android Views and used all the ViewGroups, I figured it was time to go read about what the heck I have been up to and see if I could make sense of the hacking I had been using.

Found a number of good blogs and went back over the Google documentation. I am still struggling to do things that are immediate and easy for me in XHTML and CSS. Maybe what I am missing is the CSS? I guess it is another X-format to memorize and learn. At least there is only one "browser" the Android API Level 8 for me.

Passing Around Serializable Objects

http://lyle.smu.edu/~coyle/cse7392mobile/handouts/Intent.DataPassing.ZomDroid.pdf

Seems very well written, but I hate giving up method calls like that. Public? I hate it ... but I want my Androids to be very fast ... bummer? Or just life on the edge?

Friday, August 13, 2010

Knowing What is Selected In Android Spinner

You have getSelectedXXX methods from the AdapterView class from which the Spinner derives:

getSelectedItem()

getSelectedItemPosition()

getSelectedItemId()


These are really good methods.  You get the row_id back!!!

Wednesday, August 11, 2010

Visual Guide to Android Widets

http://www.droiddraw.org/widgetguide.html

This is a nice visual guide to Android widgets.

The page is very straightforward -- a basic table containing screenshots of the widget plus the XML and Java to put one in your application.

Tuesday, August 10, 2010

Android Activity Lifecycle

The Android mobile operating system has a well-defined life cycle for Activities and application components running in the OS.

Lifecycle events can happen even if the current component is not handing off control to another Activity explicitly -- the mobile OS is a very busy place and things happen constantly that you, as the developer a single application, cannot control.

For example, perhaps a call comes in to the handset. If this happens, and your Activity is running, it will be swapped out while the call Activity takes over.  What is an Alarm goes off?  What if the task killer elects to eliminate your package?

http://developer.android.com/guide/topics/fundamentals.html#lcycles