andbook!.pdf - Learning Android Get an anddev.org - Android-Shirt Back to index
anddev.org Header Logo
FAQ Search Top rated articles Browse Feeds anddev.org - Authors Contact Details Register Log in

Simple GoogleMaps with Threads


 
       anddev.org - Android Development Community | Android Tutorials | Index -> Map Tutorials
Author Message
michels
Junior Developer
Junior Developer


Joined: 24 Sep 2008
Posts: 17
Location: Germany

PostPosted: Thu Sep 25, 2008 1:10 pm    Post subject: Simple GoogleMaps with Threads Reply with quote

Simple GoogleMaps with Threads
Using Threads and Handlers the Android-Way


This tutorial is also available in german at my android weblog Androidianer.de

This tutorial based on the Simple GoogleMaps tutorial I wrote yesterday, where we learned how to convert an address in longitude and latitude by using the GeoCoder class. As read in the APIs, "it may be useful to call this method from a thread separate from your primary UI thread." So we will do this today.

How it looks like:
Like the Simple GoogleMaps. But with a progress dialog that is shown everytime a new address is searched.




What is a thread?
You can read this chapter in the java docs for better understanding and to see how threads are used.
Read also this in the android API.
Or just accept the following sentence:
A thread is a parallel process - While we search an adress, we can also display a progress dialog.

How can we use threads in Android?
We can implement the Runnable interface and create a run() function.
Java:

public class simpleGoogleMaps extends MapActivity implements runnable{
  public void onCreate(Bundle savedInstanceState) {
  Thread thread = new Thread(this);
  thread.start();
  }
 
  public void run() {
    //do something
  }
}

You can read this tutorial from helloandroid.com to see how this works.

But there is also an alternative way I like much more

GeoCoder with threads
1.If you look at the Simple GoogleMaps code, you will see, that everything important, like the address search, happens in the OnClickListener function.
But now, everything we do in the OnClickListener is to display a progress dialog and start parallel a new thread:

Java:

btnSearch.setOnClickListener(new OnClickListener() {
  public void onClick(View v) {
    //Show a progress dialog
    pd = ProgressDialog.show(simpleGoogleMaps.this, "Working..", "Searching your address", true, false);
   
    //create a new thread
    searchAdress = new Thread() {
      public void run(){
        //action of the thread
      }
    }
  }
});


2.While the progress dialog is shown, we will search for the address. So we add the search function in our thread and start it.

Java:

btnSearch.setOnClickListener(new OnClickListener() {
  public void onClick(View v) {
    //Show a progress dialog
    pd = ProgressDialog.show(simpleGoogleMaps.this, "Working..", "Searching your address", true, false);
   
    //create a new thread
    searchAdress = new Thread() {
      public void run(){
        String addressInput = adress.getText().toString(); // Get input text
        try {
          foundAdresses = gc.getFromLocationName(addressInput, 5); // Search addresses
        } catch (Exception e) {
          // @todo: Show error message
        }
        showAdressResults.sendEmptyMessage(0);   
      }
    }
    searchAdress.start();
  }
});


3.Now our application shows a nifty progress dialog and searches in the background an entered address. Nice!
After the search is ready (end of the try-catch-statement) we send a message to showAdressResults. We haven't defined that yet, so let's do

Java:

private Handler showAdressResults = new Handler() {
  public void handleMessage(Message msg) {
  }
}


4.showAdressResults is defined as a handler, that waits all the time for a message.
When he gets one, he knows that we found an address. Then we dismiss the progress dialog and display the map.
Here we go
Java:

