Monday, July 25, 2011

Implicit Intent For Android Developer


We have seen in Part 2 how to use Explicit Intents to invoke activities through a very simple example. Now, we will move on to a more interesting concept of Implicit Intents and Intent Filters. 

This requires a little of theoretical understanding before we move on to an example. 

As described earlier, an implicit intent does not name a target component that should act upon the intent. I 
also said that the android platform resolves as to which component is best suited to respond to an Implicit Intent. How does this happen?

Basically, an Intent object has the following information (among other things like Component name, extras and flags) which is of interest for implicit intents:
  • Action
  • Category
  • Data
So, the android platform compares these 3 (action, category and data) to something called "Intent Filters" that are declared by probable target components who are willing to accept Implicit Intent calls.
i.e. Intent Filters are the way of any component to advertise its own capabilities to the Android system. This is done declaratively in the AndroidManifest.xml file.

So here are some important points to remember:
  1. Implicit Intents do not specify a target component
  2. Components willing to receive implicit intents have to declare their ability to handle a specific intent by declaring intent filters
  3. A component can declare any number of Intent Filters
  4. There can be more than one component that declares the same Intent Filters and hence can respond to the same implicit intent. In that case the user is presented both the component options and he can choose which one he wants to continue with
  5. You can set priorities for the intent filters to ensure the order of responses.
There are 3 tests conducted in order to match an intent with intent filters:
  1. Action Test
  2. Category Test
  3. Data Test
For more details about them, you may visit the Android developer documentation here.

Finally we shall look at declaring an implicit intent in one activity which will invoke one of the native activities of the platform by matching the intent filters declared by the same.

The complete code for a very simple implicit intent example that has been described in this article is available for download here.

The InvokeImplicitIntent Activity creates an implicit intent object "contacts". This intent object's component is not set. However, the action is set to "android.content.intent.ACTION_VIEW" and the data's URI is set to "People.CONTENT_URI". 

Such an intent matches with the intent filter declared by the view contacts native activity.
So, when you run this application, it displays the native UI for viewing the existing contacts on the phone!

Here is the relevant piece of code for the same:
           Button viewContacts = (Button)findViewById(R.id.ViewContacts);
        
            viewContacts.setOnClickListener(new OnClickListener() {
            
             public void onClick(View v) {
              Intent contacts = new Intent();
              contacts.setAction(android.content.Intent.ACTION_VIEW);
              contacts.setData(People.CONTENT_URI);
              startActivity(contacts);
             }
            });


In this manner many of the native applications can be seamlessly invoked as one of the activities in our applications through implicit intents.

Explicit Intent For Android

Having introduced you to the basic anatomy of an android application in the Part 1 of the series, I would like to show you an example where communication between 2 activities happens through an intent.



However, just one more detail to be introduced as promised and that is -
There are 2 types of intents that Android understands.
1. Explicit Intent
2. Implicit Intent


In an Explicit intent, you actually specify the activity that is required to respond to the intent. In other words, you explicitly designate the target component. This is typically used for application internal messages.


In an Implicit intent (the main power of the android design), you just declare an intent and leave it to the platform to find an activity that can respond to the intent. Here, you do not declare the target component and hence is typically used for activating components of other applications seamlessly
Note: Here for simplicity sake I tell an activity responds to an intent, it could as well be other types of components.
Now I will jump into the example which you can download from here:


This example has 2 activities:
1. InvokingActivity
2. InvokedActivity
The InvokingActivity has a button "Invoke Next Activity" which when clicked explicitly calls the "InvokedActivity" class.
The relevant part of the code is here:

        Button invokingButton = (Button)findViewById(R.id.invokebutton);
        invokingButton.setOnClickListener(new OnClickListener() {
        

        
public void onClick(View v) {
        
Intent explicitIntent = new Intent(InvokingActivity.this,InvokedActivity.class);
         startActivity(explicitIntent);
        
}
        });

As explained in part 1 of the series, this is very much like an API call with compile time binding.
NOTE: The layout for InvokingActivity is defined in main.xml and for InvokedActivity in InvokedActivity.xml. The downloadable example can be opened in Eclipse Ganymede as an android project and can be executed.
In the next part of the series, we will see how to work with implicit intents which also needs us to understand intent-filters

The Uniqueness of Android – The Mobile Platform from Google

