Sunday, 3 June 2012

Android Google Maps Tutorial 

Android Google Map Tutorial By Sukhpal Saini

The Android platform provides easy and tight integration between Android applications and Google Maps. The well established Google Maps API is used under the hood in order to bring the power of Google Maps to your Android applications. In this tutorial we will see how to incorporate Google Maps into an Android app.

Installing the Google APIs

In order to be able to use Google Maps, the Google APIs have to be present in your SDK. In case the Google APIs are not already installed, you will have to manually install them. This is accomplished by using the Android SDK and AVD Manager.

Launch the manager and choose the “Installed Options” section to see what is already installed and the “Available Packages” to download the additional APIs.



You can find more information about this procedure in the following links:

Setting up an Eclipse project


Now that the appropriate tools are installed, let's proceed with creating a new Android project in Eclipse. The project I created is named “AndroidGoogleMapsProject” and has the following configuration:



It is important to use the “Google APIs” as the target since this option includes the Google extensions that allow you to use Google Maps. Return to the first step of this tutorial if no such option is available in your configuration. I chose the 1.5 version of the platform since we will not be using any of the latest fancy API stuff.

Google Maps API Key Generation

As you might know if you have used the Google Maps API in the past, a key is required in order to be able to use the API. The process is slightly different for use in Android applications, so let's see what is required to do. Note that the process is described in the “Obtaining a Maps API Key” page, but I will also provide a description here.

First, we have to calculate the MD5 fingerprint of the certificate that we will use to sign the final application. This fingerprint will have to be provided to the Google Maps API service so that it can associate the key with your application. Java's Key and Certificate Management tool named keytool is used for the fingerprint generation.

The keytool executable resides in the %JAVA_HOME%/bin directory for Windows or $JAVA_HOME/bin for Linux/OS X. For example, in my setup, it is installed in the “C:\programs\Java\jdk1.6.0_18\bin” folder.

While developing an Android application, the application is being signed in debug mode. That is, the SDK build tools automatically sign the application using the debug certificate. This is the certificate whose fingerprint we need to calculate. To generate the MD5 fingerprint of the debug certificate we first need to locate the debug keystore. The location of the keystore varies by platform:
  • Windows Vista: C:\Users\\.android\debug.keystore
  • Windows XP: C:\Documents and Settings\\.android\debug.keystore
  • OS X and Linux: ~/.android/debug.keystore

Now that we have located the keystore, we use the keytool executable to get the MD5 fingerprint of the debug certificate by issuing the following command:

keytool -list -alias androiddebugkey \
-keystore .keystore \
-storepass android -keypass android


For example, in my Windows machine I changed directory to the .android folder and I used the following command:

%JAVA_HOME%/bin/keytool -list -alias androiddebugkey -keystore debug.keystore -storepass android -keypass android

Note that this was executed against the debug keystore, you will have to repeat this for the keystore that will be used with the application you are going to create. Additionally, the application is run on another development environment, with different Android SDK keystore, the API key will be invalid and Google Maps will not work.

The output would be something like the following:

androiddebugkey, Apr 2, 2010, PrivateKeyEntry,
Certificate fingerprint (MD5): 72:BF:25:C1:AF:4C:C1:2F:34:D9:B1:90:35:XX:XX:XX


This the fingerprint we have to provide to the Google Maps service. Now we are ready to sign up for a key by visiting the Android Maps API Key Signup page. After we read and accept the terms and conditions, we provide the generated fingerprint as follows:



We generate the API key and we are presented with the following screen:



Creating the Google Maps application

Finally, its time to write some code. Bookmark the Google APIs Add-On Javadocs for future reference. Integrating Google Maps is quite straightforward and can be achieved by extending the MapActivity class instead of the Activity class that we usually do. The main work is performed by a MapView which displays a map with data obtained from the Google Maps service. A MapActivity is actually a base class with code to manage the boring necessities of any activity that displays a MapView. Activity responsibilities include:
  • Activity lifecycle management
  • Setup and teardown of services behind a MapView

