Day 2: The Journey to Hiroshima

For those not following the planning of this trip, there are 2 key elements to it: Hiroshima Peace Ceremony and the Mt. Fuji Climb.  Today, I began my long journey from Tokyo to Hiroshima.

The day started well enough, I got to sleep in till about 8am. Had time to take inventory and understand what I had.  Initially I had planned to take my suitcase and leave my hiking pack.  However, given that there would be a stop in Osaka to visit Mari-chan, I decided against this for ease of use.  Thus, I left my suitcase at the Marriott and proceeded to Osaka.

P8040011_resize

It was at this point where things began not going as planned.  The train I had intended to take, Hikari at 1010 from Shinagawa was full.  This is the first time in all of my visit I have ever run into this problem.  I ended up taking the Hikari 469 at 1110 instead.

P8040015_resize

This delayed me by one hour, thus I arrived in Osaka at 200pm instead of 100pm as was intended. Not a huge difference.  I just love the Shinkansen, it’s the epitome of efficiency for the Japanese.  3hrs, that’s all it takes to get from the largest city in Japan to the 3rd largest; and not on the outskirts either like you get with an airport, but right in the city center.  See, the Tokkaido Shinkansen doesn’t run all the way to southern portion of the island, most trains stop in Osaka where the Sanyo Shinkansen takes over, so there is always a transfer at Osaka when going this far south.  Knowing thus, I arranged for Mari-chan to meet me for lunch; it was very good to see her again.

P8050017_resize

It doesn’t matter to me how strong you think you are, you take a trip like this and you do get lonely.  It really means a lot to me to have friends and people to chat with when I am there, I don’t like the great isolation and loneliness that tends to accompany these trips at all.

I had a great time with Mari at lunch, she is just so cool and nice.  Her English is much improved from last year, which is good cause my Japanese has fallen off, again Smile.  It is just so hard to keep it up when you don’t use it at all back home.  Unfortunately, I missed my connecting train to Hiroshima after parting ways with Mari.  There is nothing worse, in my mind, then making a stupid mistake and then having to try to explain it to someone who doesn’t speak your language.  Thankfully, after three tries it dawned on me: I have a Rail Pass, I can just buy another ticket.  Did that and jumped on the Sakura train bound for Kagoshima, but stopping at Hiroshima.

P8050018_resize

Another reason I love Japan; they get mass transit.  Maybe its because Americans are so fond of their cars that most of our mass transit equipment is about 20yrs old where as the Japanese are constantly investing in it and, they are just cleaner as a society then America.  This is what my seat looked like on the train.

P8050019_resize

Among the decisions I made in planning for this trip I made sure the hotels I choose where close to my arrival point as possible or were hotels I knew the location of beforehand (Marriott).  With Hiroshima, I picked the new Sheraton (it just opened two months ago I am told), literally right outside Hiroshima station.

P8050022_resize

I really lucked out here, this is literally one of the nicest hotels I have ever been to, and I have been to quite a few hotels.  Definitely the most modern of the any hotel I have ever stayed at and with an incredible view of the city.

P8050024_resize

Oddly enough, despite the fact that I booked this room through Travelocity, hence why I could afford it, Sheraton was somehow able to use my Starwood frequent stayer account.  Not really a problem except that they decided to use the American Express associated with the Starwood account for co-incidentals and any extra charges (Internet).  Again not a problem until you realize, as I did, the Amex card associated with Starwood belongs to RCM Technologies and no reason I should get them in trouble.

Perhaps the coolest thing about the room has this:

P8050025_resize

Basically, its quite interesting how the hotel saves money, no lights in the room will allow themselves to be turned in, unless there is a reason.  That means, I cannot leave the room and leave lights on.  really neat, compliments the room quite nicely.

I have to say at this point, I am starting to really understand why using a travel agent is so critical.  Don’t get me wrong, I love what I have done and all the help I am getting but, if not for a couple solid decisions, the tune of this trip could be very different.  Today was difficult, Ill say it, if I had taken the suitcase rather then the hiking pack, I don’t think I would’ve gotten out of Shinagawa, let alone all the way to Hiroshima.

Its also incredibly lonely.  I am so thankful that I have friends like Mari and Mami to hang out with me because it really sucks doing all of this traveling alone.  You cant even enjoy a ribbing when you cant set the alarm clock in your room cause you cant read the button labels.

