<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Hari&apos;s Blog</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/" />
    <link rel="self" type="application/atom+xml" href="http://www.lacherstorfer.at/haris_blog/atom.xml" />
    <id>tag:www.lacherstorfer.at,2008-03-04:/haris_blog//1</id>
    <updated>2012-02-23T08:28:44Z</updated>
    
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Open Source 4.1</generator>

<entry>
    <title>Another JS1K Submission</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2012/02/another-js1k-submission.html" />
    <id>tag:www.lacherstorfer.at,2012:/haris_blog//1.14</id>

    <published>2012-02-23T08:20:45Z</published>
    <updated>2012-02-23T08:28:44Z</updated>

    <summary>Long time no see ;-) Just wanted to let you know that I submittet a (very) little Javascript animation to the JS1K competition. The motto of the current competition is &quot;Love&quot;. So I decided to do an EKG style heartbeat...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><img alt="heartbeat.jpg" src="http://www.lacherstorfer.at/haris_blog/2012/02/23/heartbeat.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" height="114" width="142" /></span>Long time no see ;-) Just wanted to let you know that I submittet a (very) little Javascript animation to the <a href="http://www.js1k.com/">JS1K</a>
 competition. The motto of the current competition is "Love". So I 
decided to do an EKG style heartbeat animation (440 Bytes). It runs with IE9, FF10, Chrome 17 and Safari 5. You can find
 it here: <a href="http://js1k.com/2012-love/demo/1173">http://js1k.com/2012-love/demo/1173</a>. ]]>
        
    </content>
</entry>

<entry>
    <title>Javascript Demo (Game) - less than 1024 chars of code</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2010/09/javascript-demo-game-less-than.html" />
    <id>tag:www.lacherstorfer.at,2010:/haris_blog//1.13</id>

    <published>2010-09-06T11:27:05Z</published>
    <updated>2010-09-06T11:30:50Z</updated>

    <summary>Have contributed a little minesweeper game, have a look at: http://js1k.com/demo/512...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="javascriptjs1kminesweeperdemo" label="javascript js1k minesweeper demo" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[Have contributed a little minesweeper game, have a look at: <a href="http://js1k.com/demo/512">http://js1k.com/demo/512</a> ]]>
        
    </content>
</entry>

<entry>
    <title>Android How-Tos and Samples updated to new SDK (1.0 R2)</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2009/01/android-howtos-and-samples-upd.html" />
    <id>tag:www.lacherstorfer.at,2009:/haris_blog//1.12</id>

    <published>2009-01-09T21:18:58Z</published>
    <updated>2009-01-09T21:20:23Z</updated>

    <summary>I&apos;ve updated the code snippets of this blog to the newest SDK of Android (1.0 R2)....</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[I've updated the code snippets of this blog to the newest SDK of Android (1.0 R2).<br />]]>
        
    </content>
</entry>

<entry>
    <title>TrackBacks for this BLOG deactivated</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/08/trackbacks-for-this-blog-deact.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.11</id>

    <published>2008-08-05T15:52:24Z</published>
    <updated>2008-08-05T15:56:49Z</updated>

    <summary>Due to spamming attempts I decided to deactivate the trackbacks for this log!...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        Due to spamming attempts I decided to deactivate the trackbacks for this log! 
        
    </content>
</entry>

<entry>
    <title>Programming Concepts of Android Explained</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/07/programming-concepts-of-androi.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.10</id>

    <published>2008-07-10T18:12:56Z</published>
    <updated>2008-07-10T18:16:43Z</updated>

    <summary>Today I stumbled accross a little paper which explains some programming concepts of Android. It has been written by D. Guntz and J. Pleumann who were involved in the creation of core libraries of Android. So have a look at...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="androiddevelopment" label="Android Development" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[Today I stumbled accross a little paper which explains some programming concepts of Android. It has been written by D. Guntz and J. Pleumann who were involved in the creation of core libraries of Android. So have a look at <a href="http://www.gruntz.ch/papers/AndroidLogBook/index.html">their site</a> for details (paper + full source and binary).<br />]]>
        
    </content>
</entry>