To extend from MapActivity we have to implement the isRouteDisplayed method, which denotes whether or not we are displaying any kind of route information, such as a set of driving directions. We will not provide such information, so we just return false there.

In our map activity, we will just take reference of a MapView. This view will be defined in the layout XML. We will also use the setBuiltInZoomControls method to enable the built-in zoom controls.

Let's see how our activity looks like so far:


package com.javacodegeeks.android.googlemaps;

import android.os.Bundle;

import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

public class GMapsActivity extends MapActivity {
    
    private MapView mapView;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mapView = (MapView) findViewById(R.id.map_view);       
        mapView.setBuiltInZoomControls(true);
        
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
}

Let's also see the referenced main.xml layout file:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:orientation="vertical" 
 android:layout_width="fill_parent"
 android:layout_height="fill_parent">
 
 <com.google.android.maps.MapView
  xmlns:android="http://schemas.android.com/apk/res/android"
  android:id="@+id/map_view"
  android:layout_width="fill_parent" 
  android:layout_height="fill_parent"
  android:clickable="true" 
  android:enabled="true" 
  android:apiKey="API-KEY-HERE" />
   
</RelativeLayout>

Do not forget to provide your API key in the relevant field or else Google Maps will not work.

Launching the application

To test the application we will have to use a device that includes the Google APIs. We will use the AVD manager to create a new device with target set to one of the Google APIs and settings like the following:



If we now launch the Eclipse configuration, we will encounter the following exception:

java.lang.ClassNotFoundException: com.javacodegeeks.android.googlemaps.GMapsActivity in loader dalvik.system.PathClassLoader@435988d0

The problem is that we haven't notified Android that we wish to use the add-on Google APIs which are external to the base API. To do so, we have to use the uses-library element in our Android manifest file, informing Android that we are going to use classes from the com.google.android.maps package.

Additionally, we have to grant internet access to our application by adding the android.permission.INTERNET directive. Here is how our AndroidManifest.xml file looks like:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.javacodegeeks.android.googlemaps"
      android:versionCode="1"
      android:versionName="1.0">
      
    <application android:icon="@drawable/icon" android:label="@string/app_name">
    
        <activity android:name=".GMapsActivity"
                  android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        
      <uses-library android:name="com.google.android.maps" />
      
    </application>

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

</manifest> 

And here is what the application screen looks like:



If you click inside the map, the zoom controls will appear and you will be able to zoom in and out.

Adding map overlays

The next step is to add some custom map overlays. To do so, we can extend the Overlay class, which is a base class representing an overlay which may be displayed on top of a map. Alternatively, we may extend the ItemizedOverlay, which is a base class for an Overlay which consists of a list of OverlayItems. Let's see how we can do this (note that the following example is very similar to the Hello Map View article from the Android documentation):

package com.javacodegeeks.android.googlemaps;

import java.util.ArrayList;

import android.app.AlertDialog;
import android.content.Context;
import android.graphics.drawable.Drawable;

import com.google.android.maps.ItemizedOverlay;
import com.google.android.maps.OverlayItem;

public class CustomItemizedOverlay extends ItemizedOverlay<OverlayItem> {
   
   private ArrayList<OverlayItem> mapOverlays = new ArrayList<OverlayItem>();
   
   private Context context;
   
   public CustomItemizedOverlay(Drawable defaultMarker) {
        super(boundCenterBottom(defaultMarker));
   }
   
   public CustomItemizedOverlay(Drawable defaultMarker, Context context) {
        this(defaultMarker);
        this.context = context;
   }

   @Override
   protected OverlayItem createItem(int i) {
      return mapOverlays.get(i);
   }

   @Override
   public int size() {
      return mapOverlays.size();
   }
   