Anyway, as I sign off for the night, I leave with the view of Hiroshima from my hotel room, looks like the local baseball team is still in action.

P8050032_resize

By the way, it has been so hot here.  Was over a 100 in Osaka, God only knows how warm it is in Hiroshima, its farther south.  Also, it seems we had a typhoon just miss hitting the island directly, but that we did feel the effects of, so that explained the intense and sporadic rain today.

Day 1 : Traveling to Japan

Unlike last year, my vacation to Japan started a bit earlier this year, August 3rd thanks to my parents taking my brothers and I to Comerica Park in Detroit, MI for a Tiger game.  This is the third time I have been to the park.  It was  a lot of fun hanging out with everyone, even though we got absolutely soaked Smile

ComericaPark

Anyway, I knew that going to this game presented a risk cause sleep would be hard to come by during the course of my trip; I have never slept well on planes.  Thankfully I got about 5hrs ahead of the trip.

The first part of the journey was from Detroit to Toronto via my first ever “turbo-prop” plane ride.

TurboProp

I will say this, these planes are LOUD!!! And it seems like the positioning of the emergency exit is not the smartest location, as I told the flight attendant “there is a giant whirling propeller outside the exit!!”.  Anyway, aside from a bit of nervousness, the trip was uneventful.  We arrived in Toronto in good time.

While waiting for the plane I had a great chance to meet a Serbian immigrant by the name of Pete. He was on his to the “former Yugoslovoia” which is now 10 different countries.  Beautiful area, the Balkands, but a lot of fighting and politics over the past 20yrs has heavily divided it. Thankfully, I had been paying attention to the news of late and we had a good conversation about American foreign policy and the fate of  Slobodan Milošević who is being tried for war crimes.

It is at this point of the trip that things began to slide south.  First, Air Canada, I love your plane and Toronto is a wonderful airport but, DO NOT DELAY A 12hr FLIGHT FOR 2HRS BECAUSE YOU CANT GET THE TV SYSTEM WORKING!!!  Especially after we board a flight already delayed 2hrs.

P8030011_resize

I am not joking, this problem delayed our departure from Toronto by 2.5hrs!!! It totally destroyed any chance I had of hanging out with Mami in Fussa for the festival.  Though, perhaps it was a blessing in disguise.  The delay allowed me to avoid rush-hour and forced me to actually go to bed 🙂

The flight to Tokyo was smooth and uneventful, if not a bit longer then I remember. Unfortunately, my goal of working on my Windows Phone 7 app was dismissed because MPNS (Microsoft Push Notification Service) requires Internet even if you are using a local service reference.

Upon landing in Narita, I was amazed at how well the experience last year prepared me for things.  Last year, because of a mix-up in arrivals, it took the better part of 4hrs to get through Customs and Immigration, this year, about 30m total.  After that I exchanged my money, when down and got my Rail pass.  Bit of a snag here, I had to delay the start of the pass for one day to ensure I could cover the Shinkansen from Osaka to Tokyo on the 11th.

But again, this might have been a blessing in disguise. Because the reliance on JR trains was removed for the night, I was able to take the Skyliner line from Narita to Ueno. 

P8040012_resize

Ueno, is much farther north then Tokyo and I had made it a point to limit my travel due to the three bags I was carrying. So, as I rode I knew I would have a tough go of it, working down the Yamanote to Tokyo, and then Maronouchi and Hibiya subway lines.  But I caught a break.  The Hibiya line connects to Ueno!!

Once I learned this, and having studied the Tokyo subway maps in detail prior to departure, I jumped at the chance.  It was some extra walking at Ueno station, but instead of changing trains and going through “The Maw” I was able to circumvent the whole process and get there quite fast.

And as I came up to street level from Higashi-Ginza, my photographic memory immediately kicked on, and I recognized EXACTLY where I was and I knew where the hotel was in relation.  At this point, my body was beginning to really complain.  I did sleep, somewhat, on the plane, but certainly not comfortably. I made it to the hotel and up to my room and was greeted with awesomeness: being a Platinum Marriott member (still) I am always treated like royalty at Marriott hotels, especially the really nice ones.