<entry>
    <title>Android How-To: See also ...</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/android-howto-see-also.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.9</id>

    <published>2008-03-21T07:58:06Z</published>
    <updated>2008-03-21T08:09:05Z</updated>

    <summary>Here are some resources where you can also find How-Tos as well as other interesting Android related stuff:anddev.org (How-Tos, Tutorials, Android Apps, Discussions, FAQ, ...)Android Discussion Groups (official discussion group site from Google)Common Tasks and How To Do Them in...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="androiddiscussiongroups" label="Android Discussion Groups" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[Here are some resources where you can also find How-Tos as well as other interesting Android related stuff:<br /><br /><ul><li><a href="http://www.anddev.org/">anddev.org</a> (How-Tos, Tutorials, Android Apps, Discussions, FAQ, ...)</li><li><a href="http://code.google.com/android/groups.html">Android Discussion Groups</a> (official discussion group site from Google)</li><li><a href="http://code.google.com/android/kb/commontasks.html">Common Tasks and How To Do Them in Android</a> (Android online Documentation)</li><li><a aiotarget="false" aiotitle="The Android Log (Unofficial Log about Android)" href="http://theandroidlog.com/">The Android Log</a> (Unofficial Log about Android, couple of Android related Links)</li><li><a href="http://www.androidboards.com/">Android Boards</a> (posts Android news, and has other stuff) <br /></li></ul><div><br /></div>]]>
        
    </content>
</entry>

<entry>
    <title>Exploring jQuery </title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/exploring-jquery.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.8</id>

    <published>2008-03-18T22:25:21Z</published>
    <updated>2009-01-09T16:50:06Z</updated>

    <summary> jQuery is well known to the &quot;Ajax-Community&quot;. To get familiar with this Javascript library and tools, I implemented the little game &quot;Trap&quot; (a minesweeper clone) using jQuery features. Findings: Maybe I need further experience, but for now jQuery reminds...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="ajaxjquery" label="Ajax jQuery" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[ <a href="http://www.jquery.com">jQuery</a> is well known to the "Ajax-Community". To get familiar with this Javascript library and tools, I implemented the little game "Trap" (a minesweeper clone) using jQuery features.
<br/>
<br/>
Findings: Maybe I need further experience, but for now jQuery reminds me of ancient times in which some self-styled programming gurus wrote single lines of code in C that nobody else could read....
<br/>
<br/>
Anyway: <a href="/trap-js/trap.html" target="_blank">here</a> is the result of my implementation and exploration efforts, feel free to play, copy, re-use and comment.
<br/>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="/trap-js/trap.html" target="_blank"><img alt="trap.jpg" src="http://www.lacherstorfer.at/haris_blog/trap.jpg" width="270" height="416" class="mt-image-center" style="text-align: center; display: block; margin: 0 auto 20px;" /></a></span>]]>
        
    </content>
</entry>

<entry>
    <title>Android How-To: Create Spinners, ListViews and Context Menues programmatically</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/android-howto-create-spinners.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.7</id>

    <published>2008-03-18T22:04:38Z</published>
    <updated>2009-01-07T23:39:58Z</updated>

    <summary>[NOTE] Updated on 2009-01-17: Adopted Samples to final release of Android SDK (1.0 R2) An Android user interface is created by specifying a layout XML usually, but sometimes you need to create your interfaces or parts of it &quot;on-the-fly&quot; in...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="androiddevelopment" label="Android Development" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[<div style="color:red">[NOTE] Updated on 2009-01-17: Adopted Samples to final release of Android SDK (1.0 R2)</div>
<br/>
An Android user interface is created by specifying a layout XML usually, but sometimes you need to create your interfaces or parts of it "on-the-fly" in your programm code. This is not very easy sometimes because of the lack of documentation. The following code snippets show you how I could create a Spinner and a ListView widget programmatically:
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
...
public class Sample extends Activity
  ...
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    ...
    <div style="color:#00aa00;">    //Creating a spinner</div>
    Spinner spinner = new Spinner(this);
    ArrayAdapter<String> spinnerArrayAdapter = new ArrayAdapter<String>(this,
        android.R.layout.simple_spinner_dropdown_item,
            new String[] { "Apple", "Peach", "Banana" });
    spinner.setAdapter(spinnerArrayAdapter);

    <div style="color:#00aa00;">    //Add spinner to this activity's view (a LinearLayout)</div>
    mainLayout.addView(spinner, new LinearLayout.LayoutParams(
        LinearLayout.LayoutParams.WRAP_CONTENT,
        LinearLayout.LayoutParams.WRAP_CONTENT));
    ...
  }
}
</pre>