   @Override
   protected boolean onTap(int index) {
      OverlayItem item = mapOverlays.get(index);
      AlertDialog.Builder dialog = new AlertDialog.Builder(context);
      dialog.setTitle(item.getTitle());
      dialog.setMessage(item.getSnippet());
      dialog.show();
      return true;
   }
   
   public void addOverlay(OverlayItem overlay) {
      mapOverlays.add(overlay);
       this.populate();
   }

}

Our class requires an Android Drawable in its constructor, which will be used as a marker. Additionally, the current Context has to be provided. We use an ArrayList to store all the OverlayItems stored in the specific class, so the createItem and size methods are pretty much self-explanatory. The onTap method is called when an item is “tapped” and that could be from a touchscreen tap on an onscreen Item, or from a trackball click on a centered, selected Item. In that method, we just create an AlertDialog and show it to the user. Finally, in the exposed addOverlay method, we add the OverlayItem and invoke the populate method, which is a utility method to perform all processing on a new ItemizedOverlay.

Let's see how this class can be utilized from our map activity:

package com.javacodegeeks.android.googlemaps;

import java.util.List;

import android.graphics.drawable.Drawable;
import android.os.Bundle;

import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapController;
import com.google.android.maps.MapView;
import com.google.android.maps.Overlay;
import com.google.android.maps.OverlayItem;

public class GMapsActivity extends MapActivity {
    
    private MapView mapView;
    
    private static final int latitudeE6 = 37985339;
    private static final int longitudeE6 = 23716735;
    
    @Override
    public void onCreate(Bundle savedInstanceState) {
        
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        
        mapView = (MapView) findViewById(R.id.map_view);       
        mapView.setBuiltInZoomControls(true);
        
        List mapOverlays = mapView.getOverlays();
        Drawable drawable = this.getResources().getDrawable(R.drawable.icon);
        CustomItemizedOverlay itemizedOverlay = 
             new CustomItemizedOverlay(drawable, this);
        
        GeoPoint point = new GeoPoint(latitudeE6, longitudeE6);
        OverlayItem overlayitem = 
             new OverlayItem(point, "Hello", "I'm in Athens, Greece!");
        
        itemizedOverlay.addOverlay(overlayitem);
        mapOverlays.add(itemizedOverlay);
        
        MapController mapController = mapView.getController();
        
        mapController.animateTo(point);
        mapController.setZoom(6);
        
    }

    @Override
    protected boolean isRouteDisplayed() {
        return false;
    }
    
}

We create a new instance of our CustomItemizedOverlay class by using the default Android icon as the Drawable. Then we create a GeoPoint pointing to a predefined location and use that to generate an OverlayItem object. We add the overlay item to our CustomItemizedOverlay class and it magically appears in our map on the predefined point.

Finally, we take reference of the underlying MapController and use it to point the map to a specific geographical point using the animateTo method and to define the zoom level by using the setZoom method.

If we launch again the configuration, we will be presented with a zoomed-in map which includes an overlay marker pointing to JavaCodeGeeks home town Athens, Greece. Clicking on the marker will cause the alert dialog to pop-up displaying our custom message.



That's all guys. A detailed guide on how to integrate Google Maps into your Android application. As always, you can download the Eclipse project created for this tutorial.

Happy mobile coding! And don't forget to share!

Saturday, 2 June 2012

Creating a simple android app with 2 buttons

Creating a simple android app with 2 buttons

How do I build a very simple android app you ask? It's easy, building a basic android application is not that hard. Making something really useful, cool and bug free, now that takes a good developer.
This is a brief tutorial will show you how to code a very basic two button android application (with a start button and a stop button).
You can use this code as an android project template or starting point for simple projects.

Two Button Application Use Case

A simple two button application, can be your starting point for various android projects. It can be useful for example when you have an application that starts and stops a service from the click of a button Watch for tutorial on this soon.
Note:This tutorial assumes you have completed the HelloWorld Tutorial in the Android docs and you are a little familiar with Eclipse and ADT. The tutorial is aimed at developers who are very new to Android.

