Simple Android Speedometer

UPDATE

There’s been quite a bit of activity on this post. Some of the info is old, and people keep asking for the full Eclipse project.

Here’s something even better… Step-by-step tutorial for the simple speedometer:

Nothing but old info below here…

I’ve seen lots of questions concerning the use of the GPS functionality in Android.  It’s super easy, but some of the explanations are needlessly complicated.

The code below is a simple speedometer that uses the GPS chip to show your current speed.  There are optimations that can be made (specifically in the “locationManager.requestLocationUpdates” call), but this is good enough to get you going.  The Android API documentation should fill in the gaps. As always … take it, run, and share with the rest of us.

Check out the interface and class below, and make sure to see the previous post for the “CLocation” class.

import android.location.GpsStatus;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;

public interface IBaseGpsListener extends LocationListener, GpsStatus.Listener
{
  public void onLocationChanged(Location location);

  public void onProviderDisabled(String provider);

  public void onProviderEnabled(String provider);

  public void onStatusChanged(String provider, int status, Bundle extras);

  public void onGpsStatusChanged(int event);
}
import java.util.Formatter;
import java.util.Locale;

import android.app.Activity;
import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.CheckBox;
import android.widget.CompoundButton;
import android.widget.CompoundButton.OnCheckedChangeListener;
import android.widget.TextView;

public class CSpeedometer extends Activity implements IBaseGpsListener
{
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    this.setContentView(R.layout.speedometer_main);

    LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
                                           0,
                                           0,
                                           this);

    this.updateSpeed(null);

    CheckBox chkUseMetricUnits = (CheckBox)this.findViewById(R.id.chkUseMetricUnits);
    chkUseMetricUnits.setOnCheckedChangeListener(new OnCheckedChangeListener()
    {
      public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
      {
        CSpeedometer.this.updateSpeed(null);
      }
    });
  }

  public boolean onCreateOptionsMenu(Menu menu)
  {
    MenuInflater inflater = getMenuInflater();
    inflater.inflate(R.menu.speedometer_main, menu);
    return true;
  }

  public boolean onOptionsItemSelected(MenuItem item)
  {
    switch (item.getItemId())
    {
      case R.id.menuItemQuit:
        this.finish();
        return true;
      default:
        return super.onOptionsItemSelected(item);
    }
  }

  public void finish()
  {
    super.finish();
    System.exit(0);
  }

  public void updateSpeed(CLocation location)
  {
    float nCurrentSpeed = 0;

    if( location!=null )
    {
      location.setUseMetricUnits(this.useMetricUnits());
      nCurrentSpeed = location.getSpeed();
    }

    Formatter fmt = new Formatter(new StringBuilder());
    fmt.format(Locale.US, "%5.1f", nCurrentSpeed);
    String strCurrentSpeed = fmt.toString();
    strCurrentSpeed = strCurrentSpeed.replace(' ', '0');

    String strUnits = "miles/hour";
    if (this.useMetricUnits())
    {
      strUnits = "meters/second";
    }

    TextView txtCurrentSpeed = (TextView) this.findViewById(R.id.txtCurrentSpeed);
    txtCurrentSpeed.setText(strCurrentSpeed + " " + strUnits);
  }

  public boolean useMetricUnits()
  {
    CheckBox chkUseMetricUnits = (CheckBox)this.findViewById(R.id.chkUseMetricUnits);
    return chkUseMetricUnits.isChecked();
  }

  public void onLocationChanged(Location location)
  {
    if (location != null)
    {
      CLocation myLocation = new CLocation(location, this.useMetricUnits());
      this.updateSpeed(myLocation);
    }
  }

  public void onProviderDisabled(String provider)
  {
    // TODO: do something one day?
  }

  public void onProviderEnabled(String provider)
  {
    // TODO: do something one day?
  }

  public void onStatusChanged(String provider, int status, Bundle extras)
  {
    // TODO: do something one day?

  }

  public void onGpsStatusChanged(int event)
  {
    // TODO: do something one day?
  }
}

UPDATE

I’ve uploaded the source, layout xml, and manifest xml here:

speedometer_test.zip

 

Android Location class with U.S. customary units (instead of metric)

I’m a big proponent of going metric; I’ve never fully understood why we don’t just do it.  Then again, I’d also like the entire world to be on UTC time.  But since we insist on using our own bass-ackward units of measure, I needed an Android Location class that returned U.S. customary units instead of metric.

So, here goes…

import android.location.Location;

public class CLocation extends Location
{
  private boolean bUseMetricUnits = false;

  public CLocation(Location location)
  {
    this(location, true);
  }

  public CLocation(Location location, boolean bUseMetricUnits)
  {
    super(location);
    this.bUseMetricUnits = bUseMetricUnits;
  }

  public boolean getUseMetricUnits()
  {
    return this.bUseMetricUnits;
  }