<pre style="color:blue;background-color:#eeeeee">
...
public class Sample extends Activity
  ...
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    ...
    <div style="color:#00aa00;">    //Creating a ListView with Context Menu</div>
    ListView listView = new ListView(this);
    ArrayAdapter<String> listViewArrayAdapter =
        new ArrayAdapter<String>(this,
           android.R.layout.simple_list_item_1, new String[] {
            "Apple", "Peach","Banane" });
    listView.setAdapter(listViewArrayAdapter);
    listView.setFocusableInTouchMode(true);
    listView.setOnFocusChangeListener(
        new View.OnFocusChangeListener() {
      @Override
      public void onFocusChange(View arg0, boolean arg1) {
        Log.i("SampleApp", "onFocusChanged() - view=" + arg0);
      }
    });
    listView.setOnItemClickListener(
        new AdapterView.OnItemClickListener() {
      @Override
      public void onItemClick(AdapterView adapterView, View view,
          int arg2, long arg3) {
        int selectedPosition = adapterView.getSelectedItemPosition();
        Log.i("SampleApp", "Click on position"+selectedPosition);
      }
    });
    listView
        .setOnCreateContextMenuListener(
            new View.OnCreateContextMenuListener() {

          public void onCreateContextMenu(ContextMenu menu, View view,
              ContextMenu.ContextMenuInfo menuInfo) {
            AdapterContextMenuInfo mi =
                (AdapterContextMenuInfo) menuInfo;
            menu.add(0, 0, 0, "Context-Menu-Entry");
          }

    });
    ...
  }
}
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Android How-To: Invoke a phone call Activity</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/android-howto-invoke-a-phone-c.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.6</id>

    <published>2008-03-18T21:56:33Z</published>
    <updated>2008-03-18T22:00:11Z</updated>

    <summary>Here&apos;s the code to invoke a phone call for a given number: try { Intent intent = new Intent(Intent.CALL_ACTION); intent.setData(Uri.parse(&quot;tel:+436641234567&quot;)); startActivity(intent); } catch (Exception e) { Log.e(&quot;SampleApp&quot;, &quot;Failed to invoke call&quot;, e); }...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="androiddevelopment" label="Android Development" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[Here's the code to invoke a phone call for a given number:
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
try {
   Intent intent = new Intent(Intent.CALL_ACTION);
   intent.setData(Uri.parse("tel:+436641234567"));
   startActivity(intent);
} catch (Exception e) {
   Log.e("SampleApp", "Failed to invoke call", e);
}
</pre>]]>
        
    </content>
</entry>

<entry>
    <title>Android How-To: Create a new Contact</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/android-howto-create-a-new-con.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.5</id>

    <published>2008-03-18T21:30:55Z</published>
    <updated>2009-03-11T19:40:38Z</updated>

    <summary>[NOTE] Updated on 2009-03-11: Adopted sample to release of Android SDK (1.1 R1) It took me some time to figure out how contacts are created and stored in Android. There were a couple of postings (see Android Google Groups) I...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[<div style="color:red">[NOTE] Updated on 2009-03-11: Adopted sample to release of Android SDK (1.1 R1)</div>
<br/>
It took me some time to figure out how contacts are created and stored in Android. There were a couple of postings (see <a href="http://code.google.com/android/groups.html">Android Google Groups</a>) I had to consult, but finally I did it :-). In case you experience the same difficulties here is the full picture (source code) that worked for me:
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee;">

ContentValues personValues = new ContentValues();
personValues.put(Contacts.People.NAME, "John F. Doe");
<span style="color:#00aa00">/* STARRED 0 = Contacts, 1 = Favorites */</span>
personValues.put(Contacts.People.STARRED, 1);