Creating a two button app

1) Create the project

In Eclipse create a new Android project and define the properties as shown below. Feel free to use your own package names.

2) Create a simple layout

For our main activity we're going to define a very basic layout consisting of one TextView and two Buttons (a start button and a stop button).
Modify your project/res/layout/main.xml file to this:




















<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
<TextView 
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="This is a simple two button app. \r\n \r\n Tell your user what your app does here \r\n \r\n \r\n \r\n"
    android:padding="10dp"
    android:textColor="#FFFFFF"
    />
<Button
 android:id="@+id/buttonStart"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Start"/>
<Button
 android:id="@+id/buttonStop"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Stop"/>
</LinearLayout>
If you run your project in the emulator it should look like this

3) Adding onClickListeners to the buttons

In order for the buttons to actually do something useful, and to provide a template for where you can put future functionality, we'll need to define onClickListeners for each button.
Let's update the TwoButtonApp.java main activiy with the following code:






















package com.idleworx.android.twobuttonapp;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;
public class TwoButtonApp extends Activity {
     
 private static String logtag = "TwoButtonApp";//for use as the tag when logging
   
 /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
         
        Button buttonStart = (Button)findViewById(R.id.buttonStart);       
     buttonStart.setOnClickListener(startListener); // Register the onClick listener with the implementation above
       
     Button buttonStop = (Button)findViewById(R.id.buttonStop);       
     buttonStop.setOnClickListener(stopListener); // Register the onClick listener with the implementation above
    }
     
    //Create an anonymous implementation of OnClickListener
    private OnClickListener startListener = new OnClickListener() {
        public void onClick(View v) {
          Log.d(logtag,"onClick() called - start button");             
          Toast.makeText(TwoButtonApp.this, "The Start button was clicked.", Toast.LENGTH_LONG).show();
          Log.d(logtag,"onClick() ended - start button");
        }
    };
     
    // Create an anonymous implementation of OnClickListener
    private OnClickListener stopListener = new OnClickListener() {
        public void onClick(View v) {
         Log.d(logtag,"onClick() called - stop button");
         Toast.makeText(TwoButtonApp.this, "The Stop button was clicked.", Toast.LENGTH_LONG).show();
          Log.d(logtag,"onClick() ended - stop button");
        }
    };
     
     
    @Override
 protected void onStart() {//activity is started and visible to the user
  Log.d(logtag,"onStart() called");
  super.onStart(); 
 }
 @Override
 protected void onResume() {//activity was resumed and is visible again
  Log.d(logtag,"onResume() called");
  super.onResume();
   
 }
 @Override
 protected void onPause() { //device goes to sleep or another activity appears
  Log.d(logtag,"onPause() called");//another activity is currently running (or user has pressed Home)
  super.onPause();
   
 }
 @Override
 protected void onStop() { //the activity is not visible anymore
  Log.d(logtag,"onStop() called");
  super.onStop();
   
 }
 @Override
 protected void onDestroy() {//android has killed this activity
   Log.d(logtag,"onDestroy() called");
   super.onDestroy();
 }
}

Notes

  • As you can see, each button (or any resource for that matter) can be retrieved by the id was associated with in the layout:
    @+id/buttonStart 
    
    can be retreived with:
    
    Button buttonStart = (Button)findViewById(R.id.buttonStart);  
    
  • We have attached two anonymous OnClickListeners() to each of our two buttons
  • Each listener displays a simple Toast (a brief message to the user).
  • Logging is very important especially during debugging, so make sure you use it where ever you need
  • Not the logtag variable defined in the very top. It's a quick shortcut to save time when logging statements in your app with the Log.X methods. I usually use the same name as the class name and use the Create Filter option in the LogCat view to filter my code out.
  • For easier debugging I've added logging of all the other lifecycle methods in the Activity. When you do debugging of your apps it's very important to understand the lifecycle of an android app, and even more important to see how it's called in relation to your code.
