Archive for the ‘Programming’ Category

sometimes I even confuse myself

I’ve got this long standing personal project that I just can’t seem to finish.  It’s this file encryption program that I only seem to find time to work on in the 30 minutes before bed time.  I’ve got the core written and it’s working mostly everywhere (even on my Droid).  All I’ve got left is to wrap a GUI around it, and I’ll at least have a releasable beta.  I don’t care much for front-end development, so perhaps that’s why I’ve hit a roadblock… No sure.

Anyway, I’m sitting here looking at some of the high level crypto functions and I’m having trouble following the logic.  I can’t tell if my own code is genius or just plain dumb.

ah oh…

How did I miss THIS yesterday?

Seems the web developers at MySQL skipped out on their best practices 101 class … you know, the day they talked about binding parameters.

Of course, that’s every developer’s knee-jerk reaction.  I’m sure if you searched all of our code long enough, you’d see some improperly escaped SQL in there somewhere.

Although, I’m puzzled as to how this would have gotten through a formal code review.  Interesting, no doubt.

Now, I’m off to change my MySQL.com account passwords…

More Java stuff

Before you read, just keep in mind that I am a Java developer by trade.  I may be a bit biased, but I try to be somewhat objective.

As I mentioned in a previous post, Java will be absent from future versions of OS X.  It’s not surprise, and we’ve known about it for months.  Apple is handing the reigns over to Oracle so that the actual “java people” can do the Java development.

Really, this is a long time coming and it’s absolutely the best move.  The big down side is that it just won’t be there by default (like it has been since the beginning of OS X).  Mac OS X was supposed to be the operating system of choice for Java developers, but I digress.

With all that said, Java is not a totally lost cause on OS X Lion.  While it will not be installed by default, you will be prompted to download the 1.6.0 release from Apple when trying to launch any Java applications.  At present it will install 1.6.0_24, which is the latest release from Oracle.  It seems that applet support is missing though (I would love to be proved wrong).  You may recoil in horror at the thought of applets, but you’d probably be surprised how ofter you encounter them (for legitimate purposes) and never know it.

I’m beyond overjoyed that the OpenJDK project is taking over development on the OS X port, but I am a bit dismayed at the current attitude toward Java in the Apple community.  After all, they have quite a bit of experience with resurrecting obsolete/near-dead programming languages … I’m looking at you Objective-C :)

But hey, maybe I really shouldn’t care.  Nobody uses OS X in the server world; Apple killed Xserver and OS X server may be on the same path.  It’s also not going to be too long before the only people with a need for an OS X computer are iOS application developers.

And as always, I take great comfort in knowing the “cloud” (that makes everyone’s iDevice usable) lives and breathes on linux and java :)

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 :)

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…