After arriving, I immediately took inventory and reorganized things for tomorrow’s trip to Hiroshima.  Only had a couple things explode, but I knew they might so they were isolated from everything else.  Spent the remainder of the evening playing with my Trophy tinkering with the settings to make the phone work properly.

At present, I am debating, internally, if a prepaid cell might be a better choice for right now.  With voice calls costing $2/min and sending txt messages not all that much cheaper, it very well might be the best option, even if it is unexpected.  Unfortunately, my Japanese language skills are not quite good enough to where I would be comfortable buying a cell phone here.  In my experience, while many Japanese can speak English, they don’t speak it well and certainly the people in the small shops don’t speak it with enough confidence to where I would be willing to buy a cell.

This matter will be worked on today.  Tomorrow’s entry will show me meeting my friend Mari in Osaka as I make my way to the Hiroshima Sheraton.

Part 2: IntelliJ and Android

In my previous post I talked about installing and setting up Android to work with the JetBrains IntelliJ because in my view the development experience is a huge improvement over what is afforded to developers by Eclipse.  In this post, I will talk about how to use emulators and the other various tools you may or may not be familiar with

Setting up an Emulator

Working with any mobile operating system is going to require emulation to mimic various devices and situations.  Android is not only the exception, but with its proliferation as an open operating system it finds itself on a wide variety of devices.  Use the SDK Manager tool to install skins and other emulator profiles, this will be essential in your test.

To create an emulator, use the SDK Manager that comes with Android, it is accessible from directly within IntelliJ (see below)

2011-07-30_2314

The option you will want out of the submenu is “Android SDK and AVD Manager”.  The SDK Manager is responsible for adding/removing various optional components from the SDKs that you have installed, as well as adding new Android SDKs.  The AVD Manager is responsible for managing the emulators.  As you can see, I currently have a wide variety of emulators available on my current system.

2011-07-30_2317

To add a new one, press the New button.  This will bring up the next screen where you provide the configurations for your emulator of AVD.

2011-07-30_2318

The main things to be concerned with here is the Name, which I have provided as Gingerbread_WVGA, indicating the SDK name and the resolution the emulator will run at.  At this point you could hit Create AVD and be done, but lets explain the other sections.

  • SD Card : Specifying this size allows you to mimic a device with an SD Card.  If your app is going to save anything to the phone, you will need this as a storage mechanism
  • Skin : This is the device you want to mimic, it could be a Galaxy or Milestone.  I generally leave as default with a standard resolution (HVGA or WVGA).  You can download additional skins through the SDK Manager
  • Hardware : Depending on what you want to do with your app, you may want to add certain hardware features to the emulator to more closely simulate an actual device.

The end result, if successful, is the device should now appear in your AVD list.

Using an Emulator

For most apps, I recommend using an emulator set to the lowest possible version you want to support, 2.1 is the most common platform target since 2.x makes up roughly 90% of the platform distribution for the Android platform.

To set a certain emulator to run when running the app, you will need to set a Run Configuration (shown below)

2011-07-30_2326

This will bring up the Run/Debug Configurations screen where you can configure the run.  For this particular application I have two configurations PayItSquare and PISDevice.  The second one is more manual and allows me to target an actual device if one is plugged in.  The first one is my default and runs my Éclair emulator to emulate a device running Android 2.1-update 1.

Configuration 1

2011-07-30_2331

Configuration 2

2011-07-30_2329

We are going to demonstrate the second configuration since it gives the most flexibility.  I would encourage a new user to explore the various options on all the tabs (Emulator, Logcat as well) to get a good feel for how to bring the emulator as close as possible to the device a user will be using.

Hitting Play with the second configuration selected will bring up the following screen:

2011-07-30_2334

As you can see, at the current moment I have no Emulators running or devices plugged in.  If I press the Launch Emulator button, I can select which emulator I wish to run the app in (see below).

2011-07-30_2335

This display is even nice enough to tell us which emulators would not be compatible with our projects target SDK.  In this case, I would pick the Eclair _HVGA emulator.

Note: when you press OK your app will NOT be deployed to the emulator.  You will have to keep the other window open until the emulator instance shows up.  I generally wait till the emulator reaches the start screen before hitting Refresh.