So this is it, Introduction to Android 101. You should now have a very basic android app running.
For reference here is how your AndroidManifest.xml file should look (you should not have had to modify this file so far if you have followed this tutorial):

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.       package="com.idleworx.android.twobuttonapp"
  4.       android:versionCode="1"
  5.       android:versionName="1.0">
  6.     <uses-sdk android:minSdkVersion="8" />
  7.  
  8.     <application android:icon="@drawable/icon" android:label="@string/app_name">
  9.         <activity android:name=".TwoButtonApp"
  10.                   android:label="@string/app_name">
  11.             <intent-filter>
  12.                 <action android:name="android.intent.action.MAIN" />
  13.                 <category android:name="android.intent.category.LAUNCHER" />
  14.             </intent-filter>
  15.         </activity>
  16.  
  17.     </application>
  18. </manifest>

Friday, 1 June 2012

Writing Your First Android App

By Sukhpal Saini on 01 june 2012
Writing your first app and seeing it running on your phone is only half the fun when it comes to Android. It’s relatively simple to have your app up and live in the Android Market, being used by Android users almost instantly.
Head over to http://market.android.com/publish and using your Google Account, register as a developer in the Android Market. The registration process is immediate and requires a one-off registration fee of $25.
By the end of this article, you’ll be ready to submit an Android app to the Market (although it’s probably best to avoid submitting this HelloWorld-style app that we’re about to create).
Setting Up Your Development Environment
Java developers, especially those using Eclipse, will have an easy transition to the Android development world. Most apps are written in Java (you can drop down to using native C), and it’s typical for development to be done within the Eclipse IDE due to the tooling support provided by Google (although everything can be done outside the IDE from the command line). Android development is supported on the three major operating systems: Windows (XP, Vista, and 7), Mac OS X, and Linux.
this is installed or unzipped for the next step.
In order to set up your environment, you’ll need to download and install the following:
  • Android Developer Tools (ADT)—Eclipse Plugin, which needs to be installed from inside Eclipse:
    • From the Help menu, click on Install New Software, then select Add.
    • In the dialog box, enter ADT Plugin for the Name and https://dl-ssl.google.com/android/eclipse/ in Location; then press OK.
    • Select Developer Tools and click Next, and Next again when presented with the items to be installed.
    • Read and accept the license terms, and click Finish.
