More Initialization of Micro Jobsjava

The previous section was a rather long digression into XML Layout files, but as you can see, that is where a lot of the initialization of the application's user interface takes place: where views are defined, named, and given attributes; where the screen is layed out; and where hints are given to the layout manager describing the way we would like the screen to look. Let's get back to the Java code that brings up the application, starting where we left off in db = new MicroJobsDatabase(this);

// Get current position final Location myLocation

= getCurrentLocation((LocationManager) getSystemService(Context.LOCATION_SERVICE));

Spinner spnLocations = (Spinner) findViewById(; mvMap = (MapView) findViewById(;

// get the map controller final MapController mc = mvMap.getController();

mMyLocationOverlay = new MyLocationOverlay(this, mvMap); mMyLocationOverlay.runOnFirstFix( new Runnable() {

mc.animateTo(mMyLocationOverlay.getMyLocation()); mc.setZoom(16);

Create the database object

We said before that we are going to use a small SQLite database to hold the job, worker, and employer information. The first line initializes that database by asking Android to create a new MicroJobsDatabase object (and initialize it). The Java code for this is in the file, and we'll look at it in detail later in Chapter 8.

Get our location

We'll need to know our current location to do things like finding jobs that are close by, so we get it here by calling getCurrentLocation, which is a method defined later and that accepts the name of our LocationManager as its argument. The Location Manager is a special class that Android instantiates for you, and you can retrieve the instance for your application through the call to getSystemService.

Initialize the Spinner

As explained in the previous section, we place a Spinner widget at the top of the screen to help users quickly go to one of their favorite locations and look for jobs. This is the first time we encounter the findViewByld method, which is the way we access the IDs we defined in the XML layout file. If you recall, we identified the Spinner in main.xml as spnLocations. When we built the application, Android compiled that XML into a Java identifier that it placed in and linked it into the application. So now we can use findViewByld to connect our Java Spinner to the XML attributes we defined.

Initialize the MapView and MapController

Similarly,we connect the Java MapView to the attributes defined for it in main.xml, and then attach a MapController to it. You'll see much more about the controller in Chapter 9, but for now think of it as a handle to get to all the methods you need to control the MapView.

Initialize the LocationOverlay

We want to create a LocationOverlay that will build and draw the Map in our MapView when we want to view a map of our local area. Again, Maps are covered in much more detail later, but you can see here that we use the constructor to create a new overlay and tell it to run when it gets its first fix from the LocationManager, so that it displays our current location. We also set the zoom level so it's about right for a metropolitan area.

We'll skip over the map overlay initialization, because that will be covered in more detail in Chapter 9, where we talk about mapping. We still need to initialize the remaining Views on this screen: the Button and the Spinner. The code for these follows:

// Create a button click listener for the List Jobs button. Button btnList = (Button) findViewByld(; btnList.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) {

Intent intent = new Intent(MicroJobs.this.getApplication(),

MicroJobsList.class); startActivity(intent);

// Load a HashMap with locations and positions List<String> lsLocations = new ArrayList<String>();

final HashMap<String, GeoPoint> hmLocations = new HashMap<String, GeoPoint>(); hmLocations.put("Current Location", new GeoPoint((int) latitude, (int) longitude)); lsLocations.add("Current Location");

// Add favorite locations from this user's record in workers table worker = db.getWorker();

hmLocations.put(worker.getColLoc1Name(), new GeoPoint((int)worker.getColLoc1Lat(),

(int)worker.getColLoc1Long())); lsLocations.add(worker.getColLoc1Name());

hmLocations.put(worker.getColLoc2Name(), new GeoPoint((int)worker.getColLoc2Lat(),

(int)worker.getColLoc2Long())); lsLocations.add(worker.getColLoc2Name());

hmLocations.put(worker.getColLoc3Name(), new GeoPoint((int)worker.getColLoc3Lat(),

(int)worker.getColLoc3Long())); lsLocations.add(worker.getColLoc3Name());

ArrayAdapter<String> aspnLocations

= new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, lsLocations);

aspnLocations.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spnLocations.setAdapter(aspnLocations);

Create a callback for the btnList Button View

We first get a handle on the Button View by doing a lookup on its ID, just as we did before for the Spinner and MapView. We then set the behavior of the Button, which uses a construct known as a listener to respond to external events.

When a user clicks a button, Android sends an event to its OnClickListener listener. In this code, we set the Button's behavior by setting its OnClickListener to the method that we immediately define, onClick.

When the user clicks on btnList, we want to display a list of available MicroJobs. To do that, we have to launch a new Activity,, which contains the screen that displays the list. We can do that by calling the startActivity method with an Intent that describes the new Activity. The first statement in onClick() creates the Intent, using the constructor for Intents that allows us to explicitly name the Activity. This constructor takes two arguments: a pointer to the context of the current application, and the name of the Class to start. The next statement in onClick() then uses that Intent to start an instantiation of MicroJobsList.

Initialize the list of entries in the Spinner View

We need two data structures to pass to our Spinner: a list of favorite locations that the Spinner will display (and the user can select), and a hash map connecting location names to geographical locations (latitude and longitude). Don't confuse the HashMap with a geographical Map; the HashMap uses the term "map" in the way many programmers use it, to mean an associative array. We first create the list of location names (lsLocations), and then the HashMap that we'll use to map names to GeoPoints (hmLocations). We then put the first entry, Current Location, into the list and the HashMap. This entry will always return the user to the current location. This item is special because it can be a moving target. For example, the user may be consulting our application on a fast-moving train or an airplane, so we have to dynamically retrieve the location of the device whenever the current location is selected.

We then add three entries for the user's "favorite locations," recorded in the user's record in the workers table in the MJAndroid database. We'll dive into the details of how the database works and how it's set up later. For now, we'll just say that the code immediately following worker = db.getWorker(); loads the location names and positions (latitudes and longitudes) into the lsLocations and hmLocations lists.

Spinner Views require an ArrayAdapter to feed them the list, so we create one named aspnLocations, attaching it to the list of location names in its constructor. Then, we attach the adapter to the Spinner by calling setAdapter. The statement "aspnLocations.setDropDownViewResource(android.R.layout.simple_spin ner_dropdown_item);" provides the Spinner with the drop-down layout necessary for the user to display the whole list of locations.

Now that we have initialized the lists, we can add the following code, which enables the appropriate action when the user clicks on an item with the Spinner:

// Set up a callback for the spinner spnLocations.setOnItemSelectedListener( new OnItemSelectedListener() {

public void onNothingSelected(AdapterView<?> arg0) { }

public void onItemSelected(AdapterView<?> parent, View v, int position, long id) { TextView vt = (TextView) v; if ("Current Location".equals(vt.getText())) { latitude = myLocation.getLatitude(); longitude = myLocation.getLongitude();

mc.animateTo(new GeoPoint((int) latitude, (int) longitude)); } else {



Initialize the Spinner callback

Just as we did with the Button View, we create a method named onltemSelected and set it to be called when the user selects an item using the Spinner. The onNothingSelected method is also required, but we leave it empty (not used). As mentioned earlier, Current Location is a special case because we retrieve the device's location dynamically when the user selects that item. The if block handles that case: we look to see whether the selection is Current Location and if it is, we get the current location and go there. Otherwise, we go to the selected location.

Then, in the final statement, we invalidate the map so it will redraw itself.

0 0

Post a comment