Once you see the emulator instance in the selector window (hit Refresh) you can select it and indicate to IntelliJ to deploy your app to that emulator:

2011-07-30_2338

This will launch your app.

Using Logcat

Logcat is the secret weapon of most Android developers, it provides information, straight from the phone, about what is happening (or happened) under the hood.  It will even give you stack trace information when an error is encountered, its damn handy, and IntelliJ makes it really easy to use.

Mine is located at the bottom of my development environment

2011-07-30_2354

Clicking on this will bring up the Logcat for all connected Android devices and emulators.  There does tend to be a lot of data, so look for Red if you trying to determine the cause of an error.

I hope this helps people looking to use IntelliJ as their new development environment over Eclipse.

Upgrade to IntelliJ

As an Android developer I took the normal road when I started Android development, I used Eclipse and worked with the tools supported by Google through the ADT. But like many developers, I grew tired of the quirkiness of Eclipse and began looking for a better option. I found it in IntelliJ from JetBrains, makes of another favorite tool of mine ReSharper. However, the caveat to IntelliJ is that you wont found as much documentation on setting things up as you will for Eclipse, this blog post is meant to solve that. Lets get started:

1) Get the Android Tools – this may seem like a weird place to start but, it works out b/c the Tools installer will tell you where to find the correct Java Installation, if you don’t already have it. You can download the installer here: installer_r12-windows.exe (Windows Only).

If you are special, like me, you will get this lovely message when you try to install it:

2011-07-25_2109

Follow these instructions to get the CORRECT Java SDK, it must support x86.

2) Downloading the JDK – I always do it this way to make sure I get any new updates to the path that Google has found. The key here is to get the x86 version of Java, x64 doesn’t seem to work at this time. Download the SDK here: jdk-6u26-windows-i586.exe

2011-07-25_2154

3) Installing the JDK – This step is very simple, just follow the instructions and take all the defaults.

4) Get Android Tools and SDK – Now that you have Java, you can run the Installer which will install the SDK and Tools on your machine.

2011-07-25_2232

You might get this message, even though Java is installed. This is a weird error within the installer, the workaround is to hit Back, and then Next, which should fix the problem

2011-07-25_2233

Take the remaining defaults and complete the installer. Understand that at this point you do NOT have the Android platform, only the tools. At the end of the Tools installation, the SDK manager will launch and prompt you to download the platforms. You can pick and choose here, but I always just take everything

2011-07-25_2235

Understand that this will take a few hours, depending on your connection speed. Alternatively, hit “Cancel” here and choose a package from the “Available Packages” list and install that.

You can confirm what you have installed by using Windows Explorer to look at c:\Program Files\android\android-sdk\platforms – there you should see something like this

2011-07-25_2255_001_001

5) Download and Install IntelliJ – While the installation process is proceeding, head over to JetBrains and download IntelliJ Community, here is the link: http://www.jetbrains.com/idea

Using the installer take all the defaults and install the application.

6) Configure IntelliJ – Once the download is complete for Android and you have IntelliJ installed, you can run the application and configure it to support Android. This is a two step process, all of which can be handled by running the “Create Project Wizard” and select the Android Module as the type.

2011-07-25_2258

The next window you are looking for is Project JDK. This will be blank and that is a problem, hit Configure to tell IntelliJ where Java is.

2011-07-25_2259

Simply select the path you installed Java to (mine is c:\Program Files\Java\jdk1.6.0_26) and hit Ok.

With this you now have a JDK that IntelliJ can use. Hitting Next will take you to the Android specific setup screen. The glaring problem is in red

2011-07-25_2302

We have no Android SDK to work with. Its no big deal, just need to tell IntelliJ where our Android SDK is, to that hit the button to the right of the Android SDK dropdown.

Hitting this will open up the following dialog. On this dialog hit the + (indicated by the red arrow) to add an Android SDK reference to the classpath.

2011-07-25_2304

Select the android-sdk (mine is C:\Program Files\Android\android-sdk) folder in your path, this will prompt you with the available platforms at that path. In our case, we have only Android 2.3.3, take that and hit Ok. Note, it may ask for the Java version, select 1.6 in this case (it should be the only one). Below is the completed SDK selection

2011-07-25_2306