<div style="color:#00aa00">// worked in SDK 1.0 R2 but not in SDK 1.1 R1 anymore
//Uri newPersonUri = getContentResolver()
//	.insert(Contacts.People.CONTENT_URI, personValues);</div>

Uri newPersonUri = Contacts.People
  .createPersonInMyContactsGroup(getContentResolver(), personValues);

if (newPersonUri != null) {

<div style="color:#00aa00">// add company (organisation)</div>
ContentValues organisationValues = new ContentValues();
Uri orgUri = Uri.withAppendedPath(newPersonUri,
		Contacts.Organizations.CONTENT_DIRECTORY);
organisationValues.put(Contacts.Organizations.COMPANY,
		"MyCompany Inc.");
organisationValues.put(Contacts.Organizations.TYPE,
		Contacts.Organizations.TYPE_WORK);
Uri orgUpdate = getContentResolver()
		.insert(orgUri, organisationValues);
if (orgUpdate == null) {
	throw new Exception("Failed to insert organisation");
}

<div style="color:#00aa00">// add mobile phone number</div>
ContentValues mobileValues = new ContentValues();
Uri mobileUri = Uri.withAppendedPath(newPersonUri,
		Contacts.People.Phones.CONTENT_DIRECTORY);
mobileValues.put(Contacts.Phones.NUMBER,
		"(660) 111-1111");
mobileValues.put(Contacts.Phones.TYPE,
		Contacts.Phones.TYPE_MOBILE);
Uri phoneUpdate = getContentResolver()
		.insert(mobileUri, mobileValues);
if (phoneUpdate == null) {
	throw new Exception(
			"Failed to insert mobile phone number");
}

<div style="color:#00aa00">// add fax number</div>
ContentValues faxValues = new ContentValues();
Uri faxUri = Uri.withAppendedPath(newPersonUri,
		Contacts.People.Phones
                        .CONTENT_DIRECTORY);
faxValues.put(Contacts.Phones.NUMBER,
		"(408) 111-1111-1");
faxValues.put(Contacts.Phones.TYPE,
		Contacts.Phones.TYPE_FAX_WORK);
phoneUpdate = getContentResolver()
		.insert(faxUri, faxValues);
if (phoneUpdate == null) {
	throw new Exception(
			"Failed to insert work fax number");
}

<div style="color:#00aa00">// add email</div>
ContentValues emailValues = new ContentValues();
Uri emailUri = Uri
		.withAppendedPath(
				newPersonUri,
				Contacts.People.ContactMethods
                                       .CONTENT_DIRECTORY);
emailValues.put(Contacts.ContactMethods.KIND,
		Contacts.KIND_EMAIL);
emailValues.put(Contacts.ContactMethods.TYPE,
		Contacts.ContactMethods.TYPE_HOME);
emailValues.put(Contacts.ContactMethods.DATA,
		"john.f.doe@exit.com");
Uri emailUpdate = getContentResolver()
		.insert(emailUri, emailValues);
if (emailUpdate == null) {
	throw new Exception("Failed to insert email");
}

<div style="color:#00aa00">// add address</div>
ContentValues addressValues = new ContentValues();
Uri addressUri = Uri
		.withAppendedPath(
				newPersonUri,
				Contacts.People.ContactMethods
                                         .CONTENT_DIRECTORY);
addressValues.put(Contacts.ContactMethods.KIND,
		Contacts.KIND_POSTAL);
addressValues.put(Contacts.ContactMethods.TYPE,
		Contacts.ContactMethods.TYPE_HOME);
addressValues.put(Contacts.ContactMethods.DATA,
		"Baker Street 14\n54123 New Hampshire");
Uri addressUpdate = getContentResolver().insert(addressUri,
				addressValues);
if (addressUpdate == null) {
	throw new Exception("Failed to insert address");
}

</pre>]]>
        
    </content>
</entry>