There is a huge furore and expectation in the mobile industry, after the announcement of “Android”, the mobile platform (consisting of an operating system, middleware and key applications), by Google last November. Its ripple effect in the developer community and the services industry is also pretty palpable.

In Google’s typical way, the 10 million dollar awards towards the best android applications had added the required momentum to bring the large developer community into its fold, and at the same time, harvest collective intelligence.

What is so unique about Android?
We have had many mobile OS like the Symbian, Windows Mobile OS, Mac OS X and Linux based Palm Nova, ALP etc, already flooding the market and fragmenting it.
So, why is another OS required?
If we are talking about something very radical, iPhone did it all. It took the market by storm with its mind-boggling features.
With all these in the market, isn’t android late? Still, why the interest?

Market Buy-in


Google has first of all roped in most of the players in the mobile market be it mobile operators, handset manufacturers, mobile application providers or software companies and even some commercialization companies.

The only significant players who are missing from the list for obvious reasons are:
1. Microsoft
2. Apple
3. Nokia
4. Palm
Two Major National US carriers missing are AT&T and Verizon.

Google is planning to keep it open source, the most happening way to get the acceptance in the market

Technically,
1. It is the only OS so far that allows integration / use of the basic phone features with any externally developed mobile application,
2. It is designed to simplify the reuse of components. Any application can publish its capabilities and any other application can use it. Taking the cue from the enterprise world on service oriented architecture, android has built it into its fundamental architecture
3. It is built on the open Linux Kernel
4. It will be open source
5. Mashup-ready: Embed browser and map views directly in your applications

To the End User:
1. Choice will be unlimited. The end user is not tied to using the basic features of the phone as provided by the handset manufacturer. He could use his own choice from any third party provider as the default feature of the phone
2. The ability to seamlessly integrate core and new applications will produce a new generation of unheard-of applications that are going to change the way the mobile would be used. Like for example, the ability to alert friends who are in the vicinity about your presence or the ability to be notified of all the shops that have a product you are looking for, as you enter a mall.
3. The open platform should provide more cheaper and innovative mobile devices and services
4. Application life cycle and automatic process management frees the end user from worrying about what applications are active
5. Location based services and notifications
6. Standard 2d and 3d graphics with optional acceleration
7. High quality audio/video support including H.264 (AVC).
8. Low power operation

Android - Technically, What Is It?

Android - Technically what is it?
    (an overivew of what is Android and its uniqueness is discussed in another post below)
    1. It is an operating system for mobile
    2. Interestingly, it is not yet another OS, but component based
      OS
    3. It has an integrated Java Virtual Machine
    4. System interfaces are exposed only through Java libraries
    5. It is based on the Linux Kernel
    6. An Android SDK is provided to let developers build applications on top of the OS but not extend the OS itself
    7. The SDK includes
      • Android packages
      • sample files
      • Documentation
      • A Simulator
The offical site of Android broadly classfies the technical parts of the OS as
consisting of
  1. Linux Kernel
  2. Android Runtime
  3. Libraries
  4. Application Framework
over which the core applications run as well as the applications developed by anyone using this framework

iPad stays top tablet: Faces growing Android challenge as Amazon circles

Apple’s iPad continues to dominate the tablet market, with global shipments up to 9.3m units according to the latest figures, though its percentage marketshare has declined by over 33-percent thanks to increasing competition from consumer-centric rivals. 61.3-percent of tablets sold worldwide run iOS, analysts Strategy Analytics calculate, with Android taking the lion’s share of what remains, at 30.1-percent.




Android’s rise from Q2 2010 is significant, with the Google platform on just 2.9-percent of the tablets a year ago and seeing shipping numbers of just 100,000 units. The analysts now believe that 4.6m Android tablets were sold in Q2, not least because of the dedicated tablet version of the OS, 3.x Honeycomb, which was designed specifically to suit larger-screen devices.




Despite generally negative reviews, Windows 7 holds third place, with a reported 4.6-percent of the marketshare. That puts it ahead of QNX, the platform RIM has used for the BlackBerry PlayBook, which lags in fourth place with 3.3-percent. Strategy Analytics blame the absence of key apps like a native email client on the PlayBook for its placement
Since the figures detail Q2 2011 – April through June inclusive – newer slates like the HP TouchPad don’t get a look in. Looking forward, the Android tablet segment is open to a single, dominant vendor, and there are suggestions that it could well be Amazon. “If Amazon decides to enter the Android tablet category later this year, that will bring fresh excitement and buzz to the Android community” Neil Mawston, Director at Strategy Analytics suggests, ”but Amazon will need to deliver a truly standout offering if it really wants to make headway against the popular iPad.”