Hit Finish and IntelliJ will setup a default Android Hello World application. Congrats, you know have an Android enabled IntelliJ installation. Our next segment will cover getting the emulator going and understanding why we would need multiple emulators (or AVDs).

WM .NET UG: SOLID and MVC Safeguards

This past Tuesday the West Michigan .NET User Group featured two out-of-state speakers presenting for a special meeting.  We had Stephen Bohlen out from New York and, as a surprise, Adam Tuliper from Pennsylvania.  Steve spoke on the SOLID principles introduced by Martin Fowler and Adam talked about how to secure your ASP .NET sites (both webforms and MVC) against malicious attacks, such as XSS (Cross Site Scripting) and SQL Injection.

How Adam became involved in this was quite interesting, as Steve recommended him to me based on Adam’s interest and that he has family in Rockford, MI.  We happily invited Adam to speak, though we could only give him 30m to speak less Steve not have enough time (SOLID is a fairly big topic).  The result was impressive.  While Adam had to cut quite a bit out he impressed the entire group; so much so that we intend to ask him back next year to give a full talk.

Steve, whom I met when I was consulting in New York last year, presented on a topic of great interest to me: SOLID. Generally speaking, when you talk about Object Oriented programming, you learn about the three pillars on which the paradigm is built: Inheritance, Encapsulation, and Polymorphism.  A fourth one could be Composition, given some of the more modern needs of applications, but that is a debatable.

As we have progressed in writing applications certain approaches have been shown to work, while other have shown to be less effective.  This has culminated with the rise of the SOLID principles, by Martin Fowler, as a set of guides to writing modern OO applications in an effective and maintainable matter.  The principles are:

  • Single Responsibility Principle
  • Open/Close Principle
  • Liskov Substitution Principle
  • Interface Segregation Principle
  • Dependency Inversion Principle

Adhering to these five principles will generally lead to better more flexible and maintainable code.  I will not be elaborating on what these principles mean, that is simple too much for this simple blog entry.  However, a quick Google for Martin Fowler SOLID principles should yield additional information.

Looking forward to our next session (Wednesday) which is our normal meeting time, the topic will be Mango, which is something I am deeply interested in as I continue to build my knowledge of the Windows Phone 7 mobile platform.

Thanks again to Steve and Adam for being willing to travel so far to spread their knowledge and experience to our user group.

Augmenting Activities with Dialogs

One of the difficulties in working on the Pay It Square Android app is the web experience is so rich and fluid. It is always a challenge to bring that fluidity to the mobile device because the experiences are inherently different.

I think there is a tendency amongst Android developers to overuse Activities without consider the user experience and how it is affected by going deep into a stack of activities.  This is a problem.  Inevitably you will either have to write code to finish a ton of activities, or you will have the user pressing their hardware back button to get back to the screen they want.

One of the ways that you can solve this problem, in some cases, is by creating a custom dialog.  Now, that doesn’t mean you should replace all of your activities with dialogs, only where acceptable. This is the same lesson we are learning/have learned on the web with the modal dialog UI effect everyone is favorable towards.  Learning where and when to use this, vs an Activity is a crucial skill in mobile application development for Android.

The first task is to extend the Dialog class.  Note that there is an AlertDialog class that you can also extend.  This will come with a title bar and two buttons for accepting and negating the alert.  I have also found it very difficult to theme the default dialogs in Android.  For our purpose, we are going to simply extend Dialog and generate the simplest constructor, which takes our current Context.

   1: package com.ost.PayItSquare;

   2:  

   3: import android.app.Dialog;

   4: import android.content.Context;

   5:  

   6: public class MyDialog extends Dialog

   7: {

   8:     public MyDialog(Context context) {

   9:         super(context);

  10:     }

  11: }

Dialogs behave very much like Activities, in fact many of the common calls used in Activities are used here.  We can use setContentView to set a layout for the Dialog, findViewById to look up Views in that layout.  Code update is below:

package com.ost.PayItSquare;

import android.app.Dialog;
import android.content.Context;
import android.view.ViewGroup;
import android.view.Window;

public class MyDialog extends Dialog
{
    public MyDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        setContentView(R.layout.custom_dialog);
    }
}
 

