Archive for September 2010

Android GUI thread timer sample

I was looking for a simple Android timer to do updates on ticks in one of the views I’m playing with. The problem with spinning off another thread brings up two issues, one is that it takes more resources and the second one is that you will have to switch back over to the UI thread to update the screen. Then I came across a much better solution in the SDK documentation click here. I had to read it a couple of times and when I imported it into my app had to figure out some things a long the way. So for your benefit here is a cut down simple version.

In case you didn’t know see how easy it’s to use the built in Log class, the output will be visible in LogCat output. Also note the call Handler.removeCallbacks(mUpdateTimeTask); to free resources.

//
package us.kristjansson.test;
//
import us.kristjansson.test.R;
//
import android.app.Activity;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Window;
//

public class FxFireWorks extends Activity
{
        // Timer
        private Handler mHandler = new Handler();
        //
        private Runnable mUpdateTimeTask = new Runnable()
        {
           public void run()
           {
               // Do something
               Log.d( this.toString(), “Do something !!”);
               // timer
               mHandler.postDelayed(mUpdateTimeTask, ( 2 * 1000)) ;
           }
        };
       
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);

        // Hide the title bar
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.fireworks);
   
        // timer
        mHandler.removeCallbacks(mUpdateTimeTask);
        mHandler.postDelayed(mUpdateTimeTask, 100);
    }

    @Override
    public void onStop()
    {
        super.onStop();
       
        // timer
        mHandler.removeCallbacks(mUpdateTimeTask);
    }
   
}

Adobe Air development

I was talking to a friend about lack of a good interface for discovering NetFlix movies that do actually stream. The problem is that most of the movies are DVD distribution only. Further the streaming movies are sometimes streaming and sometimes not. It has something to do about when they are showing on TV. If your like me, you want to watch your movie at the end of the day when there is nothing on TV. In that case you want it streaming right there and then.

So I figure why not create a small app that will keep a list of the movies your wanting to see and it should be able to refresh and show you which ones are available for NetFlix streaming at any given time. Sounds easy enough, but there is a catch, I wanted it cross platform as my friend mostly uses a Mac. Hmm so I was thinking that’s easy enough just create simple C# program that will run smoothly on Mac under Mono. No that’s too easy, then it came to me, I have wanted to look at Adobe Air apps, this is a perfect opportunity. Let’s give it a try, as added bonus I wanted to do some dev on my Linux box. It should be fun to create this little app on the Linux and have it run on PC and Mac as well.

Well it turns out that Adobe only supports the FlashBuilder on Win and Mac, no Linux for you my friend. But we don’t give up that easily, I don’t want to run under Wine, turn to google and I find Fb4Linux. As it turns out after installing a bunch of libs and the FlashBuilder and some Sdks and such that I couldn’t get it to run under Linux ( I might try again later ). I’m probably not running the same versions of stuff as the author of the instructions, or maybe I just can’t follow instructions that well. Oh well, back to Windows, get the install from Adobe and it installs fine, then run the IDE, it plugs into Eclipse. Sure enough nothing to be found there, but wait a minute, not only do they ( claim to ) install it as plugin in your existing Eclipse, they also install a whole new instance of Eclipse. Sure enough when I run that new instance FB comes up and works as expected, you can start a new FB project etc.

Now with all the install trouble out of the way let’s give it a spin. File -> New Flex Project, the basics are setup for you by the wizard. Drag a couple of controls on the panel, goto properties and create click event for the button, there you have it “Hello World” Then click export, go through the wizard and an .air install file has been created. That’s pretty nice considering that I didn’t read any quick starts tutorials. But wait a minute, I click the air file to run it on my desktop and get some error indicating corrupted Air install file, contact the provider for a new file etc. Google search to the rescue and after un-installing and re-installing Air, nothing had changed. Then I uncheck the option of having a Timestamp in the digital signature of the .air file and that did the trick, now I can run and install, uhh.

Things seem to be looking up, time to code this puppy….. when I get to it, not sure if I’m going to pursue that or not, might be a follow up post. Notice all the javascript, might be too web-ish for my taste.

Here is Hello World in code

<?xml version=“1.0” encoding=“utf-8”?>
<s:WindowedApplication xmlns:fx=“http://ns.adobe.com/mxml/2009”
                                           xmlns:s=“library://ns.adobe.com/flex/spark”
                                           xmlns:mx=“library://ns.adobe.com/flex/mx”>

                <fx:Script>
                <![CDATA[
                        import mx.events.FlexEvent;
                       
                        protected function button1_clickHandler(event:MouseEvent):void
                        {
                                txSome.text = “Hello World !”;
                        }
                ]]>
        </fx:Script>

        <fx:Declarations>
                <!– Place non-visual elements (e.g., services, value objects) here –>
        </fx:Declarations>
        <s:Button x=“37” y=“10” label=“Button” click=“button1_clickHandler(event)”/>
        <s:TextArea x=“37” y=“52” id=“txSome”/>
</s:WindowedApplication>

And the app itself

Update
—–
I got Flex builder working later on the Linux box after some tinkering, that’s how the sample looks there.

Android code sample

I wanted to try some smart phone development. I started with Mac OsX in a VirtualBox got the Os installed on the virtual machine, but it wouldn’t boot for me after install. As I was fiddling with that on my Windows box to do iPhone development I thought this is way harder than it’s supposed to be.

Then I thought let’s see how this compares to doing Android development. Went to the Android SDK site and got the SDK which integrates with Eclipse very easily. The installs are just a few clicks of a button and your all set. Of course they have a Hello world sample that you will have running in Android emulator in matter of minutes. The install instructions show how to setup different devices under the emulator etc.