private Handler showAdressResults = new Handler() {
  public void handleMessage(Message msg) {
    if (foundAdresses.size() == 0) { // if no address found,
      // display an error
      Dialog locationError = new AlertDialog.Builder(simpleGoogleMaps.this)
      .setIcon(0)
      .setTitle("Error")
      .setPositiveButton(R.string.ok, null)
      .setMessage("Sorry, your address doesn't exist.")
    .create();
    locationError.show();
     
    } else { // else display address on map
      for (int i = 0; i < foundAdresses.size(); ++i) {
      // Save results as Longitude and Latitude
      Address x = foundAdresses.get(i);
      lat = x.getLatitude();
      lon = x.getLongitude();
    }
    navigateToLocation((lat * 1000000), (lon * 1000000),myMap); // display the found address
  }
}


Full Source Code
Java:

//lots of imports.. see attached source
public class simpleGoogleMaps extends MapActivity {
     protected boolean isRouteDisplayed() {
          return false;
     }
 
     //lots of variables here

     @Override
     public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.main);

          myMap = (MapView) findViewById(R.id.simpleGM_map); // Get map from XML
          btnSearch = (Button) findViewById(R.id.simpleGM_btn_search); // Get button from xml
          adress = (EditText) findViewById(R.id.simpleGM_adress); // Get address from XML

          gc = new Geocoder(this); // create new geocoder instance

          btnSearch.setOnClickListener(new OnClickListener() {
               public void onClick(View v) {
                    
                    pd = ProgressDialog.show(simpleGoogleMaps.this, "Working..", "Searching your address", true, false); //Show a progress dialog
               
                    
                    searchAdress = new Thread() {
                         public void run(){
                              String addressInput = adress.getText().toString(); // Get input text
                              try {
                                   foundAdresses = gc.getFromLocationName(addressInput, 5); // Search addresses
                                   Thread.sleep(1500); //just to show you that it works Smile
                              } catch (Exception e) {
                                   // @todo: Show error message
                              }
                              showAdressResults.sendEmptyMessage(0);                           
                         }
                    };
                    searchAdress.start();
               }
          });
     }
     
     private Handler showAdressResults = new Handler() {
             @Override
             public void handleMessage(Message msg) {
               pd.dismiss();
                 
                    if (foundAdresses.size() == 0) { // if no address found,
                         // display an error
                         Dialog locationError = new AlertDialog.Builder(
                                   simpleGoogleMaps.this).setIcon(0).setTitle(
                                   "Error").setPositiveButton(R.string.ok, null)
                                   .setMessage("Sorry, your address doesn't exist.")
                                   .create();
                         locationError.show();
                         
                    } else { // else display address on map
                         for (int i = 0; i < foundAdresses.size(); ++i) {
                              // Save results as Longitude and Latitude
                              // @todo: if more than one result, then show a
                              // select-list
                              Address x = foundAdresses.get(i);
                              lat = x.getLatitude();
                              lon = x.getLongitude();
                         }
                         navigateToLocation((lat * 1000000), (lon * 1000000),myMap); // display the found address
                    }
                    
             }
         };   

     /**
      * Navigates a given MapView to the specified Longitude and Latitude
      *
      * @param latitude
      * @param longitude
      * @param mv
      */

     public static void navigateToLocation(double latitude, double longitude, MapView mv) {
          GeoPoint p = new GeoPoint((int) latitude, (int) longitude); // new
          // GeoPoint
          mv.displayZoomControls(true); // display Zoom (seems that it doesn't
          // work yet)
          MapController mc = mv.getController();
          mc.animateTo(p); // move map to the given point
          int zoomlevel = mv.getMaxZoomLevel(); // detect maximum zoom level
          mc.setZoom(zoomlevel - 1); // zoom
          mv.setSatellite(false); // display only "normal" mapview
     }
}


Full source code is attached. Hope that helps to understand what a thread is and how it should be used.

Greetings from Germany
Mic



simpleGoogleMaps-withThread.tar
 Description:
Full source code

Download
 Filename:  simpleGoogleMaps-withThread.tar
 Filesize:  74.5 KB
 Downloaded:  1506 Time(s)



Last edited by michels on Thu Oct 16, 2008 9:26 pm; edited 1 time in total
Back to top
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Thu Sep 25, 2008 2:23 pm    Post subject: Reply with quote

Smile fine once again Exclamation
One thing I'd mention is that you should pass a Constant to showAdressResults.sendEmptyMessage(0); instead of just '0'.

So you could switch(incomingMessage.what) in myHandler.handleMessage(Message incomingMessage) to handle the messages based on their what-id.

Best Regards,
plusminus

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
ninor
Moderator
Moderator


Joined: 14 Aug 2008
Posts: 180
Location: Barcelona, Spain

PostPosted: Thu Sep 25, 2008 9:41 pm    Post subject: Reply with quote

Very useful and clear example! Smile
Back to top
View user's profile Send private message
happy_bob
Freshman
Freshman


Joined: 20 Oct 2008
Posts: 3

PostPosted: Tue Oct 28, 2008 1:29 pm    Post subject: Reply with quote

so why doesn't the map appear for me? it always seems to be empty.



android.JPG
 Description:
mapview
 Filesize:  40.78 KB
 Viewed:  12701 Time(s)

android.JPG


Back to top
View user's profile Send private message
michels
Junior Developer
Junior Developer


Joined: 24 Sep 2008
Posts: 17
Location: Germany

PostPosted: Tue Oct 28, 2008 1:52 pm    Post subject: Reply with quote

happy_bob wrote:
so why doesn't the map appear for me? it always seems to be empty.


Do you have internet access?

_________________
Androidianer.de - Deutscher Weblog rund um Android
Back to top
View user's profile Send private message
happy_bob
Freshman
Freshman