There are two things that I have come to find Android will try to ensure that all dialogs adhere to: wrap sizing and presence of a title bar.  For the title bar, simply requesting Window feature Window.FEATURE_NO_TITLE ensures that there is no title bar for the dialog.  The wrap sizing can be a bit hard to understand.  No matter how much you adjust your layout code, the dialog will not change.  The fix that I have found is to set the width and height programmatically as show above.

With this, you have a custom dialog that you can do anything with.  Lets add two buttons and force the user to make a selection to hide the dialog.

package com.ost.PayItSquare;

import android.app.Dialog;
import android.content.Context;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.Button;

public class MyDialog extends Dialog
{
    private Button btnOk;
    private Button btnCancel;

    public MyDialog(Context context) {
        super(context);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setLayout(ViewGroup.LayoutParams.FILL_PARENT,
                ViewGroup.LayoutParams.WRAP_CONTENT);
        setContentView(R.layout.custom_dialog);

        setCancelable(false);
        initFields();
        setFields();
    }

    private void initFields() {
        btnOk = (Button)findViewById(R.id.btnOk);
        btnCancel = (Button)findViewById(R.id.btnCancel);
    }

    private void setFields() {
        btnOk.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view) {
                dismiss();
            }
        });

        btnCancel.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View view) {
                cancel();
            }
        });
    }
}
 

As a disclaimer, this is a coding style that I have adopted with Android when I cant use View Injection (as is the case with Dialogs), I really do try to avoid calling findViewById wherever possible.

Calling the built-in method setCancelable to false will disallow the user from dismissing the Dialog by hitting the hardware back key; use it when you require the user input.

One of the very nice conventions I like to use with custom dialogs is to differentiate a cancel action with an accept action by calling cancel and dismiss respectively.  The reason for this is that Dialog provides handlers for OnCancel and OnDismiss.  This is a good way, I have found, to easily differentiate what the user has done.

At this point, you can treat the Dialog much like the Activity.  Remember, it is still a dialog, so overloading it with functionality is never a good idea.  Use it for quick contextual editing, such as for list items.  It can never fully replace an Activity nor should it be considered such.  Think of it as what you would use a modal window for in the web world and generally you will be fine.

Announcing Mobile Monday

Tonight was the inaugural meeting of the Mobile Monday Chapter for Grand Rapids, MI. The event was chiefly sponsored by Verizon and featured some leaders from various mobile leaders in the area, both from the development and business side. Among the panelists were two people that I have had the great pleasure to get to talk to over the years: Carl Erikson and Jon Johnston. Carl is the head of Atomic Object, one of top consulting firms in Grand Rapids (and Michigan). He is someone that I have a lot of respect for as he has built his consulting company the right way and are always near the forefront on the new technologies.

One of the interesting topics that Carl brought up was the notion that in some cases, depending on need and desire, mobile may precede the web side of an application. This was a new concept for me that I hadn’t considered, since generally I feel you need to flush out the SOA architecture before you can expose it for mobile development. Carl hinted at the intimacy we often associate with our smart devices and how they become integral components of our lives as the impetus for this trend. Indeed, if you look at a service such as foursquare and ask, how often do you visit their website? Many services are settling for exposing enough functionality through their API that you don’t even need the site anymore as the functions can all be carried out by a device that, for all intents and purposes, is always with you, always connected, and always available.

Joe, I have had the privilege to talk with often, is a UI specialist for the nationally famous Universal Mind. UI is a huge, huge thing in mobile, much more so then any other content delivery mechanism of the past. Joe made some excellent points especially with regard to the major obstacle of mobile app development going web based, the conventions used by each device based on its platform; ie the hard buttons on Android devices and the lack thereof on iPhone devices.

Perhaps the biggest question I have regarding these devices is the battery. Indeed, I think we are fast approaching a point were we must investigate alternative battery technologies as our device requirements are fast outpacing what batteries can provide (my phone can barely make it through the day and I know plenty of people who regularly have to charge theirs during the day), 4G is an excellent example of this.

The next meeting of the group is August 8th at a location to be determined. As I will be traveling through Japan at that time, I will not be able to attend, but I look forward to the September session. More information can be garnered here.

Creating a Splash Screen for Android

Pay It Square utilizes a token based authentication approach to indicate an authenticated request and map the request to the particular user authenticated.  This token is generated during the login process and can be stored on the device itself for future use.