<entry>
    <title>J2ME vs. Android: Game Trap</title>
    <link rel="alternate" type="text/html" href="http://www.lacherstorfer.at/haris_blog/2008/03/j2me-vs-android-game-trap.html" />
    <id>tag:www.lacherstorfer.at,2008:/haris_blog//1.4</id>

    <published>2008-03-18T20:26:08Z</published>
    <updated>2009-01-09T21:18:46Z</updated>

    <summary>[Note] Updated: Adopted code to Android SDK 1.0 R2 To become familiar with mobile programming plattforms I&apos;ve implemented a little game (a minesweeper clone) in J2ME. After having finished this I ported this game to Android. While porting to Android...</summary>
    <author>
        <name>Harald Lacherstorfer</name>
        
    </author>
    
    <category term="j2meandroidmobilegame" label="j2me android mobile game" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://www.lacherstorfer.at/haris_blog/">
        <![CDATA[<div style="color:red">[Note] Updated: Adopted code to Android SDK 1.0 R2</div>
<br/>
To become familiar with mobile programming plattforms I've implemented a little game (a minesweeper clone) in J2ME. After having finished this I ported this game to Android.
<br/>
<br/>
<div style="width:100%;text-align:center">
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://www.lacherstorfer.at/haris_blog/trap-android.html" onclick="window.open('http://www.lacherstorfer.at/haris_blog/trap-android.html','popup','width=420,height=778,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lacherstorfer.at/haris_blog/trap-android.jpg" border="0" width="150"></a></span>
<span class="mt-enclosure mt-enclosure-image" style="display: inline;"><a href="http://www.lacherstorfer.at/haris_blog/trap-j2me.html" onclick="window.open('http://www.lacherstorfer.at/haris_blog/trap-j2me.html','popup','width=322,height=727,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://www.lacherstorfer.at/haris_blog/trap-j2me.jpg" border="0" width="150"></a></span>
</div>
<br/>
<br/>
While porting to Android I explored the following features:
<br />
<br />
<ul>
<li>Rendering images via View.onDraw()</li>
<li>Working with multiple Activities (Main Activity, Options Activity)</li>
<li>Passing data from one Activity to another<br /></li>
<li>Handling Activity states (freeze, restore)</li>
<li>Handling custom menues (onCreateOptionsMenu)</li>
<li>etc.</li>
</ul>
It turned out that - as expected ;-) - separating program logic is a good thing. I used the same classes for the game logic.
<br/>
<br/>
Disclaimer: Please note, that my intention was to explore some features of the plattforms. There is still room for improvement as I've not implemented a timer, a highscore table etc..
<br/>
Attached you can find the Eclipse (3.4) projects of both implementations:
<ul>
<li><span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://www.lacherstorfer.at/haris_blog/TrapAndroid.rar">TrapAndroid.rar</a></span></li>
<li><span class="mt-enclosure mt-enclosure-file" style="display: inline;"><a href="http://www.lacherstorfer.at/haris_blog/TrapJ2ME.rar">TrapJ2ME.rar</a></span></li>
</ul>

The following sources are extracts from the Android implementation:
<br />
<br /><u>TrapMain.java</u><br />
<br/>
<pre style="color:blue;background-color:#eeeeee;">
package at.lacherstorfer.trap.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class TrapMain extends Activity {

  private TrapView trapView;
  private static int EDIT_OPTIONS = 1;

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);

    setContentView(R.layout.trap_main_layout);
    trapView = (TrapView) findViewById(R.id.trap);

    if (icicle != null) {
      // We are being restored
      Bundle map = icicle.getBundle("trapView");
      if (map != null) {
        trapView.restoreState(map);
      }
    }

    trapView.doStart();

  }

  @Override
  protected void onSaveInstanceState(Bundle outState) {
    // store game state
    outState.putBundle("trapView", trapView.saveState());
  }

  @Override
  public boolean onCreateOptionsMenu(Menu menu) {
    super.onCreateOptionsMenu(menu);
    MenuItem menuItem = menu.add(0, 0, 0, "Start");
    menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {

		public boolean onMenuItemClick(MenuItem item) {
			 trapView.doStart();
			 return true;
		}
    	
    });
    
    menuItem = menu.add(0, 0, 0, "Options");
    menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {

		public boolean onMenuItemClick(MenuItem item) {
	        Intent optionsIntent = new Intent(TrapMain.this, TrapOptions.class);
	        Bundle extras = new Bundle();
	        extras.putInt("numberRows", trapView.getNumberRows());
	        extras.putInt("numberCols", trapView.getNumberCols());
	        extras.putInt("numberTraps", trapView.getNumberTraps());
	        optionsIntent.putExtras(extras);
	        startActivityForResult(optionsIntent, EDIT_OPTIONS);
            return true;
		}
	});
    return true;
  }
  
  @Override
  protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (resultCode == RESULT_OK) {
      trapView.doStart(data.getIntExtra("numberRows", 8),
          data.getIntExtra("numberCols", 8), data.getIntExtra("numberTraps", 8));
    }
  }

}
</pre>
<br/>
<br/>
<u>TrapView.java</u>
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
package at.lacherstorfer.trap.android;

