- 论坛徽章:
- 0
|
So you saw the
Android announcement and decided you wanted a piece of that
US$10million in
prize money
huh? In the week since the SDK was released more than 4,300 people have joined
the Android support
forum posting more than 4,000 messages between them. Robert Scoble
doesn't know a single developer playing with Android – perhaps Scoble
doesn't hang around with many developers?
I wanted to give the SDK a good work-out so my application uses the GPS, the
address book, and has a map.
The only way to judge an SDK is getting in there and writing an application that
does something cool, so I'll take you through the development process for my
first Android application: Where Are My Friends?
WamF shows how far away you are right now from all the people in your
address book, plots you and them on a map, and draws lines between you and any
friends nearby.
![]()
WamF is pretty simple but it makes use of some of the more interesting
features of Android – Location Based Information (GPS etc), maps, the contacts
manager, and the phone dialer. Total development time from hitting Download on
the SDK page was about 14 hours (spread over two mornings and evenings).
My Android development is in Windows with Eclipse using the plugin, so I will
assume you're doing the same.
Before I get started here's a bit on my background. I've mentioned before that
I'm a C# .NET desktop applications developer in
my real life. It's been almost 10 years since I've done anything with
Java and I've never done any mobile phone development. With Android I develop
in Windows with Eclipse using the Android plugin.
Let's start by downloading
Eclipse and unzipping it into a new folder. Then download the
Android SDK and unzip that into another new folder. Open Eclipse and
create a new workspace for Android development.
Install the
Android Plugin by selecting Help > Software Updates > Find and
Install..., and in the dialog box choose Search for new Features to
install. Select New Remote Site and enter https://dl-ssl.google.com/android/eclipse/.
into the dialog box. Hit OK and accept all the prompts until it's installed.
Restart Eclipse and you're almost ready to rock.
Select Window > Preferences... and select Android, then put the
folder where you unzipped the SDK into the SDK Location text box. Hit Apply
then OK and you're done.
The tutorial and exercises are useful. Do them.
Let's make sure everything's installed right by creating the
Hello Android demo. The Android team have
a detailed description of how to do this so I won't repeat it here.
It's worth checking out the
known bugs if you encounter any problems.
The Android
documentation
is excellent; after you've finished the Hello Android project run through the
exercises. They're easy to follow and give a good idea of how a 'real'
application fits together.
Design a UI, leveraging one of the sample projects
Onto business. Step one should always be UI design. Figure out what it is you
want to tell the user and what actions they'll need then develop an interface
that will make this as intuitive as possible. To keep things simple I'm going
to base my new project on the NotePad project used in the tutorial
exercises.
I'll start by changing the resource strings to change the name of the app, and
modifying the
menu options
.
Use the Location Based Services to figure out where we are and request updates
when we move
Possibly the most enticing of the Android features are the
Location Based Services that give your application geographical context
through Location Providers (GPS etc). Android includes a mock provider called 'gps'
that marches back and forth through San Fransisco. Alternatively you can create
your own mock providers in XML.
You use the LocationManager to find your current position.
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
Location location = locationManager.getCurrentLocation("gps");
Iterate over the address book pulling out names, locations, and phone numbers
A less publicized feature of Android is the ability to share content between
applications. We're going to use this feature to populate our List with our
contacts' names and their current distance from our phone so we create an updateList
method that we call after we've gotten our current location.
Use the ContentResolver to return a query that provides access to
data shared using
Content Providers. Queries are returned as
cursors that provide access to the underlying data tables. The data
we're interested in is accessed using the
People content provider.
Cursor c = getContentResolver().query(People.CONTENT_URI, null, null, null,
null); startManagingCursor(c);
The Cursor is a managed way of controlling your position (Row) in the underlying
table. We get access to the data by specifying the column that holds the
information we're after. Rather than memorising the column index for each
Content Provider we can use constants from the People class as a
shortcut.
int coordIdx = c.getColumnIndex(People.NOTES); int phoneIdx =
c.getColumnIndex(People.PhonesColumns.NUMBER); int nameIdx =
c.getColumnIndex(People.NAME);
Now iterate over the table using the cursor storing the results in arrays.
You'll note that we're pulling our contacts' location from the Notes
field. In reality we'd want to figure this out based on their address using a
geocoding lookup.
List listItems = new ArrayList();
c.first();
do {String name = c.getString(nameIdx);
String coords = c.getString(coordIdx);
String phone = c.getString(phoneIdx);
... [ Process the lat/long from the coordinates ] ...
... [ Storing their location under variable loc ] ...
String distStr = String.valueOf(location.distanceTo(loc)/1000);
name = name + " (" + distStr + "km)";
listItems.add(name);
numbers.add("tel:" + phone); } while(c.next());
Then we assign our list of strings to the array using an ArrayAdapter.
ArrayAdapter notes = new ArrayAdapter(this, R.layout.notes_row, items);
setListAdapter(notes);
Refresh our list when we move
Given the location sensitive nature of WamF it makes sense to update the display
whenever we move. Do this by asking the LocationManager to trigger a
new Intent when our location provider notices we've moved.
List providers = locationManager.getProviders();
LocationProvider provider = providers.get(0);
Intent intent = new Intent(LOCATION_CHANGED);
locationManager.requestUpdates(provider, minTime, minDistance, intent);
Intents
in Android are like events in traditional event driven
programming, so we're triggering a LOCATION_CHANGED event/intent
every time we move by a minimum distance after a minimum time. The next step is
to create an IntentReceiver (event handler), so create a new
internal class that extends IntentReceiver and override the ReceiveIntent
event to call our update method.
public class myIntentReceiver extends IntentReceiver {@Override
public void onReceiveIntent(Context context, Intent intent) {} }
We then have our activity listen for a LOCATION_CHANGED intent by
registering the event handler and specifying the intent it should be listening
for (LOCATION_CHANGED). Do this in the onCreate method or
create a new menu option to start/stop the automatic updates.
filter = new IntentFilter(LOCATION_CHANGED);
receiver = new myIntentReceiver();
registerReceiver(receiver, filter);
Keep your phone running light by registering / unregistering the receiver when
the activity Pauses and Resumes – there's no point in listening for location
changes if we can't see the list.
Set up a map activity and create an overlay to show where you are in relation to
your friends
Half of the fun in having location sensitive information is drawing it on a
map. Create a new activity class to display a map centered on our
current location with markers at our friends locations. While we're at it we
can draw a line from our position to each of our friends.
The map control itself is called a MapView, but we can only use a MapView
in a MapActivity, so we'll change the inheritance of this activity
to MapActivity.
public class MyMapViewActivity extends MapActivity
To
display the map
we need to create a new MapView and set it as the content for our
activity in the OnCreate method.
MapView mapView = new MapView(this);
setContentView(mapView);
This will make the MapView fill the entire screen, so use views like
LinearLayout if we want to create a
more complicated UI layout.
We'll want to get access to the OverlayController and MapController,
so create global variables to store them and assign the references within the OnCreate
method. We'll also be using the Location information, so get a
reference to that too. With the references assigned set your map zoom and
starting location using the MapController. When you're finished OnCreate
should look something like this.
protected void onCreate(Bundle icicle) {super.onCreate(icicle);
MapView mapView = new MapView(this);
mapController = mapView.getController();
overlayController = mapView.createOverlayController();
locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);
mapController.zoomTo(9);
setContentView(mMapView);
updateView(); }
updateView is where we do the work. Start by getting our current
location and convert the Lat/Long to a map Point, then centre the
map on our current location.
Double lat = location.getLatitude()*1E6;
Double lng = location.getLongitude()*1E6;
Point point = new Point(lat.intValue(), lng.intValue());
mapController.centerMapTo(point, false);
The only thing left to do on our map is draw markers and link them up with
lines. To do this you need to create a new class that extends Overlay,
and add this using the OverlayController.
MyLocationOverlay myLocationOverlay = new MyLocationOverlay();
overlayController.add(myLocationOverlay, true);
The work in the Overlay class is done by overriding the draw method.
protected class MyLocationOverlay extends Overlay {@Override
public void draw(Canvas canvas, PixelCalculator calculator, boolean
shadow) {... [ draw things here ] ... } }
I start by drawing a 'marker' on my current location. There doesn't seem to be
support for 'traditional' Google Maps markers but you can achieve the same
thing by
drawing on the map canvas; I chose to draw small circles as markers.
First you need to use the PixelCalculator to convert your Lat/Long
points to screen coordinates, then create a Paint object to define
the colours and settings for your brush. Then paint your markers.
int[] screenCoords = new int[2];
calculator.getPointXY(point, screenCoords);
RectF oval = new RectF(...);
Paint paint = new Paint();
paint.setARGB(200, 255, 0, 0);
canvas.drawOval(oval, paint);
I add my friends locations the same way as before, iterating over my address
book grabbing names and locations. I filter out anyone too far away (say 10km)
and draw markers, names (drawText), and joining lines (drawLine)
to those nearby.
Let's make a call
Now we know when we're close to our friends, what are we likely to want to do
when we're close? Drop in! But we're polite so we'll call them first. Let's
change our list item click function to call the friend we've clicked. We can do
this by firing a DIAL_ACTION intent.
Intent i = new Intent();
i.setAction(DIAL_ACTION);
i.setData(new ContentURI(numbers.get(position)));
startActivity(i);
The phone dialer has registered an IntentReceiver filtered on DIAL_ACTION
so it will react to this.
Android is an environment where the biggest limitation is your imagination
And that's it.
I've got a list of a dozen or so changes to make it a little more useful and a
half dozen ideas for projects that might actually make it into the running for
some of that prize money. My conclusion? Android is everything a development
kit should be – an environment where the biggest limitation is what you can
imagine.
本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/85805/showart_1668830.html |
|