  public void setUseMetricUnits(boolean bUseMetricUnits)
  {
    this.bUseMetricUnits = bUseMetricUnits;
  }

  @Override
  public float distanceTo(Location dest)
  {
    float nDistance = super.distanceTo(dest);

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nDistance = nDistance * 3.28083989501312f;
    }

    return nDistance;
  }

  @Override
  public float getAccuracy()
  {
    float nAccuracy = super.getAccuracy();

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nAccuracy = nAccuracy * 3.28083989501312f;
    }

    return nAccuracy;
  }

  @Override
  public double getAltitude()
  {
    double nAltitude = super.getAltitude();

    if (!this.getUseMetricUnits())
    {
      // Convert meters to feet
      nAltitude = nAltitude * 3.28083989501312d;
    }

    return nAltitude;
  }

  @Override
  public float getSpeed()
  {
    float nSpeed = super.getSpeed();

    if (!this.getUseMetricUnits())
    {
      // Convert meters/second to miles/hour
      nSpeed = nSpeed * 2.2369362920544f;
    }

    return nSpeed;
  }
}

This class really isn’t anything special, it just allows you to toggle which units you would like to use:

  • U.S. Customary Units:  feet and miles/hour
  • Metric:  meters and meters/second

Please, take it and make it better :)

Gingerbread on my 1st gen Droid

My first leap into the Android world was the 1st generation Motorola Droid.  When it was released, it was THE droid to have.  I still love the phone, but when my contract was up, I couldn’t resist the call to a newer/better phone.

Because I’m cheap, I upgraded to an HTC Incredible (it was free at BestBuy).  A decent phone in it’s own right, but it’s last year’s technology.  Even though, it’s a good bit above my old trusty droid.  I wanted to hold out for Thunderbolt or Bionic, but it just didn’t happen that way.

So, now that I’ve got this shiny new phone, I can be geeky with the old one.  Thanks to the folks over at Ultimate Droid, I’ve got Gingerbread up and running on the old droid.  I must say, it’s amazing!  It’s almost making me have a few second thoughts about my upgrade.

Perhaps it’s time for me to consider rooting my main phone?

my nerdy family

There are those [weird] people who see being called a “nerd” as an insult. Then, there are those of us who [rightly so] see it as a complement. Never forget, without nerds, we’d all still be sittin’ in a cave somewhere suckin’ on rocks and gruntin’ at each other.

There are not words to describe the nerd pride I feel when I over hear my 8 year old discussing the Kuiper belt with his buddies, or when he comes up with some obscure/abstract way to solve a math problem that I had never though of. He’s truly a nerd-in-training.

But when my wife does something nerdy, it’s a whole different level of cool (and super hot). See, growing up, she was the cheerleader/beauty queen/popular girl … and, well, I’ve always been a nerd.  It’s no small miracle that she saw fit to marry me; I’m just super lucky really.  She’s always [secretly] had some nerd tendencies though; for example, she will sit down and read a 1,000 page book in a day … for fun … it’s crazy. But, sometimes she does or says something that’s just plain nerdy on anybody’s nerd scale.

Earlier this week, we were going over the boy’s spelling list for school. This week’s list focused on contractions (he insists on calling them “contraptions” instead of contractions). We were talking about the formality of saying things like “we have” instead of “we’ve”, when I mentioned that Data (of Star Trek fame) did not use contractions on a regular basis. Then, my awesome wife says this:

Yes, that’s how they knew it wasn’t Data in that one episode.

I was just super impressed that she had come up with some obscure Star Trek trivia off the top of her head; it was AMAZING.  The only thing that could have possibly made that statement any better is if she would have said:

Yes, in Episode 13 “Datalore”, Captian Picard knew that Lore was impersonating Data because he used a contraction.

It was awesome; I love my family.

*The super nerdy among us would point out that Data’s use of contractions is somewhat of a hot button topic (as evidenced here), but that’s really irrelevant to the point.

cub scouts in space

Last night in our weekly den meeting, we worked on our astronomy belt loop. I was pleasantly surprised at our discussion, and a have a [slightly] renewed faith in our public education system.

It’s very encouraging to listen to 3rd graders talk intelligently about black holes, stars, pulsars, galaxies, planets, etc. We had a debate about Pluto’s planetary status, and we drew models of the solar system (some included Pluto in their model and some didn’t). The discussion even drifted into Star Trek for a bit … AWESOME!

I think the highlight of the night for the boys was when we got the telescope out. It was super clear and we had a great view of Jupiter and the Galilean moons. It was an experience that most of the boys had never had before, and I was super honored to facilitate.

PHP HashTable implementation

Here’s a quick/dirty HashTable implementation for PHP (based on the Java Hashtable API).  There are probably better ones, but for what it’s worth … here ya go:

class CHashTable
{
  private $_arr = null;

  function __construct()
  {
    $this->_arr = array();
  }