import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import at.lacherstorfer.trap.shared.Cell;
import at.lacherstorfer.trap.shared.Field;

public class TrapView extends View {

	private Field field;

	private int numberRows = 8;
	private int numberCols = 8;
	private int numberTraps = 8;

	private int cursorX;
	private int cursorY;

	private Drawable cellClosedImage;
	private Drawable cell0Image;
	private Drawable cell1Image;
	private Drawable cell2Image;
	private Drawable cell3Image;
	private Drawable cell4Image;
	private Drawable cellBombImage;
	private Drawable cellExplodedImage;
	private Drawable cellFlaggedImage;
	private Drawable cursorImage;

	public TrapView(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		loadImages(context);
	}

	public TrapView(Context context, AttributeSet attrs) {
		super(context, attrs);
		loadImages(context);
	}

	public TrapView(Context context) {
		super(context);
		loadImages(context);
	}

	public void loadImages(Context context) {
		cellClosedImage = context.getResources().getDrawable(
				R.drawable.cellclosed);
		cell0Image = context.getResources().getDrawable(R.drawable.cell0);
		cell1Image = context.getResources().getDrawable(R.drawable.cell1);
		cell2Image = context.getResources().getDrawable(R.drawable.cell2);
		cell3Image = context.getResources().getDrawable(R.drawable.cell3);
		cell4Image = context.getResources().getDrawable(R.drawable.cell4);
		cellBombImage = context.getResources().getDrawable(R.drawable.cellbomb);
		cellExplodedImage = context.getResources().getDrawable(
				R.drawable.cellexploded);
		cellFlaggedImage = context.getResources().getDrawable(
				R.drawable.cellflagged);
		cursorImage = context.getResources().getDrawable(R.drawable.cursor);
		setFocusable(true);
	}

	public Bundle saveState() {
		Bundle map = new Bundle();
		map.putInt("numberRows", Integer.valueOf(numberRows));
		map.putInt("numberCols", Integer.valueOf(numberCols));
		map.putInt("numberTraps", Integer.valueOf(numberTraps));
		map.putInt("cursorX", Integer.valueOf(cursorX));
		map.putInt("cursorY", Integer.valueOf(cursorY));
		int[] fieldState = field.getState();
		for (int i = 0; i < fieldState.length; i++) {
			map.putInt("field-" + i, fieldState[i]);
		}
		return map;
	}