In addition to the login, it is necessary to also load some satellite data for currency information, finally if the request is authenticated we attempt to load the Collect Pages for the user.

While this could all be done in an Async Task associated with the Login Screen, I felt it would be a better experience to use a Splash Screen, in which we would perform these operations and provide a friendly indication of progress to the user.  The following code shows the Async process taking place as part of the load.  The Splash Screen is really no different then a normal Activity in the app, except that there is less control on the part of the user as to when it finishes, its handle programmatically instead.

The processing should be done off the onCreate method through an async task.  You don’t want to do this on the main thread and risk hitting the 5s limit the Android places on applications before considering “Not Responding”.

The important thing here is that when the process is complete that you call finish on the activity as you start the next activity (see below):

   1: @Override

   2: protected void onPostExecute(Boolean bool) {

   3:     if (bool.booleanValue()) {

   4:         // show the login page

   5:         showLoginActivity();

   6:     }

   7:     else {

   8:         // show the main page

   9:         showMainActivity();

  10:     }

  11:  

  12:     finish();       // kill the splash activity

  13: }

The reason you do this is to the user cannot reach the splash screen with the hardware back button.  This is a common tactic with Android apps so as to enforce control over the path the user takes, especially with respect to the user using the back button.

One of the things that I will point out that differs here from the previous version of the Pay It Square Android app (unreleased) is that instead of using SQLite, I used the Preferences engine to store the token rather then the database (see below):

   1: public class Preferences

   2: {

   3:     private final String AUTH_TOKEN_KEY = "authToken";

   4:     private final String AUTH_USERNAME = "username";

   5:  

   6:     private SharedPreferences sharedPreferences;

   7:  

   8:     public Preferences(Context context) {

   9:         sharedPreferences =

  10:             PreferenceManager.getDefaultSharedPreferences(context);

  11:     }

  12:  

  13:     public String getAuthTokenKey() {

  14:         return sharedPreferences.getString(AUTH_TOKEN_KEY, "");

  15:     }

  16:  

  17:     public void setAuthToken(String token) {

  18:         SharedPreferences.Editor editor = sharedPreferences.edit();

  19:         editor.putString(AUTH_TOKEN_KEY, token);

  20:         editor.commit();

  21:     }

  22:  

  23:     public void clearAuthToken() {

  24:         setAuthToken("");

  25:     }

  26:  

  27:     public String getStoredUsername() {

  28:         return sharedPreferences.getString(AUTH_USERNAME, "");

  29:     }

  30:  

  31:     public void setStoredUsername(String username) {

  32:         SharedPreferences.Editor editor = sharedPreferences.edit();

  33:         editor.putString(AUTH_USERNAME, username);

  34:         editor.commit();

  35:     }

  36:  

  37:     public boolean hasValidAuthToken() {

  38:         return getAuthTokenKey().compareTo("") != 0;

  39:     }

  40: }

This is a simple wrapper class that saves the AuthToken and Username to the Preference file associated with the app.  This is a very easy way to save and retrieve simple data rather then incurring the cost of setting up and maintaining a SQLite database on the device.

Handling Orientation Change in Android

I get ask this question a lot when I speak “My activities always bomb when the user switches to Landscape mode from Portrait, or visa versa.  How can I fix this?”  Indeed this is a very common problem new Android developers face.  The good news is, this is very easy to solve with minimal code.

To start with, the most important thing is to identify what activities in your app you WANT the user to be able to view in any orientation.  The truth is, there are certain activities where this doesn’t make sense (lists for example).

The first step is the Manifest.  Each Activity must be listed so that it can be loaded during execution.  This tag supports a screenOrientation attribute which locks that activity into a particular orientation.  Below is a sample from the PayItSquare app I recently wrote:

2011-07-03_1348

In this case, the screen orientation will be locked as Portrait, which makes sense for this activity.  My general rule of thumb is you can usually get away with locking activities that require no input from the user in portrait, since the user wont be entering any data in and therefore will have no use for the hard or the enlarged soft keyboard.

However, it will often be the case that you will want to handle the user changing your layout in various states.  Android does, by default, handle this for you by essentially recreating the Activity.  However, as one usually finds, this has undesirable consequences.  The trick is to tell Android to NOT handle the orientation and notify the OS that the Activity will handle it itself.  This is a two step process.