  function clear()
  {
    unset( $this->_arr );
    $this->_arr = array();
  }

  function contains($value, $bStrict=false)
  {
    return in_array($value, $this->_arr, $bStrict);
  }

  function containsKey($key)
  {
    return array_key_exists($key, $this->_arr);
  }

  function containsValue($value, $bStrict=false)
  {
    return $this->contains($value, $bStrict);
  }

  function get($key)
  {
    $value = null;

    if( array_key_exists($key, $this->_arr) )
    {
      $value = $this->_arr[$key];
    }

    return $value;
  }

  function isEmpty()
  {
    return ($this->size()<=0);   }   function keys()   {     return array_keys($this->_arr);
  }

  function put($key, $value)
  {
    $this->_arr[$key] = $value;
  }

  function putAll($arr)
  {
    if( $arr!==null )
    {
      if( is_array($arr) )
      {
        $this->_arr = array_merge($this->_arr, $arr);
      }
      else if( $arr instanceof CHashTable )
      {
        $this->_arr = array_merge($this->_arr, $arr->_arr);
      }
    }
  }

  function remove($key)
  {
    unset( $this->_arr[$key] );
  }

  function size()
  {
    return count($this->_arr);
  }

  function toString()
  {
    return print_r($this->_arr, true);
  }

  function values()
  {
    return array_values($this->_arr);
  }
}

The term “hashtable” may be a little loose  here.  There is no hashing or indexing done to increase performance.  The purpose here was to have some PHP object class to mimic the behavior of a Java Hashtable; it is really use an API wrapper around some PHP associative array.  It makes my life easier when porting code.

There may be some issues here, I haven’t really put it through it’s paces yet.  I’m writing some database code and needed a base class for data objects that behaves like a Hashtable.

If you have any constructive comments/suggestions, let me know.  As always, the commenting rules apply…

Android Market Web Fail [updated]

The new Android Market web site looks to be impressive.

The “invalid request” error I get when I (and everyone else in the world) attempt to log in is not impressive.  Sigh…

I’ll try again later…  Good job Google.

[update]

Good job Google.

After the initial issues with logging in, I noticed a few small hiccups:

  • The apps I already had were not recognized as “INSTALLED”.  Each app in the market will tell you whether or not it is installed or can be installed.
  • When installing, I would get an error message telling me to try again later.  Then (even with the error), the app would begin installing on my phone.

But … with a bit of time (I’m guessing to sync somehow with my device).  All of my apps were detected, and I am not getting error messages any more.

I’m diggin’ the new market web site right now … I think mainly because I HATE using the market app on the phone.

“What’s an internet?”

This little video is getting a bit of attention today:

I saw it first @ CNN’s site:

http://marquee.blogs.cnn.com/2011/01/31/today-flashback-katie-couric-whats-an-internet/?hpt=C2

It’s the 1994 cast of the today show wondering WTH “an internet” is.  It is pretty sad when you watch it in today’s context; but really, is it that embarrassing?

I’d be willing to bet that most you you didn’t know what the internet was in 1994 … some of you weren’t even born in 1994.

In fact, I’m certain that we didn’t have internet access in my house when I was 13/14.  I’m not even sure I knew what the internet was back then.

BANG!

Check this out:

http://gizmodo.com/5744321/how-far-into-the-past-can-our-telescopes-see

It’s a little post about different modern telescopes and how far away observable objects are.  It mentions the James Web Telescope that will allow us to see objects 13.5 billion light years away; that’s scary close to the time of the big bang.

So, the question was posed:

“I wonder if we will ever be able to get to the point of watching the Big Bang itself.”

It got me wondering if such a thing would even be possible?  If our entire universe was once condensed into an infinitely small space and then instantaneously began to expand, I’m not sure there would be an observable flash point.  I’m thinking that any such phenomenon would be on the leading edge of the expansion.  Seeing as we would have been part of the bang, and not on the outside of it, it would not be observable?  I don’t know.

Or perhaps we would see the back side of the opposite leading edge as it existed 13.7 billion years ago.  I makes my head hurt a bit, but it’s interesting to ponder.

*Before you comment, please read the disclaimer on my About page.

numbers

The human brain’s ability to recall things from memory (without you even knowing) is remarkable.

I just walked out to my car to get something I left there earlier, and on my way back into the office I typed in the code to the cipher lock on the door and went on my way.  I didn’t think about or try to remember a combination; I just typed it in and opened the door.

As I walked back down the hall, I started to think about all the numbers I have memorized:  phones, ATMs, lock combinations, online passwords, smart card pins, security codes at work/home, etc.  I attempted to make a mental list and put all the codes/passwords to the right application, but it just started to get confusing.

It’s really a miracle that I can walk up to an ATM or go to a web site and enter the proper credentials without conscience effort.  I can dial my wife’s phone number without a second thought, but if you asked me to tell you her number I’m probably stumble through it.

We are amazing machines.