Wednesday, July 20, 2011

Samsung launches new Galaxy Tab to rival iPad

Samsung Electronics Co launched a thinner and lighter version of its Galaxy tablet in its lucrative home market, trying to halt the runaway success of Apple Inc's iPad.

The Galaxy Tab 10.1 is an upgraded version of the 7-inch Tab introduced in October.

Blockbuster iPad sales announced by Apple Tuesday underscore the challenge for the South Korean company.

Apple sold 14 million iPads in the first half of the year, compared with analysts' sales estimates of about 7.5 million units for the Galaxy Tab over 2011.

"As our smartphone business grew very fast within a very short period of time, I believe it's just a matter of time for our tablet business to improve," J.K. Shin, head of Samsung's mobile division, told reporters.

Samsung is Apple's nearest rival in the booming mobile device industry as it leverages its cost competitiveness and access to chips and core tablet components.

It has sharply narrowed the gap with Apple in the smartphone market, but remains a distant second in the tablet market, which research firm Gartner forecasts will surge to 108 million devices next year from an estimated 70 million in 2011.

"Apple's quarterly results showed again it's indeed the strongest rival to beat. Samsung will have a tough second half due to growing competition from Apple as it is set to introduce a new iPhone," said James Song, an analyst at Daewoo Securities. 





Blockbuster sales of the iPhone and iPad again helped Apple crush Wall Street's expectations for its third-quarter results. Apple said Tuesday that concern over iPad 2 supply constraints had eased and demand was still outstripping supply in some markets.

The sale of the Tab in Korea is Samsung's fifth launch after its U.S. debut a month ago and its sales kickoff in Indonesia, where the company says it commands a 65 percent market share. It has also launched the device in Italy and Sweden.

Pricing for the new product, slightly thinner and lighter than the iPad 2, starts from $500 in the U.S. market, the same price as the iPad 2.

Samsung faces the challenge of moving beyond being a hardware company, clever at copying ideas, to becoming more creative and better adept at software at a time when consumer gadgets are getting smarter.

Second-quarter profit at Samsung, the world's largest maker of memory chips and televisions, fell by a quarter as weak earnings at its flat screen unit dragged, overshadowing robust sales from its mobile division.

Samsung reiterated Wednesday it aimed to boost tablet sales by more than five fold this year. It didn't provide specific numbers but analysts expect the company to have sold about 1.5 million units last year.



Tuesday, July 19, 2011

Custom ListView For Android

Now, we shall look at creating a custom list view – a custom layout, a custom row layout and how we bind the custom data holder to these layouts. (please see the earlier article on simple list view for the fundamentals of list view).

So, here again, we start with extending ListActivity.