	public void restoreState(Bundle icicle) {
		numberRows = icicle.getInt("numberRows");
		numberCols = icicle.getInt("numberCols");
		numberTraps = icicle.getInt("numberTraps");
		cursorX = icicle.getInt("cursorX");
		cursorY = icicle.getInt("cursorY");
		int[] fieldState = new int[icicle.size() - 5];
		for (int i = 0; i < fieldState.length; i++) {
			fieldState[i] = icicle.getInt("field-" + i);
		}
		field = new Field(fieldState);
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		Log.i("TrapView", "pressed key=" + keyCode);
		boolean handled = false;
		if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
			cursorX -= cursorX > 0 ? 1 : 0;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
			cursorX += cursorX < numberCols - 1 ? 1 : 0;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
			cursorY -= cursorY > 0 ? 1 : 0;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
			cursorY += cursorY < numberRows - 1 ? 1 : 0;
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER
				|| keyCode == KeyEvent.KEYCODE_ENTER) {
			fire();
			handled = true;
		} else if (keyCode == KeyEvent.KEYCODE_SPACE) {
			flag();
			handled = true;
		}
		if (handled) {
			postInvalidate();
		}
		return handled;
	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		boolean handled = false;
		if (event.getAction() == MotionEvent.ACTION_DOWN) {
			cursorX = (int) (event.getX() / 15);
			cursorX = cursorX > numberCols ? numberCols - 1 : cursorX;
			cursorY = (int) (event.getY() / 15);
			cursorY = cursorY > numberRows ? numberRows - 1 : cursorY;
			handled = true;
		}
		postInvalidate();
		return handled;
	}

	private void fire() {
		if (field == null)
			return; // game not started yet
		int cellValue = field.fireAt(cursorY, cursorX);
		if (cellValue == Cell.TRAP) {
			field.reveal();
			Builder b = new AlertDialog.Builder(this.getContext());
			b.setTitle("Trap");
			b.setIcon(0);
			b.setMessage("Game Over");
			b.show();
		} else if (field.isSolved()) {
			Builder b = new AlertDialog.Builder(this.getContext());
			b.setTitle("Trap");
			b.setIcon(0);
			b.setMessage("Congratulation, You Win!");
			b.show();
		}
	}

	private void flag() {
		if (field == null)
			return; // game not started yet
		field.flagAt(cursorY, cursorX);
		if (field.isSolved()) {
			Builder b = new AlertDialog.Builder(this.getContext());
			b.setTitle("Trap");
			b.setIcon(0);
			b.setMessage("Congratulation, You Win!");
			b.show();
		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);

		if (field == null)
			return; // game not started yet

		// draw the field
		for (int row = 0; row < numberRows; row++) {
			for (int col = 0; col < numberCols; col++) {
				Cell cell = field.getCellAt(row, col);
				Drawable cellImage = getDrawable(cell);
				cellImage.setBounds(/* left */col * 15, /* top */row * 15, /* right */
				col * 15 + 15, /* bottom */row * 15 + 15);
				cellImage.draw(canvas);
			}
		}

		// draw the cursor
		cursorImage.setBounds(cursorX * 15, cursorY * 15, cursorX * 15 + 15,
				cursorY * 15 + 15);
		cursorImage.draw(canvas);
	}

	public void doStart(int numberRows, int numberCols, int numberTraps) {
		this.numberRows = numberRows;
		this.numberCols = numberCols;
		this.numberTraps = numberTraps;
		field = new Field(numberRows, numberCols, numberTraps);
		postInvalidate();
	}

	public void doStart() {
		if (field == null) {
			field = new Field(numberRows, numberCols, numberTraps);
		} else {
			field.restart();
		}
		postInvalidate();
	}

	private Drawable getDrawable(Cell cell) {
		if (cell.isOpen()) {
			switch (cell.getValue()) {
			case Cell.TRAP:
				return cellBombImage;
			case 0:
				return cell0Image;
			case 1:
				return cell1Image;
			case 2:
				return cell2Image;
			case 3:
				return cell3Image;
			case 4:
				return cell4Image;
			}
		} else if (cell.isClosed()) {
			return cellClosedImage;
		} else if (cell.isFlagged()) {
			return cellFlaggedImage;
		} else if (cell.isExploded()) {
			return cellExplodedImage;
		} else {
			throw new RuntimeException("Internal Error");
		}
		return null;
	}

	public int getNumberRows() {
		return numberRows;
	}

	public int getNumberCols() {
		return numberCols;
	}

	public int getNumberTraps() {
		return numberTraps;
	}

}
</pre>
<br/>
<br/>
<u>TrapOptions.java</u>
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
package at.lacherstorfer.trap.android;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.EditText;

public class TrapOptions extends Activity {
	