Now what about something more than just Hello world, the SDK comes bundled with all kind of samples, both controls and graphics along with more elaborate Google maps location based samples. It has plenty of stuff to get you going. The great thing is that the code is plain old Java so if you have done any Java or C# development you will feel right at home.

I wanted to do something basic before going into any real development. My idea is to create a simple calculator to calculate handicap score. I used to play pool and we would have a simple handicap system that needed to be referenced to calculate the race between two people that have been matched up.

When Android project is created in Eclipse it will create a bunch of files, resources, manifest, etc. and the main Activity class. The Hello world sample creates control dynamically in code but that can be hard to maintain when your project increases in size. The way to do it is to declare the controls in a XML resource file and then reference it in code. I didn’t see a editor to handle the controls visually but I’m sure there are some out there.

For a simple app the XML is found under res/layout/main.xml in my case it will look like this.

<?xml version=“1.0” encoding=“utf-8”?>
<RelativeLayout xmlns:android=“http://schemas.android.com/apk/res/android”
    android:layout_width=“fill_parent”
    android:layout_height=“fill_parent”>

    <TextView
        android:id=“@+id/lbPlayer1”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:text=“Handicap Player1:”/>

    <EditText
        android:id=“@+id/txPlayer1”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:background=“@android:drawable/editbox_background”
        android:layout_below=“@id/lbPlayer1”/>

    <TextView
        android:id=“@+id/lbPlayer2”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:layout_below=“@id/txPlayer1”
        android:text=“Handicap Player2:”/>

    <EditText
        android:id=“@+id/txPlayer2”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:background=“@android:drawable/editbox_background”
        android:layout_below=“@id/lbPlayer2”/>

    <Button
        android:id=“@+id/btOk”
        android:layout_width=“wrap_content”
        android:layout_height=“wrap_content”
        android:layout_below=“@id/txPlayer2”
        android:layout_alignParentRight=“false”
        android:layout_marginLeft=“10dip”
        android:text=“Calculate” />

    <TextView
        android:id=“@+id/lbMustWin1”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:layout_below=“@id/btOk”
        android:text=“Number of games Player1 must win:”/>

    <EditText
        android:id=“@+id/txMustWin1”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:background=“@android:drawable/editbox_background”
        android:layout_below=“@id/lbMustWin1”/>

    <TextView
        android:id=“@+id/lbMustWin2”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:layout_below=“@id/txMustWin1”
        android:text=“Number of games Player2 must win:”/>

    <EditText
        android:id=“@+id/txMustWin2”
        android:layout_width=“fill_parent”
        android:layout_height=“wrap_content”
        android:background=“@android:drawable/editbox_background”
        android:layout_below=“@id/lbMustWin2”/>

       
</RelativeLayout>

Things to notice are the id’s of the controls they need to be unique and how the layout is done for each control you specify where it should show up relative to other controls. That way the manager rendering your view can order them and it will look pretty good.

As I mentioned before the code is in java.

//
package hello.world;
//
import android.app.Activity;
import android.os.Bundle;
import android.text.Editable;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;

public class helloActivity extends Activity implements OnClickListener
{

        /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState)
    {
        // The usual
        super.onCreate(savedInstanceState);
        this.setContentView(R.layout.main);
       
        // Wire up click event
        Button button = (Button)findViewById(R.id.btOk);
        button.setOnClickListener(this);
    }
   
   
    // Implement the OnClickListener callback
    public void onClick(View v)
    {
        // Input from user
        String sPlayer1 = ((EditText)this.findViewById( R.id.txPlayer1)).getText().toString().trim();
        String sPlayer2 = ((EditText)this.findViewById( R.id.txPlayer2)).getText().toString().trim();
       
        // Turn into doubles
        double[] players = {0,0};
        players[0] = Double.parseDouble( sPlayer1 );
        players[1] = Double.parseDouble( sPlayer2 );
       
        // Calculate
        calculate( players );
       
        // Set the results
        ((EditText)this.findViewById( R.id.txMustWin1 )).setText( “” + (int)players[0] );
        ((EditText)this.findViewById( R.id.txMustWin2 )).setText( “” + (int)players[1] );
    }
     
    // Calculates handicap
    private static void calculate( double[] pdaPlayers )
    {
        // STRONGER is lower handicap
        // See who is better rated coming in,
        boolean bStrongerFirst =  pdaPlayers[0] < pdaPlayers[1];
        // Holds results
        double strong_race, weak_race;

        if( bStrongerFirst )
        {
            // What’s the race
            weak_race = Math.max(2, 6Math.floor( pdaPlayers[1] ));
            strong_race = weak_race + Math.round( pdaPlayers[1] – pdaPlayers[0] );
            // set the slots before returning
            pdaPlayers[0] = strong_race;
            pdaPlayers[1] = weak_race;
        }
        else
        {
            // What’s the race
            weak_race = Math.max(2, 6Math.floor( pdaPlayers[0] ));
            strong_race = weak_race + Math.round( pdaPlayers[0] – pdaPlayers[1] );
            //  Set the slots before returning
            pdaPlayers[0] = weak_race;
            pdaPlayers[1] = strong_race;
        }
    }

}  // EOC
 

The onCreate function is the main function of the activity, to get button click event it will be setup there. The rest is straight forward and activated when the user clicks the button. The controls are addressed by R.id.xxxx which is the resource id’s given to each control in the layout XML. The R mapping is created when the project is compiled. For this simple sample, the user input is retrieved and used to calculate handicap which is then presented back to the user in controls below.

The app running in Android emulator
androidhandicap1

Update
—–
I just didn’t find the visual editor, it’s there in Eclipse it shows as tab when you open up the xml file. It’s very primitive one might be better off to use DroidDraw