Joined: 20 Oct 2008
Posts: 3

PostPosted: Tue Oct 28, 2008 2:00 pm    Post subject: Reply with quote

michels wrote:
happy_bob wrote:
so why doesn't the map appear for me? it always seems to be empty.


Do you have internet access?


yes i have! and it seems to be working in that way that it gives a error message if i search for a city that doesn't exist, for example "blablabla", but it doesnt print the map after it has searched.
I'm quite new at this, does this have something to do with the maps API key?
Back to top
View user's profile Send private message
plusminus
Site Admin
Site Admin


Joined: 14 Nov 2007
Posts: 2660
Location: College Park, MD

PostPosted: Tue Oct 28, 2008 2:29 pm    Post subject: Reply with quote

happy_bob wrote:
..., does this have something to do with the maps API key?


Seems so, yes.

_________________
Download my apps Idea
Please remember, that this board is give & take Smile


| Android Development Community / Tutorials
Back to top
View user's profile Send private message Send e-mail Visit poster's website
michels
Junior Developer
Junior Developer


Joined: 24 Sep 2008
Posts: 17
Location: Germany

PostPosted: Thu Oct 30, 2008 5:03 pm    Post subject: Reply with quote

happy_bob wrote:
does this have something to do with the maps API key?


Yes, today I've tested it with a valid API Key and it works well.

_________________
Androidianer.de - Deutscher Weblog rund um Android
Back to top
View user's profile Send private message
ndroid
Junior Developer
Junior Developer


Joined: 15 Dec 2008
Posts: 15

PostPosted: Thu Dec 18, 2008 6:10 am    Post subject: Reply with quote

Hi
my observation is that i get result for first search only.
other searches result in an exception.
do i need to get geocoder for every search.
thanks
Back to top
View user's profile Send private message
sitara
Junior Developer
Junior Developer


Joined: 27 Nov 2008
Posts: 13

PostPosted: Fri Jan 02, 2009 6:00 am    Post subject: Reply with quote

Hi ,
i am getting the same blank map as happy_bob.

i have gotten my api key, but where do i put the key? which file should i put it in?


Sitara
Back to top
View user's profile Send private message
winvinay
Freshman
Freshman


Joined: 20 Jan 2009
Posts: 3

PostPosted: Tue Jan 20, 2009 10:07 am    Post subject: Reply with quote

sitara wrote:
Hi ,
i am getting the same blank map as happy_bob.

i have gotten my api key, but where do i put the key? which file should i put it in?


Sitara



Api key should be added in the xml as shown below

<com.google.android.maps.MapView android:id="@+id/simpleGM_map"
android:layout_width="fill_parent" android:layout_height="310px"
android:apiKey="Key" android:layout_x="2px" android:layout_y="100px"
android:clickable="true" />

_________________
Vinay H V
Software Engineer
Back to top
View user's profile Send private message
android2
Developer
Developer


Joined: 04 Oct 2009
Posts: 48

PostPosted: Sun Oct 04, 2009 9:02 pm    Post subject: not function Reply with quote

I can not see the map I put the API key and there permission.internet what is wrong???
winvinay wrote:
sitara wrote:
Hi ,
i am getting the same blank map as happy_bob.

i have gotten my api key, but where do i put the key? which file should i put it in?


Sitara



Api key should be added in the xml as shown below

<com.google.android.maps.MapView android:id="@+id/simpleGM_map"
android:layout_width="fill_parent" android:layout_height="310px"
android:apiKey="Key" android:layout_x="2px" android:layout_y="100px"
android:clickable="true" />
Back to top
View user's profile Send private message AIM Address
android2
Developer
Developer


Joined: 04 Oct 2009
Posts: 48

PostPosted: Mon Oct 05, 2009 3:40 pm    Post subject: Re: not function Reply with quote

How do you get fingerprint for 'api key for Android???
android2 wrote:
I can not see the map I put the API key and there permission.internet what is wrong???
winvinay wrote:
sitara wrote:
Hi ,
i am getting the same blank map as happy_bob.

i have gotten my api key, but where do i put the key? which file should i put it in?


Sitara



Api key should be added in the xml as shown below

<com.google.android.maps.MapView android:id="@+id/simpleGM_map"
android:layout_width="fill_parent" android:layout_height="310px"
android:apiKey="Key" android:layout_x="2px" android:layout_y="100px"
android:clickable="true" />
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
       anddev.org - Android Development Community | Android Tutorials | Index -> Map Tutorials All times are GMT + 1 Hour
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


© 2007, Android Development Community
All rights reserved.
Powered by phpBB.