public class MyCustomListView extends ListActivity {

Now let us create the custom list view in an xml file – custom_list_view.xml. This will be set using the setContentView() in onCreate() method:
<ListView android:id="@id/android:list"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000fff"
android:layout_weight="2"
android:drawSelectorOnTop="false">
</ListView>
<TextView android:id="@id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#FFff00"
android:text="No data"
/>
Note that it must contain a ListView object with android:id="@id/android:list"

I have also declared a TextView which should be whon when the list if empty by declaring with android:id="@id/android:empty"

Now we will declare how each row in this ListView should be displayed by creating a new xml file – custom_row_view.xml

I plan to have 3 items one below the other in each row. So, here is the declaration for the same:
<TextView android:id="@+id/text1"
android:textSize="16sp"
android:textStyle="bold"
android:textColor="#FFFF00"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
<TextView android:id="@+id/text2"
android:textSize="12sp"
android:textStyle="bold"
android:layout_width="wrap_content"
android:layout_height="fill_parent"/>
<TextView android:id="@+id/text3"
android:typeface="sans"
android:textSize="14sp"
android:textStyle="italic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
So, now, how do I tie all of this together? The MyCustomListView class, the listview layout and the row layout. Just like in the earlier example, we need a ListAdpater object. Here I plan to use a SimpleAdpater provided by the SDK.

An adapter expects the context, the layout and the handle to the data that needs to be displayed. So, let us create a list of data in an ArrayList of HashMaps. This way, the HashMap can store any amount of data.

static final ArrayList<HashMap<String,String>> list =

new ArrayList<HashMap<String,String>>();
This is just a declaration of the list object. We need to populate it with data. Our custom row layout expects each row to have 3 prices of data…

This list is populated in a method as shown below with the 3 keys as ‘pen’, ‘price’ and ‘color’:

private void populateList() {
HashMap<String,String> temp = new HashMap<String,String>();
temp.put("pen","MONT Blanc");
temp.put("price", "200.00$");
temp.put("color", "Silver, Grey, Black");
list.add(temp);
HashMap<String,String> temp1 = new HashMap<String,String>();
temp1.put("pen","Gucci");
temp1.put("price", "300.00$");
temp1.put("color", "Gold, Red");
list.add(temp1);
HashMap<String,String> temp2 = new HashMap<String,String>();
temp2.put("pen","Parker");
temp2.put("price", "400.00$");
temp2.put("color", "Gold, Blue");
list.add(temp2);
HashMap<String,String> temp3 = new HashMap<String,String>();
temp3.put("pen","Sailor");
temp3.put("price", "500.00$");
temp3.put("color", "Silver");
list.add(temp3);
HashMap<String,String> temp4 = new HashMap<String,String>();
temp4.put("pen","Porsche Design");
temp4.put("price", "600.00$");
temp4.put("color", "Silver, Grey, Red");
list.add(temp4);
}
So, now how do we tie up the data with the row layout and the listview layout. It is in this simple piece of code in the onCreate() method of MyCustomListView class:
setContentView(R.layout.custom_list_view);
SimpleAdapter adapter = new SimpleAdapter(
this,
list,
R.layout.custom_row_view,
new String[] {"pen","price","color"},
new int[] {R.id.text1,R.id.text2, R.id.text3}

);
populateList();


setListAdapter(adapter);
Here we have set the default view to custom_list_view.
Then, using the SimpleAdapter, we have set the context, the list containing the data for display, the custom_row_view, the keys by which the data has to be fetched from the list, the TextViews into which the corresponding data has to be displayed.

Now execute and you will have a custom list view. Here is what you will get to see:


NOTE: if you do not populate the list with any data, you will see another view – the empty listview that we have defined in the custom_list_view.xml

You can download the complete source code for this example here.

Added later:
Based on a question below, I would like to add that an item can be clicked even in this custom list and the even captured by overriding the onListItemClick() method on the ListActivity class.

Here is the piece of code you can add to my sample, if you haev downlaoded and ti will toast a message on what has been selected:



protected void onListItemClick(ListView l, View v, int position, long id) {

    super.onListItemClick(l, v, position, id);
    Object o = this.getListAdapter().getItem(position);
    String pen = o.toString();
    Toast.makeText(this, "You have chosen the pen: " + " " + pen, Toast.LENGTH_LONG).show();
}

Threads and Handlers for Android

Any mobile software development needs to be done with an awareness of the end user experience. This is true in any other domain as well. But special mention here on mobile development as end users are used to responsive apps on the mobile and any small delay is perceived as un-responsiveness or worse – that the application has hung.

One of the basic principles to provide a very responsive application is to handle any time consuming code in a separate thread – not the main thread or the UI thread as it is also known. So, it is very essential to understand about how to spawn new threads (worker or background threads) and how to come back to the parent thread.

How do the 2 threads (parent/UI and the worker threads) communicate? Here comes the Handler. By definition – “A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.”

So, let us take the handler from the main thread and see how we can use it to communicate with a child thread.

When a handler is created, it is associated by default with the current thread. So, we have this piece of code in the main activity class:



Now, I spawn a new thread through a method that is called when I click a button. So, let us see the button piece of code first:

private Handler messageHandler = new Handler() {
};
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
}

start = (Button) findViewById(R.id.Button01);

start.setOnClickListener(new OnClickListener() {});
@Override
public void onClick(View arg0) {
fetchData();
}
Now, on click of the button, the fetchData() method is invoked. Assuming that this is a very time consuming task, I will spawn a thread and do the task and return from that thread as shown in the code below:

protected void fetchData() {


progressDialog = ProgressDialog.show(this, "", "Doing...");


new Thread() {


public void run() {
try {
    Thread.sleep(800);} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
       }.start();
    }


Since it is time consuming, I am starting a ProgressDialog just to inform the end user that some activity is happening. Then, I start the thread, make it sleep for 800 milliseconds and send back an empty message through the message handler. The messageHandler.sendEmptyMessage(0) is the callback on the parent thread’s messageHandler to inform that the child thread has finished its work. In this example I am sending an empty message. But this can be the means of communication and exchange of data from the child thread to the parent Thread.

Now the control returns to handleMessage() call back method. That method shown in the beginning just dismisses the progressDialog.

In real life cases, within this thread we can do things like calling web-services, calling web-sites to fetch specific data or doing network IO operations and returning actual data that needs to be displayed on the front-end.

I will take up an example of an HTTP call invoked through such a thread in the next tutorial.

Also note that the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread only. So the child thread should return all data and the painting of the UI should be left to the main thread or any UI specific thread.

There is a better way of handling this through the use of AsyncTask, a utility class available from SDK 1.5 onwards. It was available as UserTask earlier.

Threads and Handlers for Android

Any mobile software development needs to be done with an awareness of the end user experience. This is true in any other domain as well. But special mention here on mobile development as end users are used to responsive apps on the mobile and any small delay is perceived as un-responsiveness or worse – that the application has hung.

One of the basic principles to provide a very responsive application is to handle any time consuming code in a separate thread – not the main thread or the UI thread as it is also known. So, it is very essential to understand about how to spawn new threads (worker or background threads) and how to come back to the parent thread.

How do the 2 threads (parent/UI and the worker threads) communicate? Here comes the Handler. By definition – “A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue. Each Handler instance is associated with a single thread and that thread's message queue.”

So, let us take the handler from the main thread and see how we can use it to communicate with a child thread.

When a handler is created, it is associated by default with the current thread. So, we have this piece of code in the main activity class:



Now, I spawn a new thread through a method that is called when I click a button. So, let us see the button piece of code first:

private Handler messageHandler = new Handler() {
};
public void handleMessage(Message msg) {
super.handleMessage(msg);
progressDialog.dismiss();
}

start = (Button) findViewById(R.id.Button01);

start.setOnClickListener(new OnClickListener() {});
@Override
public void onClick(View arg0) {
fetchData();
}
Now, on click of the button, the fetchData() method is invoked. Assuming that this is a very time consuming task, I will spawn a thread and do the task and return from that thread as shown in the code below:

protected void fetchData() {


progressDialog = ProgressDialog.show(this, "", "Doing...");


new Thread() {


public void run() {
try {
    Thread.sleep(800);} catch (InterruptedException e) {
}
messageHandler.sendEmptyMessage(0);
}
       }.start();
    }


Since it is time consuming, I am starting a ProgressDialog just to inform the end user that some activity is happening. Then, I start the thread, make it sleep for 800 milliseconds and send back an empty message through the message handler. The messageHandler.sendEmptyMessage(0) is the callback on the parent thread’s messageHandler to inform that the child thread has finished its work. In this example I am sending an empty message. But this can be the means of communication and exchange of data from the child thread to the parent Thread.

Now the control returns to handleMessage() call back method. That method shown in the beginning just dismisses the progressDialog.

In real life cases, within this thread we can do things like calling web-services, calling web-sites to fetch specific data or doing network IO operations and returning actual data that needs to be displayed on the front-end.

I will take up an example of an HTTP call invoked through such a thread in the next tutorial.

Also note that the Android UI toolkit is not thread-safe and must always be manipulated on the UI thread only. So the child thread should return all data and the painting of the UI should be left to the main thread or any UI specific thread.

There is a better way of handling this through the use of AsyncTask, a utility class available from SDK 1.5 onwards. It was available as UserTask earlier.

Google Maps on Android For Android

Maps-based and location-based services are compelling for mobile users. Hence let us explore the support for map services in the Android platform in this tutorial. In the next we will  build upon this and add location services too.


Map services are provided by an external library that includes the com.google.android.maps package. This library is not provided as part of the standard SDK. It is provided as a Google APIs add-on to the android SDK. For the convenience of developers, this add-on is provided as part of the SDK on the emulator.


Before I jump into the example, let me explain some fundamental concepts related to the Maps API.


NOTE: For using the Google Maps, you have to obtain a Maps API key. How to obtain the key is also described towards the end of this tutorial. This is Step 1.


Maps API add-on provides a MapActivity class that extends the Activity class of Android. This helps is managing the lifecycle of a MapView object that we will be using later. Our main class in the application will be extending the MapActivity class. This class can be treated as the default activity class whenever we deal with the Maps API.


MapView – This is a class that extends the View and the ViewGroup classes of Android. It provides the basic functionality expected on a Map like responding to key presses or touch and allowing zooming etc. It also provides a controller object that helps us manipulate the Map view programmatically. We will see how, in the example later.


Now that we have understood the basics of the Maps API, let us jump into the example.


Step 2: To begin with, when you create an android project in Eclipse, instead of choosing the target name as Android 1.5, you need to select the target as Google APIs. This ensures that the project has the map API external libraries along with android 1.5 SDK.


Step 3: The Activity class you create this time should not extend the standard “android.app.Activity” class but should extend the MapActivity class about which I explained earlier.


Step 4: Apart from this, you need to add the following tag in the AndroidManifext.xml in order to use the external library:


<uses-library android:name="com.google.android.maps" />


Step 5: Now let us declare the map view in main.xml in layout folder. To do so, add this element in order to display the map using MapView.


<com.google.android.maps.MapView
android:id="@+id/myGMap"
      android:layout_width="fill_parent"
      android:layout_height="wrap_content"
      android:enabled="true"
      android:clickable="true"
      android:apiKey="0YaGLMeMFKXrhzHL-uSYZSnqXqbGwE6kxF4VwFQ"
    />


Here the apikey should be what was generated by you in an earlier step 1.


 Step 6: In the activity class I set the geo point on the map and set the satellite view to false.


      myMapView = (MapView) findViewById(R.id.myGMap);
      geoPoint = new GeoPoint((int) (latitude * 1000000), (int) (longitude * 1000000));
      myMapView.setSatellite(false);


Step 7: Now you are almost ready to go. But we will try to do some programtic handling of the mapview. For that we need to get a handle to the MapController object. It is done this way:


      myMC = myMapView.getController();
      myMC.setCenter(geoPoint);
      myMC.setZoom(15);

I also set the zoom controls to be displayed with this code.


      myMapView.setBuiltInZoomControls(true);
      myMapView.displayZoomControls(true);


Step 8: Add the following permissions in the AndroidManifest.xml in order to access the maps over the internet:


<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>


You could execute your program now to view the map with the fixed geopoint. 


Step 9: One last step – let us add some actions to the key presses for zooming in, zooming out, viewing the satellite view, normal map view


      public boolean onKeyDown(int keyCode, KeyEvent event) {
            if (keyCode == KeyEvent.KEYCODE_I) {
                  myMapView.getController().setZoom(myMapView.getZoomLevel() + 1);
                  return true;
            } else if (keyCode == KeyEvent.KEYCODE_O) {
                  myMapView.getController().setZoom(myMapView.getZoomLevel() - 1);
                  return true;
            } else if (keyCode == KeyEvent.KEYCODE_S) {
                  myMapView.setSatellite(true);
                  return true;
            } else if (keyCode == KeyEvent.KEYCODE_M) {
                  myMapView.setSatellite(false);
                  return true;
            }
            return false;
      }


Now you can run the applications. The Google map will show up with a pointer to the geo location defined in the program. You can click on I, O, S and M for zooming in, zooming out, viewing the satellite map or the normal map respectively.


Interesting?


The complete code is downloadable here.



Obtaining a Maps API Key:


Step 1: Locate debug.keystore on your system. It is usually in the USER_HOME\Local Settings\Application Data\.android folder on windows.


Step 2: Use the keytool utility to generate certificate fingerprint (MD5). keytool utility that comes with the default JDK installation.


C:\>keytool -list -alias androiddebugkey -keys
tore .android\debug.keystore -storepass android -keypass android


It will getnerate a certificate fingerprint (MD5) in this format:


Certificate fingerprint (MD5): XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX:XX


Step 3: Go to the page for obtaining the Maps API Key. Put your Certificate fingerprint (MD5) And get your API key for android Google Map application. On this page, paste the certificate fingerprint in the appropriate form field, and click the “Generate API Key” button. This will return a Maps API key string.


This key needs to be used along with the MapView element declared in the XML layout file as mentioned in the tutorial above.