	private EditText etNumberCols;
	private EditText etNumberRows;
	private EditText etNumberTraps;
	
	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle icicle) {
		super.onCreate(icicle);
		setContentView(R.layout.trap_options_layout);
		etNumberRows = (EditText) findViewById(R.id.number_rows);
		etNumberCols = (EditText) findViewById(R.id.number_cols);
		etNumberTraps = (EditText) findViewById(R.id.number_traps);
		Bundle extras = getIntent().getExtras();
		etNumberRows.setText(""+extras.getInt("numberRows"));
		etNumberCols.setText(""+extras.getInt("numberCols"));
		etNumberTraps.setText(""+extras.getInt("numberTraps"));
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		super.onCreateOptionsMenu(menu);
		
	    MenuItem menuItem = menu.add(0, 0, 0, "Ok");
	    menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
			public boolean onMenuItemClick(MenuItem item) {
				int numberRows = Integer.parseInt(etNumberRows.getText().toString());
				int numberCols = Integer.parseInt(etNumberCols.getText().toString());
				int numberTraps = Integer.parseInt(etNumberTraps.getText().toString());
				Bundle b = new Bundle();
				b.putInt("numberRows", numberRows);
				b.putInt("numberCols", numberCols);
				b.putInt("numberTraps", numberTraps);
				Intent resultIntent = new Intent();
				resultIntent.putExtras(b);
				setResult(RESULT_OK, resultIntent);
				finish();
				return true;
			}
	    });
		
	    menuItem = menu.add(0, 0, 0, "Cancel");
	    menuItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
			public boolean onMenuItemClick(MenuItem item) {
				setResult(RESULT_CANCELED);
				finish();
				return true;
			}
	    });
		return true;
	}

}
</pre>
<br/>
<br/>
<u>trap_main_layout.xml</u>
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
&lt;?xml version="1.0" encoding="utf-8"?&gt;

&lt;FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;

    &lt;at.lacherstorfer.trap.android.TrapView
      android:id="@+id/trap"
      android:layout_width="fill_parent"
      android:layout_height="fill_parent" /&gt;
      
&lt;/FrameLayout&gt;
</pre>
<br/>
<br/>
<u>trap_options_layout.xml</u>
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"&gt;
    
    &lt;TableRow&gt;
    	&lt;TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:text="Number Columns"/&gt;
    	&lt;EditText android:id="@+id/number_cols"
    			  android:layout_width="fill_parent" 
            	  android:layout_height="wrap_content"
            	  android:maxLength="2" /&gt;
    &lt;/TableRow&gt;
    &lt;TableRow&gt;
    	&lt;TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:text="Number Rows"/&gt;
    	&lt;EditText android:id="@+id/number_rows"
    			  android:layout_width="wrap_content" 
            	  android:layout_height="wrap_content"
            	  android:maxLength="2" /&gt;
    &lt;/TableRow&gt;
    &lt;TableRow&gt;
    	&lt;TextView android:layout_width="wrap_content" 
              android:layout_height="wrap_content" 
              android:text="Number Traps"/&gt;
    	&lt;EditText android:id="@+id/number_traps"
    			  android:layout_width="fill_parent" 
            	  android:layout_height="wrap_content"
            	  android:maxLength="2"/&gt;
    &lt;/TableRow&gt;  
&lt;/TableLayout&gt;
</pre>
<br/>
<br/>
<u>AndroidManifest.xml</u>
<br/>
<br/>
<pre style="color:blue;background-color:#eeeeee">
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="at.lacherstorfer.trap.android"&gt;
    &lt;application android:icon="@drawable/icon" android:label="@string/app_name"&gt;
        &lt;activity android:name="TrapMain" android:label="@string/app_name"&gt;
            &lt;intent-filter&gt;
                &lt;action android:value="android.intent.action.MAIN"
                  android:name="android.intent.action.MAIN"/&gt;
                &lt;category android:value="android.intent.category.LAUNCHER"
                  android:name="android.intent.category.LAUNCHER"/&gt;
            &lt;/intent-filter&gt;
        &lt;/activity&gt;
        &lt;activity android:name="TrapOptions"
          android:label="@string/app_name"/&gt;
    &lt;/application&gt;
&lt;/manifest&gt; 
</pre>]]>
        
    </content>
</entry>

</feed>