First, access the Manifest file and define android:configChanges property.  The values here are bit flags that denote which config changes the activity will handle.  The following values (or combination of them) are acceptable here:

  • mcc
  • mnc
  • locale
  • touchscreen
  • keyboard
  • keyboardHidden
  • navigation
  • orientation
  • screenLayout
  • uiMode
  • fontScale

A complete reference of these values is located in the Android Docs here, regardless the ones we are most concerned with are orientation and keyboardHidden.  In essence, orientation means we want to handle screen orientation changes (i.e. the user has rotated the screen), and keyboardHidden means entry accessibility has changed (i.e. the user has slid out a hard keyboard, which will always force the screen orientation).  Note that while you may think that you don’t need keyboardHidden, however, my experience has proven otherwise.

To start with we add this information to the Manifest (shown below):2011-07-03_2332

It is important to understand exactly what this is doing.  This is effectively telling the OS that when this sort of config change happens WE will handle it and NOT the OS.  This means we will override the default behavior, which is Activity Recreation.

To handle it, we override the following method in our Activity:

   1: // use this method to handle the screen orientation change

   2: @Override

   3: public void onConfigurationChanged(Configuration configuration) {

   4:    super.onConfigurationChanged(configuration);

   5: }

 

For the case of suppressing the Activity Recreation on the change of orientation, this is all you will need.  You can simply leave this method as it is and the rest will be taken care of for you.  The Configuration instance passed to this method can help you determine what configuration changed occurred.  For example, you could determine the user changed the orientation and thus load a new layout file using setContentView for the updated orientation.

What I have done in Pay It Square is define this method in the super class.  Then I defined either configChanges or screenOrientation for each Activity in the Manifest.  Generally, if the user was going to provide input I would define configChanges, otherwise screenOrientation.

Remember, the onConfigurationChanged method will ONLY be called for config changes that you have told the activity to listen for.

Hopefully, this should help a lot of people overcome this very common problem.

First Day with Windows Phone 7

Since November of 2009 I have been using a Motorola Milestone (Droid) with Android 2.0 – 2.2.  Its been quite successful and a great opportunity to see a modern mobile operating system in action.  Its nothing against Android, but as a .NET developer by day I cannot help by be impressed with what Microsoft is doing with Windows Phone 7 operating system, the only obstacle was: Verizon.

Recently, Microsoft and Verizon FINALLY got together and released the HTC Trophy.  I jumped at the chance to finally take ownership of a Windows Phone 7 device.  So on Friday, I purchased a new phone.  I knew that going to WP7 would, for the moment, be a step back from Android, notably in using my phone as a GPS as WP7 does not yet (Mango will) support, but I retain every confidence that Microsoft will get there.

Quite honestly though, I was surprised at just how far the app ecosystem has come since only November.  I was able to get 90% of the apps I used on Android for my WP7.  This includes Translation software, foursquare, Twitter, Facebook, Gas Buddy, and others.  I especially liked the way the OS functions, very snappy and intuitive.  I am still waiting for Angry Birds and an app interface with Chase, but I am sure those will come in due time.

However, it wasn’t all happy and good.  I had a golf outing today at a course I had never been to.  I fully appreciate just how useful turn by turn is as I got lost because I could watch the phone’s direction list and the road at the same time; kind of felt like being back in the late 90s with MapQuest.  For me, Mango can simply not come fast enough.

There are also a host of other little things that are driving me nuts.  For example, when I instructed the phone to sync with Facebook, it brought ALL of my Facebook friends into my People list, even those whose numbers I do not have.  Android was smart enough to match the people in my contact list with those friends on Facebook and not just bring everyone in.

The other thing is the lack of being able to set a specific notification sound for particular events.  When I was using Android I could set specific sounds so I would know the importance of the notification based on the sound.  Perhaps this is coming in a later release, but this combined with the fact that all of the notifications sound the same lead to me checking my phone frequently.

Overall, the phone is very good and I like where Microsoft is headed.  They still need a few tweaks, but that is to be expected.  I really think Mango will take WP7 to the next level and make it a legitimate alternative to iPhone and Android in the near future.