When the installation is complete, restart Eclipse.
sitepoint-android-image1
Now configure the installed plugin by clicking on the Window menu and selecting Preferences. If you’re on a Mac, select Eclipse -> Preferences.
Select Android, and then for the SDK Location, browse to where you installed the Android SDK Tools, and select that. Click Apply, then OK.
Using the tools now installed, you need to install the SDK components. This is done using the Android SDK and AVD Manager found under the Window menu in Eclipse. Launch the manager and select Available packages. Then select Documentation, SDK Platform Android 2.3, and Samples for SDK API 9; click Install Selected.
sitepoint-android-image2
Running the Emulator
Now that you have all the tools required to started developing and running Android apps, you need to create a virtual device for your apps to run on in the Android Emulator. An Android Virtual Device (AVD) defines a device profile that the emulator can use when running your apps. You can also create multiple AVDs to test against, which comes in handy when you want to test your app on different-sized screens and various versions of the SDK.
To create an AVD, select Virtual Devices from the Android SDK and AVD Manager, and click New. Give the device a name and select the target SDK from the drop-down. Here, you’re also able to select different screen sizes and emulator storage sizes; for now, we’ll leave everything as the default and click Create AVD.
sitepoint-android-image3
Now you’re able to run the emulator by selecting the created AVD and clicking Start, and then Launch. After some time, you’ll see the emulator running; you’re now able to run some of the built-in apps.
sitepoint-android-image4
Creating a Project
Leaving the Emulator running, restart Eclipse so as to create our first Android project. Once Eclipse has finished loading, go to File -> New -> Other -> Android and select Android Project.
Fill in the Project and Application names, and then enter a package name for the app. This package will not only become the top-level Java package for your source files, but also provides a unique identifier for your app. No two apps can have the same package identifier installed on the phone at the same time, and the same goes for apps submitted to the Android Market.
sitepoint-android-image5
With Create Activity selected, provide a name for the Java class that will become the entry point to your app, and click Finish.
Explore the contents of the generated project. You will find various Java, XML, and configuration files.
sitepoint-android-image6
This is a good time to explain three key concepts used in Android app development.
Activity (HelloWorldActivity.java)—An Android Activity is a single-focused task that makes up part of your app. The Activity will display a user interface in the supplied Window, and interact with the user to perform the task. A single Activity could be displaying a list of emails or showing a map of the current location.
Typically, multiple Activities together form a complete Android application.
The generated Activity extends from the class android.app.Activity and overrides a single method, onCreate. Activities are driven by events coming from the Android operating system, moving the Activity through different stages of its life cycle. The onCreate method is called when the Activity is being created with the intention of being the current running Activity.
It’s worth becoming familiar with the life cycle of an Activity and the methods that can be overridden as detailed in the Android developer docs.
Manifest (AndroidManifest.xml)—This is the central configuration file required by Android to understand the various pieces of your app and how they fit together. Take a look at the generated Manifest, where you’ll see:
  • package="com.sitepoint" which forms the unique identifier of the app
  • <application ... > contains the attributes required for the app icon and name as it appears on the phone
  • <activity ... > is where the single Activity that was generated is described with attributes for the class name (relative to the app package), and a display label for the Activity.
  • <intent filter> these XML elements indicate that this Activity is the entry point for your app when it’s launched:
    • <action android:name="android.intent.action.MAIN" />
    • <category android:name="android.intent.category.LAUNCHER" />
Intents—Android is designed in such a way that apps can call out to other installed apps without having to know the specific details of their interfaces. This is achieved using the concept of Intents and Intent Filters. An Intent is an abstract description of an action (such as VIEW, SEND, EDIT), and typically references some data on which the action is to be performed (for example, a Contact in the address book).
Activities can create Intents as a way of passing responsibility for a task onto other Activities. This can be either within the same app (such as going from an Activity that displays a list of contacts to an Activity that displays the details of the single selected contact) or out to an external app (when, for example, you want to display a PDF using an installed PDF viewer).
Activities advertise their abilities to handle combinations of actions and data types through Intent Filters. Our generated Activity advertised that it’s able to handle a MAIN action when the app is being launched. A PDF viewer may advertise that it can display data of type PDF. If two apps advertise the same ability, Android will prompt the user to select which one they want to use. The Intent is run, and can make the selection the default as an option.
Running and Debugging
Now let’s run the app in the emulator, which you should already have running. Select the project in Eclipse, and from the Run menu, select Run; then select Android Application and OK in the dialog. While the app is loading (or the emulator starts up again if you closed it), you should add some of the Android-specific views to your current Eclipse perspective. You can add them from Window -> Show View -> Other -> Android. I typically add Devices, Emulator Control, and LogCat.
sitepoint-android-image7
From the Devices view, you can see any emulators or phones you have plugged into your system that are available to debug apps on. You’ll also be able to see the processes currently running along with your own, identified by the package name you gave your app. If you select the emulator in this view and then move to the LogCat view, you’ll see all the logging that the system has been writing.
This view is extremely useful for debugging your apps. It allows you to create filters, so you can switch between seeing different levels of logging (warning, debug, fatal) and different tags. (Typically, an app will output logging with a tag that’s the same as the class name for where the logging is coming from).
sitepoint-android-image8
Switch back to the emulator, and you should now see the app running as pictured below.
sitepoint-android-image9